-
Notifications
You must be signed in to change notification settings - Fork 7
/
usteer.h
373 lines (284 loc) · 9 KB
/
usteer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/*
* 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) 2020 embedd.ch
* Copyright (C) 2020 Felix Fietkau <[email protected]>
* Copyright (C) 2020 John Crispin <[email protected]>
*/
#ifndef __APMGR_H
#define __APMGR_H
#include <libubox/avl.h>
#include <libubox/blobmsg.h>
#include <libubox/uloop.h>
#include <libubox/utils.h>
#include <libubox/kvlist.h>
#include <libubus.h>
#include "utils.h"
#include "timeout.h"
#define NO_SIGNAL 0xff
#define __STR(x) #x
#define _STR(x) __STR(x)
#define APMGR_V6_MCAST_GROUP "ff02::4150"
#define APMGR_PORT 16720 /* AP */
#define APMGR_PORT_STR _STR(APMGR_PORT)
#define APMGR_BUFLEN (64 * 1024)
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
enum usteer_event_type {
EVENT_TYPE_PROBE,
EVENT_TYPE_ASSOC,
EVENT_TYPE_AUTH,
__EVENT_TYPE_MAX,
};
enum usteer_node_type {
NODE_TYPE_LOCAL,
NODE_TYPE_REMOTE,
};
enum usteer_sta_connection_state {
STA_NOT_CONNECTED = 0,
STA_CONNECTED = 1,
STA_DISCONNECTED = 2,
};
enum usteer_beacon_measurement_mode {
BEACON_MEASUREMENT_PASSIVE = 0,
BEACON_MEASUREMENT_ACTIVE = 1,
BEACON_MEASUREMENT_TABLE = 2,
};
struct sta_info;
struct usteer_local_node;
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;
struct blob_attr *rrm_nr;
struct blob_attr *node_info;
char ssid[33];
uint8_t bssid[6];
bool disabled;
int freq;
int channel;
int op_class;
int noise;
int n_assoc;
int max_assoc;
int load;
struct {
int source;
int target;
} roam_events;
uint64_t created;
};
struct usteer_scan_request {
int n_freq;
int *freq;
bool passive;
};
struct usteer_scan_result {
uint8_t bssid[6];
char ssid[33];
int freq;
int signal;
};
struct usteer_survey_data {
uint16_t freq;
int8_t noise;
uint64_t time;
uint64_t time_busy;
};
struct usteer_freq_data {
uint16_t freq;
uint8_t txpower;
bool dfs;
};
struct usteer_node_handler {
struct list_head list;
void (*init_node)(struct usteer_node *);
void (*free_node)(struct usteer_node *);
void (*update_node)(struct usteer_node *);
void (*update_sta)(struct usteer_node *, struct sta_info *);
void (*get_survey)(struct usteer_node *, void *,
void (*cb)(void *priv, struct usteer_survey_data *d));
void (*get_freqlist)(struct usteer_node *, void *,
void (*cb)(void *priv, struct usteer_freq_data *f));
int (*scan)(struct usteer_node *, struct usteer_scan_request *,
void *, void (*cb)(void *priv, struct usteer_scan_result *r));
};
struct usteer_config {
bool syslog;
uint32_t debug_level;
bool ipv6;
uint32_t sta_block_timeout;
uint32_t local_sta_timeout;
uint32_t local_sta_update;
uint32_t max_retry_band;
uint32_t seen_policy_timeout;
uint32_t measurement_report_timeout;
bool assoc_steering;
uint32_t max_neighbor_reports;
uint32_t band_steering_threshold;
uint32_t load_balancing_threshold;
uint32_t remote_update_interval;
uint32_t remote_node_timeout;
int32_t min_snr;
uint32_t min_snr_kick_delay;
int32_t min_connect_snr;
uint32_t signal_diff_threshold;
int32_t roam_scan_snr;
uint32_t roam_process_timeout;
uint32_t roam_scan_tries;
uint32_t roam_scan_timeout;
uint32_t roam_scan_interval;
int32_t roam_trigger_snr;
uint32_t roam_trigger_interval;
uint32_t roam_kick_delay;
uint32_t initial_connect_delay;
bool load_kick_enabled;
uint32_t load_kick_threshold;
uint32_t load_kick_delay;
uint32_t load_kick_min_clients;
uint32_t load_kick_reason_code;
const char *node_up_script;
uint32_t event_log_mask;
struct blob_attr *ssid_list;
};
struct usteer_bss_tm_query {
struct list_head list;
/* Can't use sta_info here, as the STA might already be deleted */
uint8_t sta_addr[6];
uint8_t dialog_token;
};
struct sta_info_stats {
uint32_t requests;
uint32_t blocked_cur;
uint32_t blocked_total;
uint32_t blocked_last_time;
};
enum roam_trigger_state {
ROAM_TRIGGER_IDLE,
ROAM_TRIGGER_SCAN,
ROAM_TRIGGER_SCAN_DONE,
ROAM_TRIGGER_WAIT_KICK,
ROAM_TRIGGER_NOTIFY_KICK,
ROAM_TRIGGER_KICK,
};
struct sta_info {
struct list_head list;
struct list_head node_list;
struct usteer_node *node;
struct sta *sta;
struct usteer_timeout timeout;
struct sta_info_stats stats[__EVENT_TYPE_MAX];
uint64_t created;
uint64_t seen;
uint64_t last_connected;
int signal;
enum roam_trigger_state roam_state;
uint8_t roam_tries;
uint64_t roam_event;
uint64_t roam_kick;
uint64_t roam_scan_start;
uint64_t roam_scan_timeout_start;
struct {
uint8_t status_code;
uint64_t timestamp;
} bss_transition_response;
int kick_count;
uint32_t below_min_snr;
uint8_t scan_band : 1;
uint8_t connected : 2;
};
struct sta {
struct avl_node avl;
struct list_head nodes;
struct list_head measurements;
uint8_t seen_2ghz : 1;
uint8_t seen_5ghz : 1;
uint8_t addr[6];
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;
extern struct avl_tree stations;
extern struct ubus_object usteer_obj;
extern uint64_t current_time;
extern const char * const event_types[__EVENT_TYPE_MAX];
extern struct blob_attr *host_info_blob;
void usteer_update_time(void);
void usteer_init_defaults(void);
bool usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr,
enum usteer_event_type type, int freq, int signal);
int usteer_snr_to_signal(struct usteer_node *node, int snr);
void usteer_local_nodes_init(struct ubus_context *ctx);
void usteer_local_node_kick(struct usteer_local_node *ln);
void usteer_ubus_init(struct ubus_context *ctx);
void usteer_ubus_kick_client(struct sta_info *si);
int usteer_ubus_trigger_client_scan(struct sta_info *si);
int usteer_ubus_notify_client_disassoc(struct sta_info *si);
int usteer_ubus_bss_transition_request(struct sta_info *si,
uint8_t dialog_token,
bool disassoc_imminent,
bool abridged,
uint8_t validity_period);
struct sta *usteer_sta_get(const uint8_t *addr, bool create);
struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create);
bool usteer_sta_supports_beacon_measurement_mode(struct sta *sta, enum usteer_beacon_measurement_mode mode);
void usteer_sta_disconnected(struct sta_info *si);
void usteer_sta_info_update_timeout(struct sta_info *si, int timeout);
void usteer_sta_info_update(struct sta_info *si, int signal, bool avg);
static inline const char *usteer_node_name(struct usteer_node *node)
{
return node->avl.key;
}
void usteer_node_set_blob(struct blob_attr **dest, struct blob_attr *val);
struct usteer_local_node *usteer_local_node_by_bssid(uint8_t *bssid);
struct usteer_remote_node *usteer_remote_node_by_bssid(uint8_t *bssid);
struct usteer_node *usteer_node_by_bssid(uint8_t *bssid);
struct usteer_node *usteer_node_get_next_neighbor(struct usteer_node *current_node, struct usteer_node *last);
bool usteer_check_request(struct sta_info *si, enum usteer_event_type type);
void config_set_interfaces(struct blob_attr *data);
void config_get_interfaces(struct blob_buf *buf);
void config_set_node_up_script(struct blob_attr *data);
void config_get_node_up_script(struct blob_buf *buf);
void config_set_ssid_list(struct blob_attr *data);
void config_get_ssid_list(struct blob_buf *buf);
int usteer_interface_init(void);
void usteer_interface_add(const char *name);
void usteer_sta_node_cleanup(struct usteer_node *node);
void usteer_send_sta_update(struct sta_info *si);
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