• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/usteer/band_steering.c

  1 /*
  2  *   This program is free software; you can redistribute it and/or modify
  3  *   it under the terms of the GNU General Public License as published by
  4  *   the Free Software Foundation; either version 2 of the License.
  5  *
  6  *   This program is distributed in the hope that it will be useful,
  7  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  8  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9  *   GNU General Public License for more details.
 10  *
 11  *   You should have received a copy of the GNU General Public License
 12  *   along with this program; if not, write to the Free Software
 13  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 14  *
 15  *   Copyright (C) 2022 David Bauer <mail@david-bauer.net>
 16  */
 17 
 18 #include "usteer.h"
 19 #include "node.h"
 20 
 21 void usteer_band_steering_sta_update(struct sta_info *si)
 22 {
 23         if (si->connected == STA_NOT_CONNECTED) {
 24                 if (si->band_steering.signal_threshold != NO_SIGNAL) {
 25                         si->band_steering.signal_threshold = NO_SIGNAL;
 26                 }
 27                 return;
 28         }
 29         if (config.band_steering_signal_threshold)
 30         {
 31                 if (si->connected != STA_NOT_CONNECTED && si->band_steering.signal_threshold == NO_SIGNAL)
 32                 {
 33                         si->band_steering.signal_threshold = si->signal;
 34                         MSG(DEBUG, "band steering station " MAC_ADDR_FMT " (%s) set threshold %d\n", MAC_ADDR_DATA(si->sta->addr), usteer_node_name(si->node), si->band_steering.signal_threshold);
 35                         return;
 36                 }
 37 
 38                 /* Adapt signal threshold to actual signal quality */
 39                 if (si->signal < si->band_steering.signal_threshold) {
 40                         si->band_steering.signal_threshold--;
 41                         MSG(DEBUG, "band steering station " MAC_ADDR_FMT " (%s) reduce threshold %d, signal: %d\n", MAC_ADDR_DATA(si->sta->addr), usteer_node_name(si->node), si->band_steering.signal_threshold, si->signal);
 42                 }
 43                 if (si->signal < si->band_steering.signal_threshold + config.band_steering_signal_threshold)
 44                         si->band_steering.below_snr = true;
 45         }
 46         if (si->signal < usteer_snr_to_signal(si->node, config.band_steering_min_snr))
 47                 si->band_steering.below_snr = true;
 48 }
 49 
 50 bool usteer_band_steering_is_target(struct usteer_local_node *ln, struct usteer_node *node)
 51 {
 52         if (&ln->node == node)
 53                 return false;
 54 
 55         if (strcmp(ln->node.ssid, node->ssid))
 56                 return false;
 57 
 58         if (node->freq < 4000)
 59                 return false;
 60 
 61         if (!usteer_policy_node_below_max_assoc(node))
 62                 return false;
 63         
 64         /* ToDo: Skip nodes with active load-kick */
 65         
 66         return true;
 67  }
 68 
 69 
 70 static bool usteer_band_steering_has_target_iface(struct usteer_local_node *ln)
 71 {
 72         struct usteer_node *node;
 73 
 74         for_each_local_node(node) {
 75                 if (usteer_band_steering_is_target(ln, node))
 76                         return true;
 77         }
 78 
 79         return false;
 80 }
 81 
 82 void usteer_band_steering_perform_steer(struct usteer_local_node *ln)
 83 {
 84         unsigned int min_count = DIV_ROUND_UP(config.band_steering_interval, config.local_sta_update);
 85         struct sta_info *si;
 86         uint32_t disassoc_timer;
 87         uint32_t validity_period;
 88 
 89         if (!config.band_steering_interval)
 90                 return;
 91 
 92         /* Band-Steering is only available on 2.4 GHz interfaces */
 93         if (ln->node.freq > 4000)
 94                 return;
 95 
 96         /* Check if we have an interface we can steer to */
 97         if (!usteer_band_steering_has_target_iface(ln))
 98                 return;
 99 
100         /* Only steer every interval */
101         if (ln->band_steering_interval < min_count) {
102                 ln->band_steering_interval++;
103                 return;
104         }
105 
106         ln->band_steering_interval = 0;
107 
108         list_for_each_entry(si, &ln->node.sta_info, node_list) {
109                 /* Check if client is eligable to be steerd */
110                 if (!usteer_policy_can_perform_roam(si))
111                         continue;
112 
113                 /* Skip clients with insufficient SNR-state */
114                 if (si->band_steering.below_snr) {
115                         si->band_steering.below_snr = false;
116                         continue;
117                 }
118 
119                 /* Skip if in validity period */
120                 if (current_time < si->roam_transition_request_validity_end)
121                         continue;
122 
123                 if (si->bss_transition) {
124                         si->roam_transition_request_validity_end = current_time + 10000;
125                         validity_period = 10000 / usteer_local_node_get_beacon_interval(ln); /* ~ 10 seconds */
126                         if (si->sta->aggressiveness >= 2) {
127                                 if (!si->kick_time)
128                                         si->kick_time = current_time + config.roam_kick_delay;
129                                 if (si->sta->aggressiveness >= 3)
130                                         disassoc_timer = (si->kick_time - current_time) / usteer_local_node_get_beacon_interval(ln);
131                                 else
132                                         disassoc_timer = 0;
133                                 usteer_ubus_band_steering_request(si, 0, true, disassoc_timer, true, validity_period);
134                         } else
135                                 usteer_ubus_band_steering_request(si, 0, false, 0, true, validity_period);
136                 }
137 
138                 si->band_steering.below_snr = false;
139         }
140 }

This page was automatically generated by LXR 0.3.1.  •  OpenWrt