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) 2020 embedd.ch 16 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> 17 * Copyright (C) 2020 John Crispin <john@phrozen.org> 18 */ 19 20 #ifndef __APMGR_H 21 #define __APMGR_H 22 23 #include <libubox/avl.h> 24 #include <libubox/blobmsg.h> 25 #include <libubox/uloop.h> 26 #include <libubox/utils.h> 27 #include <libubox/kvlist.h> 28 #include <libubus.h> 29 #include "utils.h" 30 #include "timeout.h" 31 32 #define NO_SIGNAL 0xff 33 34 #define __STR(x) #x 35 #define _STR(x) __STR(x) 36 37 #define APMGR_V6_MCAST_GROUP "ff02::4150" 38 39 #define APMGR_PORT 16720 /* AP */ 40 #define APMGR_PORT_STR _STR(APMGR_PORT) 41 #define APMGR_BUFLEN (64 * 1024) 42 43 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 44 45 enum usteer_event_type { 46 EVENT_TYPE_PROBE, 47 EVENT_TYPE_ASSOC, 48 EVENT_TYPE_AUTH, 49 __EVENT_TYPE_MAX, 50 }; 51 52 enum usteer_node_type { 53 NODE_TYPE_LOCAL, 54 NODE_TYPE_REMOTE, 55 }; 56 57 enum usteer_sta_connection_state { 58 STA_NOT_CONNECTED = 0, 59 STA_CONNECTED = 1, 60 STA_DISCONNECTED = 2, 61 }; 62 63 enum usteer_beacon_measurement_mode { 64 BEACON_MEASUREMENT_PASSIVE = 0, 65 BEACON_MEASUREMENT_ACTIVE = 1, 66 BEACON_MEASUREMENT_TABLE = 2, 67 }; 68 69 enum usteer_kick_reason_code 70 { 71 KICK_REASON_UNSPECIFIED = 1, 72 KICK_REASON_LOAD = 5, 73 KICK_REASON_BSS_TRANSITION = 12, 74 }; 75 76 struct sta_info; 77 struct usteer_local_node; 78 struct usteer_remote_host; 79 80 struct usteer_node { 81 struct avl_node avl; 82 struct list_head sta_info; 83 struct list_head measurements; 84 85 enum usteer_node_type type; 86 87 struct blob_attr *rrm_nr; 88 struct blob_attr *node_info; 89 char ssid[33]; 90 uint8_t bssid[6]; 91 92 bool disabled; 93 int freq; 94 int channel; 95 int op_class; 96 int noise; 97 int n_assoc; 98 int max_assoc; 99 int load; 100 101 struct { 102 int source; 103 int target; 104 } roam_events; 105 106 uint64_t created; 107 }; 108 109 struct usteer_scan_request { 110 int n_freq; 111 int *freq; 112 113 bool passive; 114 }; 115 116 struct usteer_scan_result { 117 uint8_t bssid[6]; 118 char ssid[33]; 119 120 int freq; 121 int signal; 122 }; 123 124 struct usteer_survey_data { 125 uint16_t freq; 126 int8_t noise; 127 128 uint64_t time; 129 uint64_t time_busy; 130 }; 131 132 struct usteer_freq_data { 133 uint16_t freq; 134 135 uint8_t txpower; 136 bool dfs; 137 }; 138 139 struct usteer_node_handler { 140 struct list_head list; 141 142 void (*init_node)(struct usteer_node *); 143 void (*free_node)(struct usteer_node *); 144 void (*update_node)(struct usteer_node *); 145 void (*update_sta)(struct usteer_node *, struct sta_info *); 146 void (*get_survey)(struct usteer_node *, void *, 147 void (*cb)(void *priv, struct usteer_survey_data *d)); 148 void (*get_freqlist)(struct usteer_node *, void *, 149 void (*cb)(void *priv, struct usteer_freq_data *f)); 150 int (*scan)(struct usteer_node *, struct usteer_scan_request *, 151 void *, void (*cb)(void *priv, struct usteer_scan_result *r)); 152 }; 153 154 struct usteer_config { 155 bool syslog; 156 uint32_t debug_level; 157 158 bool ipv6; 159 bool local_mode; 160 161 uint32_t sta_block_timeout; 162 uint32_t local_sta_timeout; 163 uint32_t local_sta_update; 164 165 uint32_t max_retry_band; 166 uint32_t seen_policy_timeout; 167 uint32_t measurement_report_timeout; 168 169 bool assoc_steering; 170 bool probe_steering; 171 172 uint32_t max_neighbor_reports; 173 174 uint32_t band_steering_threshold; 175 uint32_t load_balancing_threshold; 176 177 uint32_t remote_update_interval; 178 uint32_t remote_node_timeout; 179 180 uint32_t aggressiveness; 181 struct blob_attr *aggressiveness_mac_list; 182 uint32_t aggressive_disassoc_timer; 183 uint32_t reassociation_delay; 184 185 int32_t min_snr; 186 uint32_t min_snr_kick_delay; 187 int32_t min_connect_snr; 188 uint32_t signal_diff_threshold; 189 190 uint32_t steer_reject_timeout; 191 192 int32_t roam_scan_snr; 193 uint32_t roam_process_timeout; 194 195 uint32_t roam_scan_tries; 196 uint32_t roam_scan_timeout; 197 uint32_t roam_scan_interval; 198 199 int32_t roam_trigger_snr; 200 uint32_t roam_trigger_interval; 201 202 uint32_t roam_kick_delay; 203 204 uint32_t band_steering_interval; 205 int32_t band_steering_min_snr; 206 uint32_t band_steering_signal_threshold; 207 208 uint32_t link_measurement_interval; 209 210 uint32_t initial_connect_delay; 211 212 bool load_kick_enabled; 213 uint32_t load_kick_threshold; 214 uint32_t load_kick_delay; 215 uint32_t load_kick_min_clients; 216 uint32_t load_kick_reason_code; 217 218 const char *node_up_script; 219 uint32_t event_log_mask; 220 221 struct blob_attr *ssid_list; 222 }; 223 224 struct usteer_bss_tm_query { 225 struct list_head list; 226 227 /* Can't use sta_info here, as the STA might already be deleted */ 228 uint8_t sta_addr[6]; 229 uint8_t dialog_token; 230 }; 231 232 struct sta_info_stats { 233 uint32_t requests; 234 uint32_t blocked_cur; 235 uint32_t blocked_total; 236 uint32_t blocked_last_time; 237 }; 238 239 enum roam_trigger_state { 240 ROAM_TRIGGER_IDLE, 241 ROAM_TRIGGER_SCAN, 242 ROAM_TRIGGER_SCAN_DONE, 243 }; 244 245 struct sta_info { 246 struct list_head list; 247 struct list_head node_list; 248 249 struct usteer_node *node; 250 struct sta *sta; 251 252 struct usteer_timeout timeout; 253 254 struct sta_info_stats stats[__EVENT_TYPE_MAX]; 255 uint64_t created; 256 uint64_t seen; 257 258 uint64_t connected_since; 259 uint64_t last_connected; 260 261 int signal; 262 263 uint8_t rrm; 264 bool bss_transition; 265 bool mbo; 266 267 enum roam_trigger_state roam_state; 268 uint8_t roam_tries; 269 uint64_t roam_event; 270 uint64_t roam_transition_request_validity_end; 271 uint64_t roam_transition_start; 272 uint64_t roam_kick; 273 uint64_t roam_scan_start; 274 uint64_t roam_scan_timeout_start; 275 276 struct { 277 uint8_t status_code; 278 uint64_t timestamp; 279 } bss_transition_response; 280 281 struct { 282 bool below_snr; 283 int signal_threshold; 284 } band_steering; 285 286 uint64_t kick_time; 287 288 int kick_count; 289 290 uint32_t below_min_snr; 291 292 uint8_t scan_band : 1; 293 uint8_t connected : 2; 294 }; 295 296 struct sta { 297 struct avl_node avl; 298 struct list_head nodes; 299 struct list_head measurements; 300 301 uint8_t seen_2ghz : 1; 302 uint8_t seen_5ghz : 1; 303 304 uint32_t aggressiveness; 305 306 uint8_t addr[6]; 307 }; 308 309 struct usteer_measurement_report { 310 struct usteer_timeout timeout; 311 312 struct list_head list; 313 314 struct usteer_node *node; 315 struct list_head node_list; 316 317 struct sta *sta; 318 struct list_head sta_list; 319 320 uint64_t timestamp; 321 322 uint8_t rcpi; 323 uint8_t rsni; 324 }; 325 326 extern struct ubus_context *ubus_ctx; 327 extern struct usteer_config config; 328 extern struct list_head node_handlers; 329 extern struct avl_tree stations; 330 extern struct ubus_object usteer_obj; 331 extern uint64_t current_time; 332 extern const char * const event_types[__EVENT_TYPE_MAX]; 333 extern struct blob_attr *host_info_blob; 334 335 void usteer_update_time(void); 336 void usteer_init_defaults(void); 337 bool usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr, 338 enum usteer_event_type type, int freq, int signal); 339 340 int usteer_snr_to_signal(struct usteer_node *node, int snr); 341 342 void usteer_local_nodes_init(struct ubus_context *ctx); 343 void usteer_local_node_kick(struct usteer_local_node *ln); 344 345 int usteer_local_node_get_beacon_interval(struct usteer_local_node *ln); 346 347 bool usteer_policy_node_below_max_assoc(struct usteer_node *node); 348 bool usteer_policy_can_perform_roam(struct sta_info *si); 349 350 void usteer_band_steering_perform_steer(struct usteer_local_node *ln); 351 void usteer_band_steering_sta_update(struct sta_info *si); 352 bool usteer_band_steering_is_target(struct usteer_local_node *ln, struct usteer_node *node); 353 354 void usteer_ubus_init(struct ubus_context *ctx); 355 void usteer_ubus_kick_client(struct sta_info *si, uint32_t kick_reason_code); 356 int usteer_ubus_trigger_client_scan(struct sta_info *si); 357 int usteer_ubus_band_steering_request(struct sta_info *si, 358 uint8_t dialog_token, 359 bool disassoc_imminent, 360 uint32_t disassoc_timer, 361 bool abridged, 362 uint8_t validity_period); 363 int usteer_ubus_bss_transition_request(struct sta_info *si, 364 uint8_t dialog_token, 365 bool disassoc_imminent, 366 uint32_t disassoc_timer, 367 bool abridged, 368 uint8_t validity_period, 369 struct usteer_node *target_node); 370 371 struct sta *usteer_sta_get(const uint8_t *addr, bool create); 372 struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create); 373 374 bool usteer_sta_supports_beacon_measurement_mode(struct sta_info *si, enum usteer_beacon_measurement_mode mode); 375 bool usteer_sta_supports_link_measurement(struct sta_info *si); 376 377 void usteer_sta_disconnected(struct sta_info *si); 378 void usteer_sta_info_update_timeout(struct sta_info *si, int timeout); 379 void usteer_sta_info_update(struct sta_info *si, int signal, bool avg); 380 381 static inline const char *usteer_node_name(struct usteer_node *node) 382 { 383 return node->avl.key; 384 } 385 void usteer_node_set_blob(struct blob_attr **dest, struct blob_attr *val); 386 387 struct usteer_local_node *usteer_local_node_by_bssid(uint8_t *bssid); 388 struct usteer_remote_node *usteer_remote_node_by_bssid(uint8_t *bssid); 389 struct usteer_node *usteer_node_by_bssid(uint8_t *bssid); 390 391 struct usteer_node *usteer_node_get_next_neighbor(struct usteer_node *current_node, struct usteer_node *last); 392 bool usteer_check_request(struct sta_info *si, enum usteer_event_type type); 393 394 void config_set_interfaces(struct blob_attr *data); 395 void config_get_interfaces(struct blob_buf *buf); 396 397 void config_set_node_up_script(struct blob_attr *data); 398 void config_get_node_up_script(struct blob_buf *buf); 399 400 void config_set_ssid_list(struct blob_attr *data); 401 void config_get_ssid_list(struct blob_buf *buf); 402 403 void config_set_aggressiveness_mac_list(struct blob_attr *data); 404 void config_get_aggressiveness_mac_list(struct blob_buf *buf); 405 406 int usteer_interface_init(void); 407 void usteer_interface_add(const char *name); 408 void usteer_sta_node_cleanup(struct usteer_node *node); 409 void usteer_send_sta_update(struct sta_info *si); 410 411 int usteer_lua_init(void); 412 int usteer_lua_ubus_init(void); 413 void usteer_run_hook(const char *name, const char *arg); 414 415 void usteer_dump_node(struct blob_buf *buf, struct usteer_node *node); 416 void usteer_dump_host(struct blob_buf *buf, struct usteer_remote_host *host); 417 418 int usteer_measurement_get_rssi(struct usteer_measurement_report *report); 419 420 struct usteer_measurement_report * usteer_measurement_report_get(struct sta *sta, struct usteer_node *node, bool create); 421 void usteer_measurement_report_node_cleanup(struct usteer_node *node); 422 void usteer_measurement_report_sta_cleanup(struct sta *sta); 423 void usteer_measurement_report_del(struct usteer_measurement_report *mr); 424 425 struct usteer_measurement_report * 426 usteer_measurement_report_add(struct sta *sta, struct usteer_node *node, uint8_t rcpi, uint8_t rsni, uint64_t timestamp); 427 428 429 int usteer_ubus_trigger_link_measurement(struct sta_info *si); 430 #endif 431
This page was automatically generated by LXR 0.3.1. • OpenWrt