node: keep track of roam-sources and roam-destinations
authorDavid Bauer <mail@david-bauer.net>
Mon, 27 Sep 2021 19:48:58 +0000 (21:48 +0200)
committerDavid Bauer <mail@david-bauer.net>
Thu, 25 Nov 2021 21:26:08 +0000 (22:26 +0100)
Keep track of STA journeys between multiple nodes. When a new STA is
reported from a foreign node, check whether this STA was previously
associated with a local node.

Vice versa, check upon association whether or not the STA was previously
associated with a foreign node.

Keep track of these roaming transactions using two new (local) fields of
the node struct.

Signed-off-by: David Bauer <mail@david-bauer.net>
local_node.c
main.c
openwrt/usteer/files/etc/config/usteer
openwrt/usteer/files/etc/init.d/usteer
remote.c
ubus.c
usteer.h

index bc27766e76816f1f184b21f13f2b0f7f42b62fbd..3c1b3e174304b6c678a7c5f0e8649ebd166b02cf 100644 (file)
@@ -150,10 +150,29 @@ usteer_local_node_assoc_update(struct sta_info *si, struct blob_attr *data)
                [MSG_ASSOC] = { "assoc", BLOBMSG_TYPE_BOOL },
        };
        struct blob_attr *tb[__MSG_MAX];
+       struct usteer_remote_node *rn;
+       struct sta_info *remote_si;
 
        blobmsg_parse(policy, __MSG_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
-       if (tb[MSG_ASSOC] && blobmsg_get_u8(tb[MSG_ASSOC]))
+       if (tb[MSG_ASSOC] && blobmsg_get_u8(tb[MSG_ASSOC])) {
+               if (si->connected == STA_NOT_CONNECTED) {
+                       /* New connection. Check if STA roamed. */
+                       for_each_remote_node(rn) {
+                               remote_si = usteer_sta_info_get(si->sta, &rn->node, NULL);
+                               if (!remote_si)
+                                       continue;
+
+                               if (current_time - remote_si->last_connected < config.roam_process_timeout) {
+                                       rn->node.roam_source++;
+                                       /* Don't abort looking for roam sources here.
+                                        * The client might have roamed via another node
+                                        * within the roam-timeout.
+                                        */
+                               }
+                       }
+               }
                si->connected = STA_CONNECTED;
+       }
 
        if (si->node->freq < 4000)
                si->sta->seen_2ghz = 1;
diff --git a/main.c b/main.c
index 9d014199770a5a32db36def2f7469992f6072f6c..9fb6d4afe9150bbe266bf16cf6bc36effcd3cd37 100644 (file)
--- a/main.c
+++ b/main.c
@@ -96,6 +96,7 @@ void usteer_init_defaults(void)
        config.remote_node_timeout = 10;
 
        config.roam_kick_delay = 100;
+       config.roam_process_timeout = 5 * 1000;
        config.roam_scan_tries = 3;
        config.roam_scan_interval = 10 * 1000;
        config.roam_trigger_interval = 60 * 1000;
index 3ba1c6d252ea4b99461845b5408d792e834cf989..9031ea8a4fbcc9d0b692b6151b1a7cd1c5d9e6b2 100644 (file)
@@ -50,6 +50,10 @@ config usteer
        # Minimum signal-to-noise ratio or signal level (dBm) to remain connected
        #option min_snr 0
 
+       # Timeout (in ms) after which a association following a disassociation is not seen
+       # as a roam
+       #option roam_process_timeout 5000
+
        # Minimum signal-to-noise ratio or signal level (dBm) before attempting to trigger
        # client scans for roaming
        #option roam_scan_snr 0
index 15add881ccd57f5bd49c8c8aec3af1aba258ffa9..65a6b9a69a84980f833fdfabb21e16a200207017 100755 (executable)
@@ -79,7 +79,7 @@ uci_usteer() {
                load_balancing_threshold band_steering_threshold \
                remote_update_interval \
                min_connect_snr min_snr signal_diff_threshold \
-               initial_connect_delay \
+               initial_connect_delay roam_process_timeout\
                roam_kick_delay roam_scan_tries \
                roam_scan_snr roam_scan_interval \
                roam_trigger_snr roam_trigger_interval \
index d0d9e174d5264635a89ab23289edab2d6f27aace..4887cc023ddda9507927d82faa31b31914222ffd 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -155,9 +155,11 @@ static void
 interface_add_station(struct usteer_remote_node *node, struct blob_attr *data)
 {
        struct sta *sta;
-       struct sta_info *si;
+       struct sta_info *si, *local_si;
        struct apmsg_sta msg;
+       struct usteer_node *local_node;
        bool create;
+       bool connect_change;
 
        if (!parse_apmsg_sta(&msg, data)) {
                MSG(DEBUG, "Cannot parse station in message\n");
@@ -177,10 +179,26 @@ interface_add_station(struct usteer_remote_node *node, struct blob_attr *data)
        if (!si)
                return;
 
+       connect_change = si->connected != msg.connected;
        si->connected = msg.connected;
        si->signal = msg.signal;
        si->seen = current_time - msg.seen;
        si->last_connected = current_time - msg.last_connected;
+
+       /* Check if client roamed to this foreign node */
+       if ((connect_change || create) && si->connected == STA_CONNECTED) {
+               for_each_local_node(local_node) {
+                       local_si = usteer_sta_info_get(sta, local_node, NULL);
+                       if (!local_si)
+                               continue;
+
+                       if (current_time - local_si->last_connected < config.roam_process_timeout) {
+                               node->node.roam_destination++;
+                               break;
+                       }
+               }
+       }
+
        usteer_sta_info_update_timeout(si, msg.timeout);
 }
 
diff --git a/ubus.c b/ubus.c
index 1f57194ae34ab1522297b02d53a90ee78fa41751..776b0bf5708f81676d074efcd4054776ef0bb523 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -154,6 +154,7 @@ struct cfg_item {
        _cfg(BOOL, assoc_steering), \
        _cfg(I32, min_connect_snr), \
        _cfg(I32, min_snr), \
+       _cfg(U32, roam_process_timeout), \
        _cfg(I32, roam_scan_snr), \
        _cfg(U32, roam_scan_tries), \
        _cfg(U32, roam_scan_interval), \
@@ -281,6 +282,8 @@ void usteer_dump_node(struct blob_buf *buf, struct usteer_node *node)
        blobmsg_add_u32(buf, "noise", node->noise);
        blobmsg_add_u32(buf, "load", node->load);
        blobmsg_add_u32(buf, "max_assoc", node->max_assoc);
+       blobmsg_add_u32(buf, "roam_source", node->roam_source);
+       blobmsg_add_u32(buf, "roam_destination", node->roam_destination);
        if (node->rrm_nr)
                blobmsg_add_field(buf, BLOBMSG_TYPE_ARRAY, "rrm_nr",
                                  blobmsg_data(node->rrm_nr),
index 866c0b2532620183a757473348edbf03b2e63ec7..05dca140c3fd7242b8440a241a3240e3feb37efe 100644 (file)
--- a/usteer.h
+++ b/usteer.h
@@ -87,6 +87,9 @@ struct usteer_node {
        int n_assoc;
        int max_assoc;
        int load;
+
+       int roam_source;
+       int roam_destination;
 };
 
 struct usteer_scan_request {
@@ -160,6 +163,8 @@ struct usteer_config {
        uint32_t signal_diff_threshold;
 
        int32_t roam_scan_snr;
+       uint32_t roam_process_timeout;
+
        uint32_t roam_scan_tries;
        uint32_t roam_scan_interval;