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.
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.
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.
15 * Copyright (C) 2020 embedd.ch
16 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
17 * Copyright (C) 2020 John Crispin <john@phrozen.org>
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>
32 #define NO_SIGNAL 0xff
35 #define _STR(x) __STR(x)
36 #define APMGR_PORT 16720 /* AP */
37 #define APMGR_PORT_STR _STR(APMGR_PORT)
38 #define APMGR_BUFLEN (64 * 1024)
40 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
42 enum usteer_event_type
{
49 enum usteer_node_type
{
55 struct usteer_local_node
;
59 struct list_head sta_info
;
61 enum usteer_node_type type
;
63 struct blob_attr
*rrm_nr
;
64 struct blob_attr
*script_data
;
75 struct usteer_scan_request
{
82 struct usteer_scan_result
{
90 struct usteer_survey_data
{
98 struct usteer_freq_data
{
105 struct usteer_node_handler
{
106 struct list_head list
;
108 void (*init_node
)(struct usteer_node
*);
109 void (*free_node
)(struct usteer_node
*);
110 void (*update_node
)(struct usteer_node
*);
111 void (*update_sta
)(struct usteer_node
*, struct sta_info
*);
112 void (*get_survey
)(struct usteer_node
*, void *,
113 void (*cb
)(void *priv
, struct usteer_survey_data
*d
));
114 void (*get_freqlist
)(struct usteer_node
*, void *,
115 void (*cb
)(void *priv
, struct usteer_freq_data
*f
));
116 int (*scan
)(struct usteer_node
*, struct usteer_scan_request
*,
117 void *, void (*cb
)(void *priv
, struct usteer_scan_result
*r
));
120 struct usteer_config
{
122 uint32_t debug_level
;
124 uint32_t sta_block_timeout
;
125 uint32_t local_sta_timeout
;
126 uint32_t local_sta_update
;
128 uint32_t max_retry_band
;
129 uint32_t seen_policy_timeout
;
133 uint32_t band_steering_threshold
;
134 uint32_t load_balancing_threshold
;
136 uint32_t remote_update_interval
;
137 uint32_t remote_node_timeout
;
140 int32_t min_connect_snr
;
141 uint32_t signal_diff_threshold
;
143 int32_t roam_scan_snr
;
144 uint32_t roam_scan_tries
;
145 uint32_t roam_scan_interval
;
147 int32_t roam_trigger_snr
;
148 uint32_t roam_trigger_interval
;
150 uint32_t roam_kick_delay
;
152 uint32_t initial_connect_delay
;
154 bool load_kick_enabled
;
155 uint32_t load_kick_threshold
;
156 uint32_t load_kick_delay
;
157 uint32_t load_kick_min_clients
;
158 uint32_t load_kick_reason_code
;
160 const char *node_up_script
;
161 uint32_t event_log_mask
;
163 struct blob_attr
*ssid_list
;
166 struct sta_info_stats
{
168 uint32_t blocked_cur
;
169 uint32_t blocked_total
;
170 uint32_t blocked_last_time
;
173 enum roam_trigger_state
{
176 ROAM_TRIGGER_SCAN_DONE
,
177 ROAM_TRIGGER_WAIT_KICK
,
178 ROAM_TRIGGER_NOTIFY_KICK
,
183 struct list_head list
;
184 struct list_head node_list
;
186 struct usteer_node
*node
;
189 struct usteer_timeout timeout
;
191 struct sta_info_stats stats
[__EVENT_TYPE_MAX
];
196 enum roam_trigger_state roam_state
;
200 uint64_t roam_scan_done
;
204 uint8_t scan_band
: 1;
205 uint8_t connected
: 2;
210 struct list_head nodes
;
212 uint8_t seen_2ghz
: 1;
213 uint8_t seen_5ghz
: 1;
218 extern struct ubus_context
*ubus_ctx
;
219 extern struct usteer_config config
;
220 extern struct list_head node_handlers
;
221 extern struct avl_tree stations
;
222 extern struct ubus_object usteer_obj
;
223 extern uint64_t current_time
;
224 extern const char * const event_types
[__EVENT_TYPE_MAX
];
226 void usteer_update_time(void);
227 void usteer_init_defaults(void);
228 bool usteer_handle_sta_event(struct usteer_node
*node
, const uint8_t *addr
,
229 enum usteer_event_type type
, int freq
, int signal
);
231 void usteer_local_nodes_init(struct ubus_context
*ctx
);
232 void usteer_local_node_kick(struct usteer_local_node
*ln
);
233 void usteer_local_node_update_script_data(struct usteer_local_node
*ln
);
235 void usteer_ubus_init(struct ubus_context
*ctx
);
236 void usteer_ubus_kick_client(struct sta_info
*si
);
237 int usteer_ubus_trigger_client_scan(struct sta_info
*si
);
238 int usteer_ubus_notify_client_disassoc(struct sta_info
*si
);
240 struct sta
*usteer_sta_get(const uint8_t *addr
, bool create
);
241 struct sta_info
*usteer_sta_info_get(struct sta
*sta
, struct usteer_node
*node
, bool *create
);
243 void usteer_sta_info_update_timeout(struct sta_info
*si
, int timeout
);
244 void usteer_sta_info_update(struct sta_info
*si
, int signal
, bool avg
);
246 static inline const char *usteer_node_name(struct usteer_node
*node
)
248 return node
->avl
.key
;
250 void usteer_node_set_blob(struct blob_attr
**dest
, struct blob_attr
*val
);
252 bool usteer_check_request(struct sta_info
*si
, enum usteer_event_type type
);
254 void config_set_interfaces(struct blob_attr
*data
);
255 void config_get_interfaces(struct blob_buf
*buf
);
257 void config_set_node_up_script(struct blob_attr
*data
);
258 void config_get_node_up_script(struct blob_buf
*buf
);
260 void config_set_ssid_list(struct blob_attr
*data
);
261 void config_get_ssid_list(struct blob_buf
*buf
);
263 int usteer_interface_init(void);
264 void usteer_interface_add(const char *name
);
265 void usteer_sta_node_cleanup(struct usteer_node
*node
);
266 void usteer_send_sta_update(struct sta_info
*si
);
268 int usteer_lua_init(void);
269 int usteer_lua_ubus_init(void);
270 void usteer_run_hook(const char *name
, const char *arg
);