measurement: add handling of measurements
Add logic for saving measurement-reports from STAs. This commit does not yet save the measurement-reports received from clients but adds the necessary code to do so. Currently the codes can only handle beacon-reports, but link measurements can be added to it in the future. It also adds the new config-key measurement_report_timeout which controls how long measurements are saved upon they are received by a STA. Signed-off-by: David Bauer <mail@david-bauer.net>
This commit is contained in:
@@ -24,7 +24,7 @@ IF(NOT HAVE_PCAP_H)
|
||||
MESSAGE(FATAL_ERROR "pcap/pcap.h is not found")
|
||||
ENDIF()
|
||||
|
||||
SET(SOURCES main.c local_node.c node.c sta.c policy.c ubus.c remote.c parse.c netifd.c timeout.c event.c)
|
||||
SET(SOURCES main.c local_node.c node.c sta.c policy.c ubus.c remote.c parse.c netifd.c timeout.c event.c measurement.c)
|
||||
|
||||
IF(NL_CFLAGS)
|
||||
ADD_DEFINITIONS(${NL_CFLAGS})
|
||||
|
@@ -71,6 +71,7 @@ usteer_free_node(struct ubus_context *ctx, struct usteer_local_node *ln)
|
||||
usteer_local_node_pending_bss_tm_free(ln);
|
||||
usteer_local_node_state_reset(ln);
|
||||
usteer_sta_node_cleanup(&ln->node);
|
||||
usteer_measurement_report_node_cleanup(&ln->node);
|
||||
uloop_timeout_cancel(&ln->update);
|
||||
uloop_timeout_cancel(&ln->bss_tm_queries_timeout);
|
||||
avl_delete(&local_nodes, &ln->node.avl);
|
||||
@@ -578,6 +579,7 @@ usteer_get_node(struct ubus_context *ctx, const char *name)
|
||||
avl_insert(&local_nodes, &node->avl);
|
||||
kvlist_init(&ln->node_info, kvlist_blob_len);
|
||||
INIT_LIST_HEAD(&node->sta_info);
|
||||
INIT_LIST_HEAD(&node->measurements);
|
||||
|
||||
ln->bss_tm_queries_timeout.cb = usteer_local_node_process_bss_tm_queries;
|
||||
INIT_LIST_HEAD(&ln->bss_tm_queries);
|
||||
@@ -623,6 +625,7 @@ usteer_check_node_enabled(struct usteer_local_node *ln)
|
||||
MSG(INFO, "Disconnecting from local node %s\n", usteer_node_name(&ln->node));
|
||||
usteer_local_node_state_reset(ln);
|
||||
usteer_sta_node_cleanup(&ln->node);
|
||||
usteer_measurement_report_node_cleanup(&ln->node);
|
||||
uloop_timeout_cancel(&ln->update);
|
||||
ubus_unsubscribe(ubus_ctx, &ln->ev, ln->obj_id);
|
||||
return;
|
||||
|
1
main.c
1
main.c
@@ -86,6 +86,7 @@ void usteer_init_defaults(void)
|
||||
|
||||
config.sta_block_timeout = 30 * 1000;
|
||||
config.local_sta_timeout = 120 * 1000;
|
||||
config.measurement_report_timeout = 120 * 1000;
|
||||
config.local_sta_update = 1 * 1000;
|
||||
config.max_retry_band = 5;
|
||||
config.max_neighbor_reports = 8;
|
||||
|
112
measurement.c
Normal file
112
measurement.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Copyright (C) 2021 David Bauer <mail@david-bauer.net>
|
||||
*/
|
||||
|
||||
#include "usteer.h"
|
||||
|
||||
LIST_HEAD(measurements);
|
||||
static struct usteer_timeout_queue tq;
|
||||
|
||||
void
|
||||
usteer_measurement_report_node_cleanup(struct usteer_node *node)
|
||||
{
|
||||
struct usteer_measurement_report *mr, *tmp;
|
||||
|
||||
list_for_each_entry_safe(mr, tmp, &node->measurements, node_list)
|
||||
usteer_measurement_report_del(mr);
|
||||
}
|
||||
|
||||
void
|
||||
usteer_measurement_report_sta_cleanup(struct sta *sta)
|
||||
{
|
||||
struct usteer_measurement_report *mr, *tmp;
|
||||
|
||||
list_for_each_entry_safe(mr, tmp, &sta->measurements, sta_list)
|
||||
usteer_measurement_report_del(mr);
|
||||
}
|
||||
|
||||
struct usteer_measurement_report *
|
||||
usteer_measurement_report_get(struct sta *sta, struct usteer_node *node, bool create)
|
||||
{
|
||||
struct usteer_measurement_report *mr;
|
||||
|
||||
list_for_each_entry(mr, &sta->measurements, sta_list) {
|
||||
if (mr->node == node)
|
||||
return mr;
|
||||
}
|
||||
|
||||
if (!create)
|
||||
return NULL;
|
||||
|
||||
mr = calloc(1, sizeof(*mr));
|
||||
if (!mr)
|
||||
return NULL;
|
||||
|
||||
/* Set node & add to nodes list */
|
||||
mr->node = node;
|
||||
list_add(&mr->node_list, &node->measurements);
|
||||
|
||||
/* Set sta & add to STAs list */
|
||||
mr->sta = sta;
|
||||
list_add(&mr->sta_list, &sta->measurements);
|
||||
|
||||
/* Add to Measurement list */
|
||||
list_add(&mr->list, &measurements);
|
||||
|
||||
/* Set measurement expiration */
|
||||
usteer_timeout_set(&tq, &mr->timeout, config.measurement_report_timeout);
|
||||
|
||||
return mr;
|
||||
}
|
||||
|
||||
struct usteer_measurement_report *
|
||||
usteer_measurement_report_add_beacon_report(struct sta *sta, struct usteer_node *node,
|
||||
struct usteer_beacon_report *br, uint64_t timestamp)
|
||||
{
|
||||
struct usteer_measurement_report *mr = usteer_measurement_report_get(sta, node, true);
|
||||
|
||||
if (!mr)
|
||||
return NULL;
|
||||
|
||||
mr->timestamp = timestamp;
|
||||
memcpy(&mr->beacon_report, br, sizeof(*br));
|
||||
|
||||
return mr;
|
||||
}
|
||||
|
||||
void
|
||||
usteer_measurement_report_del(struct usteer_measurement_report *mr)
|
||||
{
|
||||
usteer_timeout_cancel(&tq, &mr->timeout);
|
||||
list_del(&mr->node_list);
|
||||
list_del(&mr->sta_list);
|
||||
list_del(&mr->list);
|
||||
free(mr);
|
||||
}
|
||||
|
||||
static void
|
||||
usteer_measurement_timeout(struct usteer_timeout_queue *q, struct usteer_timeout *t)
|
||||
{
|
||||
struct usteer_measurement_report *mr = container_of(t, struct usteer_measurement_report, timeout);
|
||||
|
||||
usteer_measurement_report_del(mr);
|
||||
}
|
||||
|
||||
static void __usteer_init usteer_measurement_init(void)
|
||||
{
|
||||
usteer_timeout_init(&tq);
|
||||
tq.cb = usteer_measurement_timeout;
|
||||
}
|
@@ -26,6 +26,9 @@ config usteer
|
||||
# Maximum amount of time (ms) a local unconnected station is tracked
|
||||
#option local_sta_timeout 120000
|
||||
|
||||
# Maximum amount of time (ms) a measurement report is stored
|
||||
#option measurement_report_timeout 120000
|
||||
|
||||
# Local station information update interval (ms)
|
||||
#option local_sta_update 1000
|
||||
|
||||
|
@@ -76,6 +76,7 @@ uci_usteer() {
|
||||
debug_level \
|
||||
sta_block_timeout local_sta_timeout local_sta_update \
|
||||
max_neighbor_reports max_retry_band seen_policy_timeout \
|
||||
measurement_report_timeout \
|
||||
load_balancing_threshold band_steering_threshold \
|
||||
remote_update_interval remote_node_timeout\
|
||||
min_connect_snr min_snr min_snr_kick_delay signal_diff_threshold \
|
||||
|
2
remote.c
2
remote.c
@@ -210,6 +210,7 @@ remote_node_free(struct usteer_remote_node *node)
|
||||
list_del(&node->list);
|
||||
list_del(&node->host_list);
|
||||
usteer_sta_node_cleanup(&node->node);
|
||||
usteer_measurement_report_node_cleanup(&node->node);
|
||||
free(node);
|
||||
|
||||
if (!list_empty(&host->nodes))
|
||||
@@ -264,6 +265,7 @@ interface_get_node(struct usteer_remote_host *host, const char *name)
|
||||
node->name = buf + addr_len + 1;
|
||||
node->host = host;
|
||||
INIT_LIST_HEAD(&node->node.sta_info);
|
||||
INIT_LIST_HEAD(&node->node.measurements);
|
||||
|
||||
list_add_tail(&node->list, &remote_nodes);
|
||||
list_add_tail(&node->host_list, &host->nodes);
|
||||
|
2
sta.c
2
sta.c
@@ -35,6 +35,7 @@ usteer_sta_del(struct sta *sta)
|
||||
MAC_ADDR_DATA(sta->addr));
|
||||
|
||||
avl_delete(&stations, &sta->avl);
|
||||
usteer_measurement_report_sta_cleanup(sta);
|
||||
free(sta);
|
||||
}
|
||||
|
||||
@@ -140,6 +141,7 @@ usteer_sta_get(const uint8_t *addr, bool create)
|
||||
sta->avl.key = sta->addr;
|
||||
avl_insert(&stations, &sta->avl);
|
||||
INIT_LIST_HEAD(&sta->nodes);
|
||||
INIT_LIST_HEAD(&sta->measurements);
|
||||
|
||||
return sta;
|
||||
}
|
||||
|
1
ubus.c
1
ubus.c
@@ -149,6 +149,7 @@ struct cfg_item {
|
||||
_cfg(U32, max_neighbor_reports), \
|
||||
_cfg(U32, max_retry_band), \
|
||||
_cfg(U32, seen_policy_timeout), \
|
||||
_cfg(U32, measurement_report_timeout), \
|
||||
_cfg(U32, load_balancing_threshold), \
|
||||
_cfg(U32, band_steering_threshold), \
|
||||
_cfg(U32, remote_update_interval), \
|
||||
|
32
usteer.h
32
usteer.h
@@ -73,6 +73,7 @@ struct usteer_remote_host;
|
||||
struct usteer_node {
|
||||
struct avl_node avl;
|
||||
struct list_head sta_info;
|
||||
struct list_head measurements;
|
||||
|
||||
enum usteer_node_type type;
|
||||
|
||||
@@ -155,6 +156,7 @@ struct usteer_config {
|
||||
|
||||
uint32_t max_retry_band;
|
||||
uint32_t seen_policy_timeout;
|
||||
uint32_t measurement_report_timeout;
|
||||
|
||||
bool assoc_steering;
|
||||
|
||||
@@ -254,6 +256,7 @@ struct sta_info {
|
||||
struct sta {
|
||||
struct avl_node avl;
|
||||
struct list_head nodes;
|
||||
struct list_head measurements;
|
||||
|
||||
uint8_t seen_2ghz : 1;
|
||||
uint8_t seen_5ghz : 1;
|
||||
@@ -263,6 +266,27 @@ struct sta {
|
||||
uint8_t rrm;
|
||||
};
|
||||
|
||||
struct usteer_beacon_report {
|
||||
uint8_t rcpi;
|
||||
uint8_t rsni;
|
||||
};
|
||||
|
||||
struct usteer_measurement_report {
|
||||
struct usteer_timeout timeout;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
struct usteer_node *node;
|
||||
struct list_head node_list;
|
||||
|
||||
struct sta *sta;
|
||||
struct list_head sta_list;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
struct usteer_beacon_report beacon_report;
|
||||
};
|
||||
|
||||
extern struct ubus_context *ubus_ctx;
|
||||
extern struct usteer_config config;
|
||||
extern struct list_head node_handlers;
|
||||
@@ -335,4 +359,12 @@ void usteer_run_hook(const char *name, const char *arg);
|
||||
void usteer_dump_node(struct blob_buf *buf, struct usteer_node *node);
|
||||
void usteer_dump_host(struct blob_buf *buf, struct usteer_remote_host *host);
|
||||
|
||||
struct usteer_measurement_report * usteer_measurement_report_get(struct sta *sta, struct usteer_node *node, bool create);
|
||||
void usteer_measurement_report_node_cleanup(struct usteer_node *node);
|
||||
void usteer_measurement_report_sta_cleanup(struct sta *sta);
|
||||
void usteer_measurement_report_del(struct usteer_measurement_report *mr);
|
||||
|
||||
struct usteer_measurement_report *
|
||||
usteer_measurement_report_add_beacon_report(struct sta *sta, struct usteer_node *node, struct usteer_beacon_report *br, uint64_t timestamp);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user