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>
24 #include <libubox/blobmsg_json.h>
30 struct ubus_context
*ubus_ctx
;
31 struct usteer_config config
= {};
32 struct blob_attr
*host_info_blob
;
33 uint64_t current_time
;
36 LIST_HEAD(node_handlers
);
38 const char * const event_types
[__EVENT_TYPE_MAX
] = {
39 [EVENT_TYPE_PROBE
] = "probe",
40 [EVENT_TYPE_AUTH
] = "auth",
41 [EVENT_TYPE_ASSOC
] = "assoc",
44 void log_msg(char *msg
)
47 syslog(LOG_INFO
, "%s\n", msg
);
49 fprintf(stderr
, "%s\n", msg
);
52 void debug_msg(int level
, const char *func
, int line
, const char *format
, ...)
56 if (config
.debug_level
< level
)
60 fprintf(stderr
, "[%s:%d] ", func
, line
);
64 vsyslog(level
>= MSG_DEBUG
? LOG_DEBUG
: LOG_INFO
, format
, ap
);
66 vfprintf(stderr
, format
, ap
);
71 void debug_msg_cont(int level
, const char *format
, ...)
75 if (config
.debug_level
< level
)
79 vfprintf(stderr
, format
, ap
);
83 void usteer_init_defaults(void)
85 memset(&config
, 0, sizeof(config
));
87 config
.sta_block_timeout
= 30 * 1000;
88 config
.local_sta_timeout
= 120 * 1000;
89 config
.measurement_report_timeout
= 120 * 1000;
90 config
.local_sta_update
= 1 * 1000;
91 config
.max_retry_band
= 5;
92 config
.max_neighbor_reports
= 8;
93 config
.seen_policy_timeout
= 30 * 1000;
94 config
.band_steering_threshold
= 5;
95 config
.load_balancing_threshold
= 0;
96 config
.remote_update_interval
= 1000;
97 config
.initial_connect_delay
= 0;
98 config
.remote_node_timeout
= 10;
100 config
.steer_reject_timeout
= 60000;
102 config
.band_steering_interval
= 120000;
103 config
.band_steering_min_snr
= -60;
105 config
.link_measurement_interval
= 30000;
107 config
.probe_steering
= 0;
109 config
.roam_kick_delay
= 10000;
110 config
.roam_process_timeout
= 5 * 1000;
111 config
.roam_scan_tries
= 3;
112 config
.roam_scan_timeout
= 0;
113 config
.roam_scan_interval
= 10 * 1000;
114 config
.roam_trigger_interval
= 60 * 1000;
116 config
.min_snr_kick_delay
= 5 * 1000;
118 config
.load_kick_enabled
= false;
119 config
.load_kick_threshold
= 75;
120 config
.load_kick_delay
= 10 * 1000;
121 config
.load_kick_min_clients
= 10;
122 config
.load_kick_reason_code
= 5; /* WLAN_REASON_DISASSOC_AP_BUSY */
124 config
.debug_level
= MSG_FATAL
;
127 void usteer_update_time(void)
131 clock_gettime(CLOCK_MONOTONIC
, &ts
);
132 current_time
= (uint64_t) ts
.tv_sec
* 1000 + ts
.tv_nsec
/ 1000000;
135 static int usage(const char *prog
)
137 fprintf(stderr
, "Usage: %s [options]\n"
139 " -v: Increase debug level (repeat for more messages):\n"
140 " 1: info messages\n"
141 " 2: debug messages\n"
142 " 3: verbose debug messages\n"
143 " 4: include network messages\n"
144 " 5: include extra testing messages\n"
145 " -i <name>: Connect to other instances on interface <name>\n"
146 " -s: Output log messages via syslog instead of stderr\n"
147 " -D <n>: Do not daemonize, wait for <n> seconds and print\n"
148 " remote hosts and nodes\n"
154 usteer_dump_timeout(struct uloop_timeout
*t
)
156 struct usteer_remote_host
*host
;
157 struct usteer_remote_node
*rn
;
158 struct blob_buf b
= {};
162 blob_buf_init(&b
, 0);
164 c
= blobmsg_open_table(&b
, "hosts");
165 avl_for_each_element(&remote_hosts
, host
, avl
)
166 usteer_dump_host(&b
, host
);
167 blobmsg_close_table(&b
, c
);
169 c
= blobmsg_open_table(&b
, "nodes");
170 for_each_remote_node(rn
)
171 usteer_dump_node(&b
, &rn
->node
);
172 blobmsg_close_table(&b
, c
);
174 str
= blobmsg_format_json(b
.head
, true);
183 int main(int argc
, char **argv
)
185 struct uloop_timeout dump_timer
;
188 usteer_init_defaults();
190 while ((ch
= getopt(argc
, argv
, "D:i:sv")) != -1) {
193 config
.debug_level
++;
196 config
.syslog
= true;
199 usteer_interface_add(optarg
);
202 dump_time
= atoi(optarg
);
205 return usage(argv
[0]);
209 openlog("usteer", 0, LOG_USER
);
211 config_set_event_log_types(NULL
);
212 usteer_update_time();
215 ubus_ctx
= ubus_connect(NULL
);
217 fprintf(stderr
, "Failed to connect to ubus\n");
221 ubus_add_uloop(ubus_ctx
);
223 dump_timer
.cb
= usteer_dump_timeout
;
224 uloop_timeout_set(&dump_timer
, dump_time
* 1000);
226 usteer_ubus_init(ubus_ctx
);
227 usteer_local_nodes_init(ubus_ctx
);