interface_add_station(struct usteer_remote_node *node, struct blob_attr *data)
{
struct sta *sta;
- struct sta_info *si;
+ struct sta_info *si, *local_si;
struct apmsg_sta msg;
+ struct usteer_node *local_node;
bool create;
+ bool connect_change;
if (!parse_apmsg_sta(&msg, data)) {
MSG(DEBUG, "Cannot parse station in message\n");
if (!si)
return;
+ connect_change = si->connected != msg.connected;
si->connected = msg.connected;
si->signal = msg.signal;
si->seen = current_time - msg.seen;
+ si->last_connected = current_time - msg.last_connected;
+
+ /* Check if client roamed to this foreign node */
+ if ((connect_change || create) && si->connected == STA_CONNECTED) {
+ for_each_local_node(local_node) {
+ local_si = usteer_sta_info_get(sta, local_node, NULL);
+ if (!local_si)
+ continue;
+
+ if (current_time - local_si->last_connected < config.roam_process_timeout) {
+ node->node.roam_events.target++;
+ break;
+ }
+ }
+ }
+
usteer_sta_info_update_timeout(si, msg.timeout);
}
list_del(&node->list);
list_del(&node->host_list);
usteer_sta_node_cleanup(&node->node);
+ usteer_measurement_report_node_cleanup(&node->node);
free(node);
if (!list_empty(&host->nodes))
node = calloc_a(sizeof(*node), &buf, addr_len + 1 + strlen(name) + 1);
node->node.type = NODE_TYPE_REMOTE;
+ node->node.created = current_time;
sprintf(buf, "%s#%s", host->addr, name);
node->node.avl.key = buf;
node->name = buf + addr_len + 1;
node->host = host;
INIT_LIST_HEAD(&node->node.sta_info);
+ INIT_LIST_HEAD(&node->node.measurements);
list_add_tail(&node->list, &remote_nodes);
list_add_tail(&node->host_list, &host->nodes);
node = interface_get_node(host, msg.name);
node->check = 0;
node->node.freq = msg.freq;
+ node->node.channel = msg.channel;
+ node->node.op_class = msg.op_class;
node->node.n_assoc = msg.n_assoc;
node->node.max_assoc = msg.max_assoc;
node->node.noise = msg.noise;
struct blob_attr *cur;
int rem;
+ if (config.local_mode)
+ return;
+
if (blob_pad_len(data) != len) {
MSG(DEBUG, "Invalid message length (header: %d, real: %d)\n", blob_pad_len(data), len);
return;
static void usteer_send_sta_info(struct sta_info *sta)
{
int seen = current_time - sta->seen;
+ int last_connected = !!sta->connected ? 0 : current_time - sta->last_connected;
void *c;
c = blob_nest_start(&buf, 0);
blob_put_int8(&buf, APMSG_STA_CONNECTED, !!sta->connected);
blob_put_int32(&buf, APMSG_STA_SIGNAL, sta->signal);
blob_put_int32(&buf, APMSG_STA_SEEN, seen);
+ blob_put_int32(&buf, APMSG_STA_LAST_CONNECTED, last_connected);
blob_put_int32(&buf, APMSG_STA_TIMEOUT, config.local_sta_timeout - seen);
blob_nest_end(&buf, c);
}
blob_put_int32(&buf, APMSG_NODE_LOAD, node->load);
blob_put_int32(&buf, APMSG_NODE_N_ASSOC, node->n_assoc);
blob_put_int32(&buf, APMSG_NODE_MAX_ASSOC, node->max_assoc);
+ blob_put_int32(&buf, APMSG_NODE_OP_CLASS, node->op_class);
+ blob_put_int32(&buf, APMSG_NODE_CHANNEL, node->channel);
blob_put(&buf, APMSG_NODE_BSSID, node->bssid, sizeof(node->bssid));
if (node->rrm_nr) {
r = blob_nest_start(&buf, APMSG_NODE_RRM_NR);
int timeout = config.remote_node_timeout;
list_for_each_entry_safe(node, tmp, &remote_nodes, list) {
- if (node->check++ > timeout)
+ if (config.local_mode || node->check++ > timeout)
remote_node_free(node);
}
}
usteer_update_time();
uloop_timeout_set(t, config.remote_update_interval);
- if (!avl_is_empty(&local_nodes) || host_info_blob) {
+ if (!config.local_mode &&
+ (!avl_is_empty(&local_nodes) || host_info_blob)) {
c = usteer_update_init();
for_each_local_node(node)
usteer_send_node(node, NULL);
return -1;
}
- if (fread(&local_id, sizeof(local_id), 1, f) < 1)
+ if (fread(&local_id, sizeof(local_id), 1, f) < 1) {
+ fclose(f);
return -1;
+ }
fclose(f);
return 0;