diff --git a/src/include/datastorage.h b/src/include/datastorage.h index 34dd0dd..9b6e995 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -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); diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 52d0381..f13fa9f 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -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; diff --git a/src/test/test_storage.c b/src/test/test_storage.c index 20499f3..cdf7e16 100644 --- a/src/test/test_storage.c +++ b/src/test/test_storage.c @@ -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); } } diff --git a/src/utils/msghandler.c b/src/utils/msghandler.c index fe0280b..608cd2f 100644 --- a/src/utils/msghandler.c +++ b/src/utils/msghandler.c @@ -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); diff --git a/src/utils/ubus.c b/src/utils/ubus.c index 836465e..b1088b2 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -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);