Add a last_connected field to the sta_info struct. This field can be
used to determine, if and when a client was last connected to a given
node. This way, other nodes can determine where a client roamed to or
from.
Signed-off-by: David Bauer <mail@david-bauer.net>
int n_assoc = 0;
int rem;
int n_assoc = 0;
int rem;
+ usteer_update_time();
+
list_for_each_entry(si, &node->sta_info, node_list) {
if (si->connected)
si->connected = STA_DISCONNECTED;
list_for_each_entry(si, &node->sta_info, node_list) {
if (si->connected)
si->connected = STA_DISCONNECTED;
h->update_sta(node, si);
}
usteer_local_node_assoc_update(si, cur);
h->update_sta(node, si);
}
usteer_local_node_assoc_update(si, cur);
- if (si->connected == STA_CONNECTED)
+ if (si->connected == STA_CONNECTED) {
+ si->last_connected = current_time;
}
node->n_assoc = n_assoc;
}
node->n_assoc = n_assoc;
[APMSG_STA_SEEN] = { .type = BLOB_ATTR_INT32 },
[APMSG_STA_TIMEOUT] = { .type = BLOB_ATTR_INT32 },
[APMSG_STA_CONNECTED] = { .type = BLOB_ATTR_INT8 },
[APMSG_STA_SEEN] = { .type = BLOB_ATTR_INT32 },
[APMSG_STA_TIMEOUT] = { .type = BLOB_ATTR_INT32 },
[APMSG_STA_CONNECTED] = { .type = BLOB_ATTR_INT8 },
+ [APMSG_STA_LAST_CONNECTED] = { .type = BLOB_ATTR_INT32 },
};
struct blob_attr *tb[__APMSG_STA_MAX];
};
struct blob_attr *tb[__APMSG_STA_MAX];
!tb[APMSG_STA_SIGNAL] ||
!tb[APMSG_STA_SEEN] ||
!tb[APMSG_STA_TIMEOUT] ||
!tb[APMSG_STA_SIGNAL] ||
!tb[APMSG_STA_SEEN] ||
!tb[APMSG_STA_TIMEOUT] ||
- !tb[APMSG_STA_CONNECTED])
+ !tb[APMSG_STA_CONNECTED] ||
+ !tb[APMSG_STA_LAST_CONNECTED])
return false;
if (blob_len(tb[APMSG_STA_ADDR]) != sizeof(msg->addr))
return false;
if (blob_len(tb[APMSG_STA_ADDR]) != sizeof(msg->addr))
msg->seen = blob_get_int32(tb[APMSG_STA_SEEN]);
msg->timeout = blob_get_int32(tb[APMSG_STA_TIMEOUT]);
msg->connected = blob_get_int8(tb[APMSG_STA_CONNECTED]);
msg->seen = blob_get_int32(tb[APMSG_STA_SEEN]);
msg->timeout = blob_get_int32(tb[APMSG_STA_TIMEOUT]);
msg->connected = blob_get_int8(tb[APMSG_STA_CONNECTED]);
+ msg->last_connected = blob_get_int32(tb[APMSG_STA_LAST_CONNECTED]);
si->connected = msg.connected;
si->signal = msg.signal;
si->seen = current_time - msg.seen;
si->connected = msg.connected;
si->signal = msg.signal;
si->seen = current_time - msg.seen;
+ si->last_connected = current_time - msg.last_connected;
usteer_sta_info_update_timeout(si, msg.timeout);
}
usteer_sta_info_update_timeout(si, msg.timeout);
}
static void usteer_send_sta_info(struct sta_info *sta)
{
int seen = current_time - sta->seen;
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);
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_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_STA_TIMEOUT, config.local_sta_timeout - seen);
blob_nest_end(&buf, c);
}
APMSG_STA_TIMEOUT,
APMSG_STA_SEEN,
APMSG_STA_CONNECTED,
APMSG_STA_TIMEOUT,
APMSG_STA_SEEN,
APMSG_STA_CONNECTED,
+ APMSG_STA_LAST_CONNECTED,
int signal;
int timeout;
int seen;
int signal;
int timeout;
int seen;
};
bool parse_apmsg(struct apmsg *msg, struct blob_attr *data);
};
bool parse_apmsg(struct apmsg *msg, struct blob_attr *data);
struct sta_info_stats stats[__EVENT_TYPE_MAX];
uint64_t created;
uint64_t seen;
struct sta_info_stats stats[__EVENT_TYPE_MAX];
uint64_t created;
uint64_t seen;
+ uint64_t last_connected;
int signal;
enum roam_trigger_state roam_state;
int signal;
enum roam_trigger_state roam_state;