rework log handling
[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 <libubus.h>
28 #include "utils.h"
29 #include "timeout.h"
30
31 #define NO_SIGNAL 0xff
32
33 #define __STR(x) #x
34 #define _STR(x) __STR(x)
35 #define APMGR_PORT 16720 /* AP */
36 #define APMGR_PORT_STR _STR(APMGR_PORT)
37 #define APMGR_BUFLEN (64 * 1024)
38
39 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
40
41 enum usteer_event_type {
42 EVENT_TYPE_PROBE,
43 EVENT_TYPE_ASSOC,
44 EVENT_TYPE_AUTH,
45 __EVENT_TYPE_MAX,
46 };
47
48 enum usteer_node_type {
49 NODE_TYPE_LOCAL,
50 NODE_TYPE_REMOTE,
51 };
52
53 struct sta_info;
54 struct usteer_local_node;
55
56 struct usteer_node {
57 struct avl_node avl;
58 struct list_head sta_info;
59
60 enum usteer_node_type type;
61
62 struct blob_attr *rrm_nr;
63 struct blob_attr *script_data;
64 char ssid[33];
65
66 int freq;
67 int noise;
68 int n_assoc;
69 int max_assoc;
70 int load;
71 };
72
73 struct usteer_scan_request {
74 int n_freq;
75 int *freq;
76
77 bool passive;
78 };
79
80 struct usteer_scan_result {
81 uint8_t bssid[6];
82 char ssid[33];
83
84 int freq;
85 int signal;
86 };
87
88 struct usteer_survey_data {
89 uint16_t freq;
90 int8_t noise;
91
92 uint64_t time;
93 uint64_t time_busy;
94 };
95
96 struct usteer_freq_data {
97 uint16_t freq;
98
99 uint8_t txpower;
100 bool dfs;
101 };
102
103 struct usteer_node_handler {
104 struct list_head list;
105
106 void (*init_node)(struct usteer_node *);
107 void (*free_node)(struct usteer_node *);
108 void (*update_node)(struct usteer_node *);
109 void (*update_sta)(struct usteer_node *, struct sta_info *);
110 void (*get_survey)(struct usteer_node *, void *,
111 void (*cb)(void *priv, struct usteer_survey_data *d));
112 void (*get_freqlist)(struct usteer_node *, void *,
113 void (*cb)(void *priv, struct usteer_freq_data *f));
114 int (*scan)(struct usteer_node *, struct usteer_scan_request *,
115 void *, void (*cb)(void *priv, struct usteer_scan_result *r));
116 };
117
118 struct usteer_config {
119 bool syslog;
120 uint32_t debug_level;
121
122 uint32_t sta_block_timeout;
123 uint32_t local_sta_timeout;
124 uint32_t local_sta_update;
125
126 uint32_t max_retry_band;
127 uint32_t seen_policy_timeout;
128
129 bool assoc_steering;
130
131 uint32_t band_steering_threshold;
132 uint32_t load_balancing_threshold;
133
134 uint32_t remote_update_interval;
135 uint32_t remote_node_timeout;
136
137 int32_t min_snr;
138 int32_t min_connect_snr;
139 uint32_t signal_diff_threshold;
140
141 int32_t roam_scan_snr;
142 uint32_t roam_scan_tries;
143 uint32_t roam_scan_interval;
144
145 int32_t roam_trigger_snr;
146 uint32_t roam_trigger_interval;
147
148 uint32_t roam_kick_delay;
149
150 uint32_t initial_connect_delay;
151
152 bool load_kick_enabled;
153 uint32_t load_kick_threshold;
154 uint32_t load_kick_delay;
155 uint32_t load_kick_min_clients;
156 uint32_t load_kick_reason_code;
157
158 const char *node_up_script;
159 uint32_t event_log_mask;
160 };
161
162 struct sta_info_stats {
163 uint32_t requests;
164 uint32_t blocked_cur;
165 uint32_t blocked_total;
166 uint32_t blocked_last_time;
167 };
168
169 enum roam_trigger_state {
170 ROAM_TRIGGER_IDLE,
171 ROAM_TRIGGER_SCAN,
172 ROAM_TRIGGER_SCAN_DONE,
173 ROAM_TRIGGER_WAIT_KICK,
174 ROAM_TRIGGER_NOTIFY_KICK,
175 ROAM_TRIGGER_KICK,
176 };
177
178 struct sta_info {
179 struct list_head list;
180 struct list_head node_list;
181
182 struct usteer_node *node;
183 struct sta *sta;
184
185 struct usteer_timeout timeout;
186
187 struct sta_info_stats stats[__EVENT_TYPE_MAX];
188 uint64_t created;
189 uint64_t seen;
190 int signal;
191
192 enum roam_trigger_state roam_state;
193 uint8_t roam_tries;
194 uint64_t roam_event;
195 uint64_t roam_kick;
196 uint64_t roam_scan_done;
197
198 int kick_count;
199
200 uint8_t scan_band : 1;
201 uint8_t connected : 2;
202 };
203
204 struct sta {
205 struct avl_node avl;
206 struct list_head nodes;
207
208 uint8_t seen_2ghz : 1;
209 uint8_t seen_5ghz : 1;
210
211 uint8_t addr[6];
212 };
213
214 extern struct ubus_context *ubus_ctx;
215 extern struct usteer_config config;
216 extern struct list_head node_handlers;
217 extern struct avl_tree stations;
218 extern struct ubus_object usteer_obj;
219 extern uint64_t current_time;
220 extern const char * const event_types[__EVENT_TYPE_MAX];
221
222 void usteer_update_time(void);
223 void usteer_init_defaults(void);
224 bool usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr,
225 enum usteer_event_type type, int freq, int signal);
226
227 void usteer_local_nodes_init(struct ubus_context *ctx);
228 void usteer_local_node_kick(struct usteer_local_node *ln);
229
230 void usteer_ubus_init(struct ubus_context *ctx);
231 void usteer_ubus_kick_client(struct sta_info *si);
232 int usteer_ubus_trigger_client_scan(struct sta_info *si);
233 int usteer_ubus_notify_client_disassoc(struct sta_info *si);
234
235 struct sta *usteer_sta_get(const uint8_t *addr, bool create);
236 struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create);
237
238 void usteer_sta_info_update_timeout(struct sta_info *si, int timeout);
239 void usteer_sta_info_update(struct sta_info *si, int signal, bool avg);
240
241 static inline const char *usteer_node_name(struct usteer_node *node)
242 {
243 return node->avl.key;
244 }
245 void usteer_node_set_blob(struct blob_attr **dest, struct blob_attr *val);
246
247 bool usteer_check_request(struct sta_info *si, enum usteer_event_type type);
248
249 void config_set_interfaces(struct blob_attr *data);
250 void config_get_interfaces(struct blob_buf *buf);
251
252 void config_set_node_up_script(struct blob_attr *data);
253 void config_get_node_up_script(struct blob_buf *buf);
254
255 int usteer_interface_init(void);
256 void usteer_interface_add(const char *name);
257 void usteer_sta_node_cleanup(struct usteer_node *node);
258 void usteer_send_sta_update(struct sta_info *si);
259
260 int usteer_lua_init(void);
261 int usteer_lua_ubus_init(void);
262 void usteer_run_hook(const char *name, const char *arg);
263
264 #endif