treewide: improve beacon/probe logging

Modifications to BEACON and PROBE handling to improve understanding of
RSSI and RCPI / RSNI values. Also address bugs in frequency / band handling.

[cleanup commit message]
Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
Ian Clowes 2022-04-02 17:30:35 +01:00 committed by Nick Hainke
parent 92eac61d30
commit c212c5469f
5 changed files with 187 additions and 152 deletions

View file

@ -149,23 +149,30 @@ extern struct probe_metric_s dawn_metric;
// ---------------- Structs ----------------
typedef struct probe_entry_s {
// List admin fields
struct probe_entry_s* next_probe;
struct probe_entry_s* next_probe_skip;
time_t rssi_timestamp; // remove_old...entries
time_t rcpi_timestamp; // remove_old...entries
// Connection accept / reject decision fields
int counter; // FIXME: Never gets reset to zero. Rely on deletion to create new for non-802.11k client?
// Client status reporting fields
struct dawn_mac client_addr;
struct dawn_mac bssid_addr;
//uint8_t ssid[SSID_MAX_LEN + 1]; // parse_to_beacon_rep()
struct dawn_mac target_addr; // TODO: Never evaluated?
uint32_t signal; // eval_probe_metric()
uint32_t freq; // eval_probe_metric()
uint8_t ht_capabilities; // eval_probe_metric()
uint8_t vht_capabilities; // eval_probe_metric()
time_t time; // remove_old...entries
int counter; // FIXME: Never gets reset to zero. Rely on deletion to create new for non-802.11k client?
int deny_counter; // TODO: Never used?
uint8_t max_supp_datarate; // TODO: Never used?
uint8_t min_supp_datarate; // TODO: Never used?
uint32_t rcpi;
uint32_t rsni;
// FIXME: Historic fields - consider removing
struct dawn_mac target_addr; // TODO: Never evaluated?
uint8_t max_supp_datarate; // TODO: Never used?
uint8_t min_supp_datarate; // TODO: Never used?
int deny_counter; // TODO: Never used?
} probe_entry;
//struct probe_entry_s {
@ -282,7 +289,7 @@ extern struct client_s *client_set_bc;
extern pthread_mutex_t client_array_mutex;
// ---------------- Functions ----------------
probe_entry *insert_to_probe_array(probe_entry *entry, int is_local, int save_80211k, int is_beacon, time_t expiry);
probe_entry *insert_to_probe_array(probe_entry *entry, int inc_probe_count, int is_beacon, time_t expiry);
int probe_array_delete(struct dawn_mac client_addr, struct dawn_mac bssid_addr);
@ -302,9 +309,7 @@ void print_client_req_entry(int level, client_req_entry *entry);
// ---------------- Functions ----------------
probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rssi, int send_network);
probe_entry* probe_array_update_rcpi_rsni(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rcpi, uint32_t rsni, int send_network);
probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, ap* this_ap, uint32_t rssi, int send_network);
void remove_old_client_entries(time_t current_time, long long int threshold);

View file

@ -209,33 +209,37 @@ int get_band(int freq) {
// TODO: as rest of values look to be static fr any given entry.
int eval_probe_metric(struct probe_entry_s* probe_entry, ap* ap_entry) {
dawnlog_debug_func("Entering...");
dawn_mutex_require(&ap_array_mutex);
dawn_mutex_require(&probe_array_mutex);
int score = 0;
int band, score = 0;
if (probe_entry->signal != 0)
{
dawn_mutex_require(&ap_array_mutex);
dawn_mutex_require(&probe_array_mutex);
// TODO: Should RCPI be used here as well?
band = get_band(probe_entry->freq);
score = dawn_metric.initial_score[band];
score += probe_entry->signal >= dawn_metric.rssi_val[band] ? dawn_metric.rssi[band] : 0;
score += probe_entry->signal <= dawn_metric.low_rssi_val[band] ? dawn_metric.low_rssi[band] : 0;
score += (probe_entry->signal - dawn_metric.rssi_center[band]) * dawn_metric.rssi_weight[band];
// TODO: Should RCPI be used here as well?
int band = get_band(probe_entry->freq);
score = dawn_metric.initial_score[band];
// check if ap entry is available
if (ap_entry != NULL) {
score += probe_entry->ht_capabilities && ap_entry->ht_support ? dawn_metric.ht_support[band] : 0;
score += !probe_entry->ht_capabilities && !ap_entry->ht_support ? dawn_metric.no_ht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring?
score += probe_entry->signal >= dawn_metric.rssi_val[band] ? dawn_metric.rssi[band] : 0;
score += probe_entry->signal <= dawn_metric.low_rssi_val[band] ? dawn_metric.low_rssi[band] : 0;
score += (probe_entry->signal - dawn_metric.rssi_center[band]) * dawn_metric.rssi_weight[band];
// performance anomaly?
if (network_config.bandwidth >= 1000 || network_config.bandwidth == -1) {
score += probe_entry->vht_capabilities && ap_entry->vht_support ? dawn_metric.vht_support[band] : 0;
// check if ap entry is available
if (ap_entry != NULL) {
score += probe_entry->ht_capabilities && ap_entry->ht_support ? dawn_metric.ht_support[band] : 0;
score += !probe_entry->ht_capabilities && !ap_entry->ht_support ? dawn_metric.no_ht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring?
// performance anomaly?
if (network_config.bandwidth >= 1000 || network_config.bandwidth == -1) {
score += probe_entry->vht_capabilities && ap_entry->vht_support ? dawn_metric.vht_support[band] : 0;
}
score += !probe_entry->vht_capabilities && !ap_entry->vht_support ? dawn_metric.no_vht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring?
score += ap_entry->channel_utilization <= dawn_metric.chan_util_val[band] ? dawn_metric.chan_util[band] : 0;
score += ap_entry->channel_utilization > dawn_metric.max_chan_util_val[band] ? dawn_metric.max_chan_util[band] : 0;
score += ap_entry->ap_weight;
}
score += !probe_entry->vht_capabilities && !ap_entry->vht_support ? dawn_metric.no_vht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring?
score += ap_entry->channel_utilization <= dawn_metric.chan_util_val[band] ? dawn_metric.chan_util[band] : 0;
score += ap_entry->channel_utilization > dawn_metric.max_chan_util_val[band] ? dawn_metric.max_chan_util[band] : 0;
score += ap_entry->ap_weight;
}
// TODO: This magic value never checked by caller. What does it achieve?
@ -653,6 +657,10 @@ void update_iw_info(struct dawn_mac bssid_mac) {
dawn_mutex_lock(&client_array_mutex);
dawn_mutex_lock(&probe_array_mutex);
dawn_mutex_lock(&ap_array_mutex);
dawn_mutex_require(&ap_array_mutex);
ap* this_ap = ap_array_get_ap(bssid_mac);
dawnlog_trace("IW info update for AP " MACSTR "\n", MAC2STR(bssid_mac.u8));
@ -665,7 +673,7 @@ void update_iw_info(struct dawn_mac bssid_mac) {
iee80211_calculate_expected_throughput_mbit(get_expected_throughput_iwinfo(j->client_addr)));
if (rssi != INT_MIN) {
if (probe_array_update_rssi(j->client_addr, j->bssid_addr, rssi, true) == NULL) {
if (probe_array_update_rssi(j->client_addr, this_ap, rssi, true) == NULL) {
dawnlog_info("Failed to update rssi!\n");
}
else {
@ -676,6 +684,7 @@ void update_iw_info(struct dawn_mac bssid_mac) {
dawnlog_trace("---------------------------\n");
dawn_mutex_unlock(&ap_array_mutex);
dawn_mutex_unlock(&probe_array_mutex);
dawn_mutex_unlock(&client_array_mutex);
}
@ -820,7 +829,7 @@ int probe_array_set_all_probe_count(struct dawn_mac client_addr, uint32_t probe_
return updated;
}
probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rssi, int send_network)
probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, ap* connected_ap, uint32_t rssi, int send_network)
{
dawnlog_debug_func("Entering...");
@ -831,8 +840,9 @@ probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_ma
if (probe_req_new) {
// Fields we will update
probe_req_new->client_addr = client_addr;
probe_req_new->bssid_addr = bssid_addr;
probe_req_new->bssid_addr = connected_ap->bssid_addr;
probe_req_new->signal = rssi;
probe_req_new->freq = connected_ap->freq;
// Other fields in case entry is new
probe_req_new->ht_capabilities = false;
@ -840,11 +850,7 @@ probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_ma
probe_req_new->rcpi = -1;
probe_req_new->rsni = -1;
//FIXME: Should we put the linked list defaults in the insert function?
probe_req_new->next_probe = NULL;
probe_req_new->next_probe_skip = NULL;
probe_req_updated = insert_to_probe_array(probe_req_new, false, false, false, time(0));
probe_req_updated = insert_to_probe_array(probe_req_new, false, false, time(0));
if (probe_req_new != probe_req_updated)
{
dawnlog_info("RSSI PROBE used to update client / BSSID = " MACSTR " / " MACSTR " \n", MAC2STR(probe_req_updated->client_addr.u8), MAC2STR(probe_req_updated->bssid_addr.u8));
@ -864,28 +870,6 @@ probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_ma
return probe_req_updated;
}
probe_entry* probe_array_update_rcpi_rsni(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rcpi, uint32_t rsni, int send_network)
{
dawnlog_debug_func("Entering...");
dawn_mutex_require(&probe_array_mutex);
probe_entry* entry = probe_array_get_entry(client_addr, bssid_addr);
if (entry) {
// FIXME: Do we need the -1 tests here?
if (rcpi != -1)
entry->rcpi = rcpi;
if (rsni != -1)
entry->rsni = rsni;
if (send_network)
ubus_send_probe_via_network(entry, true);
}
return entry;
}
probe_entry *probe_array_get_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac) {
dawnlog_debug_func("Entering...");
@ -908,7 +892,7 @@ void print_probe_array() {
}
}
probe_entry* insert_to_probe_array(probe_entry* entry, int is_local, int save_80211k, int is_beacon, time_t expiry) {
probe_entry* insert_to_probe_array(probe_entry* entry, int inc_probe_count, int is_beacon, time_t expiry) {
dawnlog_debug_func("Entering...");
dawn_mutex_require(&probe_array_mutex);
@ -948,12 +932,17 @@ probe_entry* insert_to_probe_array(probe_entry* entry, int is_local, int save_80
if (*node_ref && cmp == 0) {
dawnlog_debug("Updating...\n");
if (entry->freq)
(*node_ref)->freq = entry->freq;
if (!is_beacon)
{
if (is_local)
if (inc_probe_count)
(*node_ref)->counter++;
// Beacon reports don't have these fields, so only update them from probes
entry->rssi_timestamp = expiry;
// BEACON reports don't have these fields, so only update them from PROBE
(*node_ref)->signal = entry->signal;
// Some "synthetic" PROBE entries have FALSE for these which would overwrite genuine values
@ -967,25 +956,31 @@ probe_entry* insert_to_probe_array(probe_entry* entry, int is_local, int save_80
{
// FIXME: Equivalent to inserting BEACON based entry
(*node_ref)->counter = dawn_metric.min_probe_count;
entry->rcpi_timestamp = expiry;
// PROBE reports don't have these fields, so only update them from BEACOM
if (entry->rcpi != -1)
(*node_ref)->rcpi = entry->rcpi;
if (entry->rsni != -1)
(*node_ref)->rsni = entry->rsni;
}
if (save_80211k && entry->rcpi != -1)
(*node_ref)->rcpi = entry->rcpi;
if (save_80211k && entry->rsni != -1)
(*node_ref)->rsni = entry->rsni;
entry = *node_ref;
}
else
{
dawnlog_debug("Adding...\n");
if (is_local && !is_beacon)
if (inc_probe_count && !is_beacon)
entry->counter = 1;
else
entry->counter = 0;
entry->rssi_timestamp = expiry;
entry->rcpi_timestamp = expiry;
entry->next_probe = *node_ref;
*node_ref = entry;
@ -1004,8 +999,6 @@ probe_entry* insert_to_probe_array(probe_entry* entry, int is_local, int save_80
}
}
entry->time = expiry;
return entry; // return pointer to what we used, which may not be what was passed in
}
@ -1176,8 +1169,24 @@ void remove_old_probe_entries(time_t current_time, long long int threshold) {
dawn_mutex_lock(&client_array_mutex);
while (*i != NULL ) {
int rssi_expired = 0;
int rcpi_expired = 0;
// FIXME: Why do we not delete the old probe just because it is a client? Maybe because legacy devices are slow to send another?
if (((*i)->time < current_time - threshold) && !client_array_get_client_for_bssid((*i)->bssid_addr, (*i)->client_addr)) {
if (((*i)->rssi_timestamp < current_time - threshold) && !client_array_get_client_for_bssid((*i)->bssid_addr, (*i)->client_addr))
{
(*i)->signal = 0;
rssi_expired = 1;
}
if (((*i)->rcpi_timestamp < current_time - threshold))
{
(*i)->rcpi = -1;
(*i)->rsni = -1;
rcpi_expired = 1;
}
if (rssi_expired && rcpi_expired) {
probe_entry* victim = *i;
*i = victim->next_probe;

View file

@ -255,14 +255,14 @@ static int array_auto_helper(int action, int i0, int i1)
probe0->client_addr = this_mac;
probe0->bssid_addr = this_mac;
insert_to_probe_array(probe0, true, true, true, 0); // TODO: Check bool flags
insert_to_probe_array(probe0, true, true, 0); // TODO: Check bool flags
}
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
probe0 = dawn_malloc(sizeof(probe_entry));
set_random_mac(probe0->client_addr.u8);
set_random_mac(probe0->bssid_addr.u8);
insert_to_probe_array(probe0, true, true, true, faketime);
insert_to_probe_array(probe0, true, true, faketime);
remove_old_probe_entries(faketime, 10);
time_moves_on();
}
@ -826,7 +826,8 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
else if (!strncmp(fn, "freq=", 5)) load_u32(&pr0->freq, fn + 5);
else if (!strncmp(fn, "ht_cap=", 7)) load_u8(&pr0->ht_capabilities, fn + 7);
else if (!strncmp(fn, "vht_cap=", 8)) load_u8(&pr0->vht_capabilities, fn + 8);
else if (!strncmp(fn, "time=", 5)) load_time(&pr0->time, fn + 5);
else if (!strncmp(fn, "time=", 5)) load_time(&pr0->rssi_timestamp, fn + 5);
else if (!strncmp(fn, "time2=", 5)) load_time(&pr0->rcpi_timestamp, fn + 5);
else if (!strncmp(fn, "counter=", 8)) load_int(&pr0->counter, fn + 8);
else if (!strncmp(fn, "deny=", 5)) load_int(&pr0->deny_counter, fn + 5);
else if (!strncmp(fn, "max_rate=", 9)) load_u8(&pr0->max_supp_datarate, fn + 9);
@ -867,7 +868,8 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
pr0->freq = 0;
pr0->ht_capabilities = 0;
pr0->vht_capabilities = 0;
pr0->time = faketime;
pr0->rssi_timestamp = faketime;
pr0->rcpi_timestamp = 0;
pr0->counter = 0;
pr0->deny_counter = 0;
pr0->max_supp_datarate = 0;
@ -875,7 +877,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
pr0->rcpi = 0;
pr0->rsni = 0;
insert_to_probe_array(pr0, true, true, true, pr0->time);
insert_to_probe_array(pr0, true, true, pr0->rssi_timestamp);
}
}

View file

@ -184,10 +184,15 @@ probe_entry *parse_to_probe_req(struct blob_attr* msg) {
if (tb[PROB_SIGNAL]) {
prob_req->signal = blobmsg_get_u32(tb[PROB_SIGNAL]);
}
else
prob_req->signal = 0;
if (tb[PROB_FREQ]) {
prob_req->freq = blobmsg_get_u32(tb[PROB_FREQ]);
}
else {
prob_req->freq = 0;
}
if (tb[PROB_RCPI]) {
prob_req->rcpi = blobmsg_get_u32(tb[PROB_RCPI]);
@ -301,7 +306,7 @@ int handle_network_msg(char* msg) {
dawn_mutex_lock(&probe_array_mutex);
dawn_mutex_require(&probe_array_mutex);
if (entry != insert_to_probe_array(entry, false, false, false, time(0))) // use 802.11k values
if (entry != insert_to_probe_array(entry, false, false, time(0)))
{
// insert found an existing entry, rather than linking in our new one
dawnlog_info("Remote PROBE updated client / BSSID = " MACSTR " / " MACSTR " \n",
@ -340,30 +345,6 @@ int handle_network_msg(char* msg) {
dawnlog_debug("HANDLING UCI!\n");
handle_uci_config(data_buf.head);
}
else if (strncmp(method, "beacon-report", 12) == 0) {
probe_entry* entry = parse_to_probe_req(data_buf.head);
if (entry != NULL) {
dawn_mutex_lock(&probe_array_mutex);
dawn_mutex_require(&probe_array_mutex);
if (entry != insert_to_probe_array(entry, false, true, true, time(0))) // use 802.11k values
{
// insert found an existing entry, rather than linking in our new one
dawnlog_info("Remote BEACON updated client / BSSID = " MACSTR " / " MACSTR " \n",
MAC2STR(entry->client_addr.u8), MAC2STR(entry->bssid_addr.u8));
dawn_free(entry);
entry = NULL;
}
else
{
dawnlog_info("Remote BEACON is for new client / BSSID = " MACSTR " / " MACSTR " \n",
MAC2STR(entry->client_addr.u8), MAC2STR(entry->bssid_addr.u8));
}
dawn_mutex_unlock(&probe_array_mutex);
}
}
else
{
dawnlog_warning("No method found for: %s\n", method);

View file

@ -137,8 +137,8 @@ enum {
static const struct blobmsg_policy beacon_rep_policy[__BEACON_REP_MAX] = {
[BEACON_REP_ADDR] = {.name = "address", .type = BLOBMSG_TYPE_STRING},
[BEACON_REP_OP_CLASS] = {.name = "op-class", .type = BLOBMSG_TYPE_INT16},
[BEACON_REP_CHANNEL] = {.name = "channel", .type = BLOBMSG_TYPE_INT64},
[BEACON_REP_START_TIME] = {.name = "start-time", .type = BLOBMSG_TYPE_INT32},
[BEACON_REP_CHANNEL] = {.name = "channel", .type = BLOBMSG_TYPE_INT16},
[BEACON_REP_START_TIME] = {.name = "start-time", .type = BLOBMSG_TYPE_INT64},
[BEACON_REP_DURATION] = {.name = "duration", .type = BLOBMSG_TYPE_INT16},
[BEACON_REP_REPORT_INFO] = {.name = "report-info", .type = BLOBMSG_TYPE_INT16},
[BEACON_REP_RCPI] = {.name = "rcpi", .type = BLOBMSG_TYPE_INT16},
@ -267,6 +267,59 @@ int parse_to_client_req(struct blob_attr *msg, client_req_entry *client_req) {
return 0;
}
// FIXME: Hacky attempt to fix missing freq field in BEACON frames. Need to untangle the whole band thing...
static int get_freq(int band) {
dawnlog_debug_func("Entering...");
static const int band_freq_map[] = {
1, 2412,
2, 2417,
3, 2422,
4, 2427,
5, 2432,
6, 2437,
7, 2442,
8, 2447,
9, 2452,
10, 2457,
11, 2462,
12, 2467,
13, 2472,
14, 2484,
36, 5180,
40, 5200,
44, 5220,
48, 5240,
52, 5260,
56, 5280,
60, 5300,
64, 5320,
100, 5500,
104, 5520,
108, 5540,
112, 5560,
116, 5580,
120, 5600,
124, 5620,
128, 5640,
132, 5660,
136, 5680,
140, 5700,
149, 5745,
153, 5765,
157, 5785,
161, 5805,
165, 5825
};
for (int pos = 0; pos < (sizeof(band_freq_map) / (2 * sizeof(int))); pos += 2)
{
if (band <= band_freq_map[pos])
return band_freq_map[pos + 1];
}
return 0;
}
static probe_entry* parse_to_beacon_rep(struct blob_attr *msg) {
probe_entry* beacon_rep = NULL;
struct blob_attr *tb[__BEACON_REP_MAX];
@ -282,46 +335,24 @@ static probe_entry* parse_to_beacon_rep(struct blob_attr *msg) {
hwaddr_aton(blobmsg_data(tb[BEACON_REP_BSSID]), msg_bssid.u8) ||
hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), msg_client.u8))
{
dawnlog_warning("Parse of beacon report failed!\n");
dawnlog_warning("Parse of BEACON failed!\n");
}
else
{
dawn_mutex_lock(&ap_array_mutex);
dawn_mutex_require(&ap_array_mutex);
ap* ap_entry_rep = ap_array_get_ap(msg_bssid);
// no client from network!!
if (!ap_entry_rep) {
dawnlog_warning("No AP for beacon report entry!\n");
beacon_rep = dawn_malloc(sizeof(probe_entry));
if (beacon_rep == NULL)
{
dawnlog_error("dawn_malloc of BEACON failed!\n");
}
else
{
beacon_rep = dawn_malloc(sizeof(probe_entry));
if (beacon_rep == NULL)
{
dawnlog_error("dawn_malloc of beacon report failed!\n");
}
else
{
beacon_rep->next_probe = NULL;
beacon_rep->bssid_addr = msg_bssid;
beacon_rep->client_addr = msg_client;
beacon_rep->counter = dawn_metric.min_probe_count; // TODO: Why is this? To allow a 802.11k client to meet proe count check immediately?
hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), beacon_rep->target_addr.u8); // TODO: What is this for?
beacon_rep->freq = ap_entry_rep->freq;
beacon_rep->rcpi = blobmsg_get_u16(tb[BEACON_REP_RCPI]);
beacon_rep->rsni = blobmsg_get_u16(tb[BEACON_REP_RSNI]);
// These fields, can't be set from a BEACON REPORT, so we ignore them later if updating an existing PROBE
// TODO: See if hostapd can send optional elements which might allow these to be set
beacon_rep->signal = 0;
beacon_rep->ht_capabilities = false; // that is very problematic!!!
beacon_rep->vht_capabilities = false; // that is very problematic!!!
}
beacon_rep->bssid_addr = msg_bssid;
beacon_rep->client_addr = msg_client;
hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), beacon_rep->target_addr.u8); // TODO: What is this for?
beacon_rep->rcpi = blobmsg_get_u16(tb[BEACON_REP_RCPI]);
beacon_rep->rsni = blobmsg_get_u16(tb[BEACON_REP_RSNI]);
beacon_rep->freq = get_freq(blobmsg_get_u16(tb[BEACON_REP_CHANNEL]));
}
dawn_mutex_unlock(&ap_array_mutex);
}
return beacon_rep;
@ -504,7 +535,7 @@ static int handle_probe_req(struct blob_attr* msg) {
dawn_mutex_lock(&probe_array_mutex);
dawn_mutex_require(&probe_array_mutex);
probe_entry* probe_req_updated = insert_to_probe_array(probe_req_new, true, false, false, time(0));
probe_entry* probe_req_updated = insert_to_probe_array(probe_req_new, true, false, time(0));
// If insert finds an existing entry, rather than linking in our new one,
// send new probe req because we want to stay synced.
// If not, probe_req and probe_req_updated should be equivalent
@ -578,18 +609,28 @@ static int handle_beacon_rep(struct blob_attr *msg) {
{
if (mac_is_null(entry->bssid_addr.u8))
{
dawnlog_warning("Received NULL MAC! Client is strange!\n");
dawnlog_info("Received NULL MAC! Client is strange!\n");
dawn_free(entry);
}
else
{
// Update RxxI of current entry if it exists
// BEACON will never set RSSI, but may have RCPI and RSNI
// These fields, can't be set from a BEACON REPORT, so we ignore them later if updating an existing PROBE
// TODO: See if hostapd can send optional elements which might allow these to be set
entry->signal = 0;
entry->ht_capabilities = false; // that is very problematic!!!
entry->vht_capabilities = false; // that is very problematic!!!
// FIXME: Why is this? To allow a 802.11k client to meet proe count check immediately?
entry->counter = dawn_metric.min_probe_count;
dawn_mutex_lock(&probe_array_mutex);
// Update RxxI of current entry if it exists
dawn_mutex_require(&probe_array_mutex);
probe_entry* entry_updated = probe_array_update_rcpi_rsni(entry->client_addr, entry->bssid_addr, entry->rcpi, entry->rsni, true);
probe_entry* entry_updated = insert_to_probe_array(entry, true, true, time(0));
if (entry_updated)
if (entry_updated != entry)
{
dawnlog_info("Local BEACON used to update RCPI and RSNI for client / BSSID = " MACSTR " / " MACSTR " \n", MAC2STR(entry->client_addr.u8), MAC2STR(entry->bssid_addr.u8));
dawn_free(entry);
@ -598,15 +639,12 @@ static int handle_beacon_rep(struct blob_attr *msg) {
{
dawnlog_info("Local BEACON is for new client / BSSID = " MACSTR " / " MACSTR " \n", MAC2STR(entry->client_addr.u8), MAC2STR(entry->bssid_addr.u8));
// BEACON will never set RSSI, but may have RCPI and RSNI
dawn_mutex_require(&probe_array_mutex);
entry = insert_to_probe_array(entry, true, true, true, time(0));
ubus_send_probe_via_network(entry, true);
ret = 0;
}
dawn_mutex_unlock(&probe_array_mutex);
ret = 0;
}
}
@ -1342,11 +1380,11 @@ int ubus_send_probe_via_network(struct probe_entry_s *probe_entry, bool is_beaco
blobmsg_add_macaddr(&b, "bssid", probe_entry->bssid_addr);
blobmsg_add_macaddr(&b, "address", probe_entry->client_addr);
blobmsg_add_macaddr(&b, "target", probe_entry->target_addr);
blobmsg_add_u32(&b, "freq", probe_entry->freq);
if (!is_beacon)
{
blobmsg_add_u32(&b, "signal", probe_entry->signal);
blobmsg_add_u32(&b, "freq", probe_entry->freq);
blobmsg_add_u32(&b, "ht_capabilities", probe_entry->ht_capabilities);
blobmsg_add_u32(&b, "vht_capabilities", probe_entry->vht_capabilities);