87ee1f3f4a25d5e29d9173291ecea9d81c394a66
[project/usteer.git] / usteer.h
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 struct sta_info;
64 struct usteer_local_node;
65 struct usteer_remote_host;
66
67 struct usteer_node {
68 struct avl_node avl;
69 struct list_head sta_info;
70
71 enum usteer_node_type type;
72
73 struct blob_attr *rrm_nr;
74 struct blob_attr *node_info;
75 char ssid[33];
76 uint8_t bssid[6];
77
78 bool disabled;
79 int freq;
80 int noise;
81 int n_assoc;
82 int max_assoc;
83 int load;
84 };
85
86 struct usteer_scan_request {
87 int n_freq;
88 int *freq;
89
90 bool passive;
91 };
92
93 struct usteer_scan_result {
94 uint8_t bssid[6];
95 char ssid[33];
96
97 int freq;
98 int signal;
99 };
100
101 struct usteer_survey_data {
102 uint16_t freq;
103 int8_t noise;
104
105 uint64_t time;
106 uint64_t time_busy;
107 };
108
109 struct usteer_freq_data {
110 uint16_t freq;
111
112 uint8_t txpower;
113 bool dfs;
114 };
115
116 struct usteer_node_handler {
117 struct list_head list;
118
119 void (*init_node)(struct usteer_node *);
120 void (*free_node)(struct usteer_node *);
121 void (*update_node)(struct usteer_node *);
122 void (*update_sta)(struct usteer_node *, struct sta_info *);
123 void (*get_survey)(struct usteer_node *, void *,
124 void (*cb)(void *priv, struct usteer_survey_data *d));
125 void (*get_freqlist)(struct usteer_node *, void *,
126 void (*cb)(void *priv, struct usteer_freq_data *f));
127 int (*scan)(struct usteer_node *, struct usteer_scan_request *,
128 void *, void (*cb)(void *priv, struct usteer_scan_result *r));
129 };
130
131 struct usteer_config {
132 bool syslog;
133 uint32_t debug_level;
134
135 bool ipv6;
136
137 uint32_t sta_block_timeout;
138 uint32_t local_sta_timeout;
139 uint32_t local_sta_update;
140
141 uint32_t max_retry_band;
142 uint32_t seen_policy_timeout;
143
144 bool assoc_steering;
145
146 uint32_t band_steering_threshold;
147 uint32_t load_balancing_threshold;
148
149 uint32_t remote_update_interval;
150 uint32_t remote_node_timeout;
151
152 int32_t min_snr;
153 int32_t min_connect_snr;
154 uint32_t signal_diff_threshold;
155
156 int32_t roam_scan_snr;
157 uint32_t roam_scan_tries;
158 uint32_t roam_scan_interval;
159
160 int32_t roam_trigger_snr;
161 uint32_t roam_trigger_interval;
162
163 uint32_t roam_kick_delay;
164
165 uint32_t initial_connect_delay;
166
167 bool load_kick_enabled;
168 uint32_t load_kick_threshold;
169 uint32_t load_kick_delay;
170 uint32_t load_kick_min_clients;
171 uint32_t load_kick_reason_code;
172
173 const char *node_up_script;
174 uint32_t event_log_mask;
175
176 struct blob_attr *ssid_list;
177 };
178
179 struct sta_info_stats {
180 uint32_t requests;
181 uint32_t blocked_cur;
182 uint32_t blocked_total;
183 uint32_t blocked_last_time;
184 };
185
186 enum roam_trigger_state {
187 ROAM_TRIGGER_IDLE,
188 ROAM_TRIGGER_SCAN,
189 ROAM_TRIGGER_SCAN_DONE,
190 ROAM_TRIGGER_WAIT_KICK,
191 ROAM_TRIGGER_NOTIFY_KICK,
192 ROAM_TRIGGER_KICK,
193 };
194
195 struct sta_info {
196 struct list_head list;
197 struct list_head node_list;
198
199 struct usteer_node *node;
200 struct sta *sta;
201
202 struct usteer_timeout timeout;
203
204 struct sta_info_stats stats[__EVENT_TYPE_MAX];
205 uint64_t created;
206 uint64_t seen;
207 int signal;
208
209 enum roam_trigger_state roam_state;
210 uint8_t roam_tries;
211 uint64_t roam_event;
212 uint64_t roam_kick;
213 uint64_t roam_scan_done;
214
215 int kick_count;
216
217 uint8_t scan_band : 1;
218 uint8_t connected : 2;
219 };
220
221 struct sta {
222 struct avl_node avl;
223 struct list_head nodes;
224
225 uint8_t seen_2ghz : 1;
226 uint8_t seen_5ghz : 1;
227
228 uint8_t addr[6];
229 };
230
231 extern struct ubus_context *ubus_ctx;
232 extern struct usteer_config config;
233 extern struct list_head node_handlers;
234 extern struct avl_tree stations;
235 extern struct ubus_object usteer_obj;
236 extern uint64_t current_time;
237 extern const char * const event_types[__EVENT_TYPE_MAX];
238 extern struct blob_attr *host_info_blob;
239
240 void usteer_update_time(void);
241 void usteer_init_defaults(void);
242 bool usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr,
243 enum usteer_event_type type, int freq, int signal);
244
245 void usteer_local_nodes_init(struct ubus_context *ctx);
246 void usteer_local_node_kick(struct usteer_local_node *ln);
247
248 void usteer_ubus_init(struct ubus_context *ctx);
249 void usteer_ubus_kick_client(struct sta_info *si);
250 int usteer_ubus_trigger_client_scan(struct sta_info *si);
251 int usteer_ubus_notify_client_disassoc(struct sta_info *si);
252
253 struct sta *usteer_sta_get(const uint8_t *addr, bool create);
254 struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create);
255
256 void usteer_sta_info_update_timeout(struct sta_info *si, int timeout);
257 void usteer_sta_info_update(struct sta_info *si, int signal, bool avg);
258
259 static inline const char *usteer_node_name(struct usteer_node *node)
260 {
261 return node->avl.key;
262 }
263 void usteer_node_set_blob(struct blob_attr **dest, struct blob_attr *val);
264
265 bool usteer_check_request(struct sta_info *si, enum usteer_event_type type);
266
267 void config_set_interfaces(struct blob_attr *data);
268 void config_get_interfaces(struct blob_buf *buf);
269
270 void config_set_node_up_script(struct blob_attr *data);
271 void config_get_node_up_script(struct blob_buf *buf);
272
273 void config_set_ssid_list(struct blob_attr *data);
274 void config_get_ssid_list(struct blob_buf *buf);
275
276 int usteer_interface_init(void);
277 void usteer_interface_add(const char *name);
278 void usteer_sta_node_cleanup(struct usteer_node *node);
279 void usteer_send_sta_update(struct sta_info *si);
280
281 int usteer_lua_init(void);
282 int usteer_lua_ubus_init(void);
283 void usteer_run_hook(const char *name, const char *arg);
284
285 void usteer_dump_node(struct blob_buf *buf, struct usteer_node *node);
286 void usteer_dump_host(struct blob_buf *buf, struct usteer_remote_host *host);
287
288 #endif