utils/storage: cleanup

- New skipping linked list structure - possible bug in previous version
- Adjust some function names to better reflect what actually happens
- Remove redundant configurable sort elements
- Remove probe structure SSID field which is not set via BEACON, so is unreliable
- Adjust way the different fields from BEACON and PROBE reports are handled / merged
- Made client / BSSID paramater order consistent for probe / beacon functions to help avoid cut/ paste bugs
- Add RRM capability, RCPI and RSNI to client in hearing map (which is a summary of probe / beacon entries)

[cleanup commit message]
Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
Ian Clowes 2022-01-31 10:53:07 +00:00 committed by Nick Hainke
parent 6bf3cd7754
commit 5d7f99dded
9 changed files with 369 additions and 420 deletions

View file

@ -153,7 +153,7 @@ typedef struct probe_entry_s {
struct probe_entry_s* next_probe_skip; struct probe_entry_s* next_probe_skip;
struct dawn_mac client_addr; struct dawn_mac client_addr;
struct dawn_mac bssid_addr; struct dawn_mac bssid_addr;
uint8_t ssid[SSID_MAX_LEN + 1]; // parse_to_beacon_rep() //uint8_t ssid[SSID_MAX_LEN + 1]; // parse_to_beacon_rep()
struct dawn_mac target_addr; // TODO: Never evaluated? struct dawn_mac target_addr; // TODO: Never evaluated?
uint32_t signal; // eval_probe_metric() uint32_t signal; // eval_probe_metric()
uint32_t freq; // eval_probe_metric() uint32_t freq; // eval_probe_metric()
@ -204,8 +204,16 @@ typedef struct hostapd_notify_entry_s {
#define NR_PHY 24 #define NR_PHY 24
// ---------------- Global variables ---------------- // ---------------- Global variables ----------------
struct probe_head_s {
int node_count;
int skip_count;
int skip_ratio;
extern struct probe_entry_s *probe_set; struct probe_entry_s* first_probe;
struct probe_entry_s* first_probe_skip;
};
extern struct probe_head_s probe_set;
extern pthread_mutex_t probe_array_mutex; extern pthread_mutex_t probe_array_mutex;
/* AP, Client */ /* AP, Client */
@ -283,11 +291,13 @@ extern struct client_s *client_set_bc;
extern pthread_mutex_t client_array_mutex; extern pthread_mutex_t client_array_mutex;
// ---------------- Functions ---------------- // ---------------- Functions ----------------
probe_entry *insert_to_array(probe_entry *entry, int inc_counter, int save_80211k, int is_beacon, time_t expiry); probe_entry *insert_to_probe_array(probe_entry *entry, int is_local, int save_80211k, int is_beacon, time_t expiry);
int probe_array_delete(probe_entry *entry); int probe_array_delete(struct dawn_mac client_addr, struct dawn_mac bssid_addr);
probe_entry *probe_array_get_entry(struct dawn_mac bssid_addr, struct dawn_mac client_addr); probe_entry* probe_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, int do_bssid);
probe_entry *probe_array_get_entry(struct dawn_mac client_addr, struct dawn_mac bssid_addr);
void remove_old_probe_entries(time_t current_time, long long int threshold); void remove_old_probe_entries(time_t current_time, long long int threshold);
@ -301,9 +311,9 @@ void print_client_req_entry(int level, client_req_entry *entry);
// ---------------- Functions ---------------- // ---------------- Functions ----------------
int probe_array_update_rssi(struct dawn_mac bssid_addr, struct dawn_mac client_addr, uint32_t rssi, int send_network); probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rssi, int send_network);
int probe_array_update_rcpi_rsni(struct dawn_mac bssid_addr, struct dawn_mac client_addr, uint32_t rcpi, uint32_t rsni, 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);
void remove_old_client_entries(time_t current_time, long long int threshold); void remove_old_client_entries(time_t current_time, long long int threshold);
@ -313,6 +323,8 @@ int kick_clients(struct dawn_mac bssid, uint32_t id);
void update_iw_info(struct dawn_mac bssid); void update_iw_info(struct dawn_mac bssid);
client** client_find_first_bc_entry(struct dawn_mac bssid_mac, struct dawn_mac client_mac, int do_client);
void client_array_insert(client *entry, client ** insert_pos); void client_array_insert(client *entry, client ** insert_pos);
client *client_array_get_client(const struct dawn_mac client_addr); client *client_array_get_client(const struct dawn_mac client_addr);
@ -336,14 +348,9 @@ ap *ap_array_get_ap(struct dawn_mac bssid_mac);
int probe_array_set_all_probe_count(struct dawn_mac client_addr, uint32_t probe_count); int probe_array_set_all_probe_count(struct dawn_mac client_addr, uint32_t probe_count);
//int ap_get_collision_count(int col_domain); //int ap_get_collision_count(int col_domain);
void send_beacon_requests(ap *a, int id);
void send_beacon_reports(ap *a, int id);
/* Utils */ /* Utils */
// deprecate use of this - it makes things slow
#define SORT_LENGTH 5
extern char sort_string[];
struct kicking_nr { struct kicking_nr {
char nr[NEIGHBOR_REPORT_LEN]; char nr[NEIGHBOR_REPORT_LEN];
int score; int score;

View file

@ -46,12 +46,6 @@ struct network_config_s uci_get_dawn_network();
*/ */
bool uci_get_dawn_hostapd_dir(); bool uci_get_dawn_hostapd_dir();
/**
* Function that returns the sort order.
* @return the sort order.
*/
bool uci_get_dawn_sort_order();
int uci_set_network(char* uci_cmd); int uci_set_network(char* uci_cmd);
/** /**

View file

@ -60,7 +60,7 @@ void del_client_all_interfaces(const struct dawn_mac client_addr, uint32_t reaso
*/ */
void update_hostapd_sockets(struct uloop_timeout *t); void update_hostapd_sockets(struct uloop_timeout *t);
void ubus_send_beacon_report(client *c, ap *a, int id); void ubus_send_beacon_request(client *c, ap *a, int id);
void uloop_add_data_cbs(); void uloop_add_data_cbs();

View file

@ -114,7 +114,6 @@ int main(int argc, char **argv) {
timeout_config = time_config; // TODO: Refactor... timeout_config = time_config; // TODO: Refactor...
uci_get_dawn_hostapd_dir(); uci_get_dawn_hostapd_dir();
uci_get_dawn_sort_order();
init_mutex(); init_mutex();

View file

@ -19,8 +19,6 @@ struct local_config_s local_config;
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
static int probe_compare(probe_entry *probe1, probe_entry *probe2);
static int is_connected(struct dawn_mac bssid_mac, struct dawn_mac client_mac); static int is_connected(struct dawn_mac bssid_mac, struct dawn_mac client_mac);
static int compare_station_count(ap* ap_entry_own, ap* ap_entry_to_compare, struct dawn_mac client_addr); static int compare_station_count(ap* ap_entry_own, ap* ap_entry_to_compare, struct dawn_mac client_addr);
@ -40,13 +38,8 @@ const int max_band_freq[__DAWN_BAND_MAX] = {
5925 // This may cause trouble because there's overlap between bands in different countries 5925 // This may cause trouble because there's overlap between bands in different countries
}; };
// Ratio of skiping entries to all entries. // FIXME: Using ratio of 4 to exercise skip handling in small network. Set to 32, 64 or 128 for real use on larger network.
// Approx sqrt() of large data set, and power of 2 for efficient division when adding entries. struct probe_head_s probe_set = { 0, 0, 4, NULL, NULL };
#define DAWN_PROBE_SKIP_RATIO 128
static struct probe_entry_s* probe_skip_set = NULL;
static uint32_t probe_skip_entry_last = 0;
struct probe_entry_s* probe_set = NULL;
static uint32_t probe_entry_last = 0;
pthread_mutex_t probe_array_mutex; pthread_mutex_t probe_array_mutex;
struct ap_s *ap_set = NULL; struct ap_s *ap_set = NULL;
@ -65,9 +58,6 @@ pthread_mutex_t client_array_mutex;
struct mac_entry_s* mac_set = NULL; struct mac_entry_s* mac_set = NULL;
int mac_set_last = 0; int mac_set_last = 0;
// TODO: No longer used in code: retained to not break message xfer, etc
char sort_string[SORT_LENGTH];
/* /*
** The ..._find_first() functions perform an efficient search of the core storage linked lists. ** The ..._find_first() functions perform an efficient search of the core storage linked lists.
** "Skipping" linear searches and binary searches are used depending on anticipated array size. ** "Skipping" linear searches and binary searches are used depending on anticipated array size.
@ -81,83 +71,50 @@ char sort_string[SORT_LENGTH];
** then the target element does not exist, but can be inserted by using the returned reference. ** then the target element does not exist, but can be inserted by using the returned reference.
*/ */
static struct probe_entry_s** probe_skip_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, bool do_bssid) // Probe entries are ordered by client MAC and BSSID so that all APs for a client appear in a block
probe_entry* probe_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, int do_bssid)
{ {
int lo = 0;
struct probe_entry_s** lo_ptr = &probe_skip_set;
int hi = probe_skip_entry_last;
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
while (lo < hi) { struct probe_entry_s* curr_node = probe_set.first_probe;
struct probe_entry_s** i = lo_ptr; struct probe_entry_s* curr_skip = probe_set.first_probe_skip;
int scan_pos = lo;
// m is next test position of binary search int this_cmp = 0;
int m = (lo + hi) / 2; while (curr_skip != NULL) {
this_cmp = mac_compare_bb(curr_skip->client_addr, client_mac);
// find entry with ordinal position m
while (scan_pos++ < m)
{
i = &((*i)->next_probe_skip);
}
int this_cmp = mac_compare_bb((*i)->client_addr, client_mac);
if (this_cmp == 0 && do_bssid) if (this_cmp == 0 && do_bssid)
this_cmp = mac_compare_bb((*i)->bssid_addr, bssid_mac); this_cmp = mac_compare_bb(curr_skip->bssid_addr, bssid_mac);
if (this_cmp < 0) if (this_cmp >= 0) {
{
lo = m + 1;
lo_ptr = &((*i)->next_probe_skip);
}
else
{
hi = m;
}
}
return lo_ptr;
}
static probe_entry** probe_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, bool do_bssid)
{
probe_entry** lo_skip_ptr = &probe_skip_set;
probe_entry** lo_ptr = &probe_set;
dawnlog_debug_func("Entering...");
while ((*lo_skip_ptr != NULL))
{
int this_cmp = mac_compare_bb(((*lo_skip_ptr))->client_addr, client_mac);
if (this_cmp == 0 && do_bssid)
this_cmp = mac_compare_bb(((*lo_skip_ptr))->bssid_addr, bssid_mac);
if (this_cmp >= 0)
break; break;
}
lo_ptr = &((*lo_skip_ptr)->next_probe); else {
lo_skip_ptr = &((*lo_skip_ptr)->next_probe_skip); curr_node = curr_skip;
curr_skip = curr_skip->next_probe_skip;
}
} }
while ((*lo_ptr != NULL)) while (curr_node != NULL) {
{ this_cmp = mac_compare_bb(curr_node->client_addr, client_mac);
int this_cmp = mac_compare_bb((*lo_ptr)->client_addr, client_mac);
if (this_cmp == 0 && do_bssid) if (this_cmp == 0 && do_bssid)
this_cmp = mac_compare_bb((*lo_ptr)->bssid_addr, bssid_mac); this_cmp = mac_compare_bb(curr_node->bssid_addr, bssid_mac);
if (this_cmp >= 0) if (this_cmp >= 0) {
break; break;
}
lo_ptr = &((*lo_ptr)->next_probe); else {
curr_node = curr_node->next_probe;
}
} }
return lo_ptr; // Search including BSSID means that an exact match is required
} if (do_bssid && curr_node && this_cmp != 0)
curr_node = NULL;
return curr_node;
}
// Manage a list of client entries sorted by BSSID and client MAC // Manage a list of client entries sorted by BSSID and client MAC
static struct client_s** client_skip_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, bool do_bssid) static struct client_s** client_skip_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, bool do_bssid)
{ {
@ -199,7 +156,7 @@ static struct client_s** client_skip_array_find_first_entry(struct dawn_mac clie
return lo_ptr; return lo_ptr;
} }
static client** client_find_first_bc_entry(struct dawn_mac bssid_mac, struct dawn_mac client_mac, bool do_client) client** client_find_first_bc_entry(struct dawn_mac bssid_mac, struct dawn_mac client_mac, int do_client)
{ {
client ** lo_skip_ptr = &client_skip_set; client ** lo_skip_ptr = &client_skip_set;
client ** lo_ptr = &client_set_bc; client ** lo_ptr = &client_set_bc;
@ -290,7 +247,7 @@ struct mac_entry_s* mac_find_entry(struct dawn_mac mac)
return ret; return ret;
} }
void send_beacon_reports(ap *a, int id) { void send_beacon_requests(ap *a, int id) {
pthread_mutex_lock(&client_array_mutex); pthread_mutex_lock(&client_array_mutex);
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
@ -308,7 +265,7 @@ void send_beacon_reports(ap *a, int id) {
!!(i->rrm_enabled_capa & WLAN_RRM_CAPS_BEACON_REPORT_TABLE)); !!(i->rrm_enabled_capa & WLAN_RRM_CAPS_BEACON_REPORT_TABLE));
if (i->rrm_enabled_capa & dawn_metric.rrm_mode_mask) if (i->rrm_enabled_capa & dawn_metric.rrm_mode_mask)
ubus_send_beacon_report(i, a, id); ubus_send_beacon_request(i, a, id);
i = i->next_entry_bc; i = i->next_entry_bc;
} }
@ -464,11 +421,9 @@ int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicki
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
// This remains set to the current AP of client for rest of function // This remains set to the current AP of client for rest of function
probe_entry* own_probe = *probe_array_find_first_entry(client_mac, kicking_ap->bssid_addr, true); probe_entry* own_probe = probe_array_get_entry(client_mac, kicking_ap->bssid_addr);
int own_score = -1; int own_score = -1;
if (own_probe != NULL if (own_probe != NULL) {
&& mac_is_equal_bb(own_probe->client_addr, client_mac)
&& mac_is_equal_bb(own_probe->bssid_addr, kicking_ap->bssid_addr)) {
own_score = eval_probe_metric(own_probe, kicking_ap); //TODO: Should the -2 return be handled? own_score = eval_probe_metric(own_probe, kicking_ap); //TODO: Should the -2 return be handled?
dawnlog_trace("Current AP score = %d for:\n", own_score); dawnlog_trace("Current AP score = %d for:\n", own_score);
print_probe_entry(DAWNLOG_TRACE, own_probe); print_probe_entry(DAWNLOG_TRACE, own_probe);
@ -482,8 +437,8 @@ int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicki
int max_score = own_score; int max_score = own_score;
int kick = 0; int kick = 0;
int ap_count = 0; int ap_count = 0;
// Now go through all AP entries for this client looking for better score // Now go through all probe entries for this client looking for better score
probe_entry* i = *probe_array_find_first_entry(client_mac, dawn_mac_null, false); probe_entry* i = probe_array_find_first_entry(client_mac, dawn_mac_null, false);
while (i != NULL && mac_is_equal_bb(i->client_addr, client_mac)) { while (i != NULL && mac_is_equal_bb(i->client_addr, client_mac)) {
if (i == own_probe) { if (i == own_probe) {
@ -720,8 +675,8 @@ void update_iw_info(struct dawn_mac bssid_mac) {
iee80211_calculate_expected_throughput_mbit(get_expected_throughput_iwinfo(j->client_addr))); iee80211_calculate_expected_throughput_mbit(get_expected_throughput_iwinfo(j->client_addr)));
if (rssi != INT_MIN) { if (rssi != INT_MIN) {
if (!probe_array_update_rssi(j->bssid_addr, j->client_addr, rssi, true)) { if (!probe_array_update_rssi(j->client_addr, j->bssid_addr, rssi, true)) {
dawnlog_warning("Failed to update rssi!\n"); dawnlog_info("Failed to update rssi!\n");
} }
else { else {
dawnlog_trace("Updated rssi: %d\n", rssi); dawnlog_trace("Updated rssi: %d\n", rssi);
@ -891,71 +846,56 @@ client *client_array_delete(client *entry, int unlink_only) {
return ret; return ret;
} }
static __inline__ int probe_compare(probe_entry* probe1, probe_entry* probe2) { int probe_array_delete(struct dawn_mac client_mac, struct dawn_mac bssid_mac) {
int ret = 0;
if (ret == 0)
{
ret = mac_compare_bb(probe1->client_addr, probe2->client_addr);
}
if (ret == 0)
{
ret = mac_compare_bb(probe1->bssid_addr, probe2->bssid_addr);
}
#if 0
// TODO: Is this needed for ordering? Is it a key field?
if (ret == 0)
{
ret = ((probe1->freq < 5000) && (probe2->freq >= 5000));
}
// TODO: Is this needed for ordering? Is it a key field?
if (ret == 0)
{
ret = (probe1->signal < probe2->signal);
}
#endif
return ret;
}
static __inline__ void probe_array_unlink_next(probe_entry** i)
{
probe_entry* victim = *i;
dawnlog_debug_func("Entering...");
// TODO: Can we pre-test that entry is in skip set with
// if ((*s)->next_probe_skip != NULL)... ???
for (struct probe_entry_s** s = &probe_skip_set; *s != NULL; s = &((*s)->next_probe_skip)) {
if (*s == victim) {
*s = (*s)->next_probe_skip;
probe_skip_entry_last--;
break;
}
}
*i = victim->next_probe;
dawn_free(victim);
victim = NULL;
probe_entry_last--;
}
int probe_array_delete(probe_entry *entry) {
int found_in_array = false; int found_in_array = false;
struct probe_entry_s** node_ref = &probe_set.first_probe;
struct probe_entry_s** skip_ref = &probe_set.first_probe_skip;
dawnlog_debug_func("Entering..."); int cmp = 0;
while ((*skip_ref) != NULL) {
cmp = mac_compare_bb((*skip_ref)->client_addr, client_mac);
for (probe_entry** i = &probe_set; *i != NULL; i = &((*i)->next_probe)) { if (cmp == 0)
if (*i == entry) { cmp = mac_compare_bb((*skip_ref)->bssid_addr, bssid_mac);
probe_array_unlink_next(i);
found_in_array = true; if (cmp >= 0) {
break; break;
} }
else {
node_ref = &((*skip_ref)->next_probe);
skip_ref = &((*skip_ref)->next_probe_skip);
}
}
while ((*node_ref) != NULL) {
cmp = mac_compare_bb((*node_ref)->client_addr, client_mac);
if (cmp == 0)
cmp = mac_compare_bb((*node_ref)->bssid_addr, bssid_mac);
if (cmp >= 0) {
break;
}
else {
node_ref = &((*node_ref)->next_probe);
}
}
if (*node_ref && cmp == 0) {
struct probe_entry_s* victim = *node_ref;
*node_ref = victim->next_probe;
probe_set.node_count--;
if (*skip_ref == victim)
{
*skip_ref = victim->next_probe_skip;
probe_set.skip_count--;
}
dawn_free(victim);
victim = NULL;
found_in_array = true;
} }
return found_in_array; return found_in_array;
@ -969,72 +909,58 @@ int probe_array_set_all_probe_count(struct dawn_mac client_addr, uint32_t probe_
// MUSTDO: Has some code been lost here? updated never set... Certain to hit not found... // MUSTDO: Has some code been lost here? updated never set... Certain to hit not found...
pthread_mutex_lock(&probe_array_mutex); pthread_mutex_lock(&probe_array_mutex);
for (probe_entry *i = probe_set; i != NULL; i = i->next_probe) { for (probe_entry *i = probe_array_find_first_entry(client_addr, dawn_mac_null, false);
if (mac_is_equal_bb(client_addr, i->client_addr)) { i != NULL && mac_is_equal_bb(client_addr, i->client_addr);
dawnlog_debug("Setting probecount for given mac!\n"); i = i->next_probe) {
i->counter = probe_count; dawnlog_debug("Setting probecount for given mac!\n");
} else if (mac_compare_bb(client_addr, i->client_addr) > 0) { i->counter = probe_count;
dawnlog_info("MAC not found!\n");
break;
}
} }
pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&probe_array_mutex);
return updated; return updated;
} }
int probe_array_update_rssi(struct dawn_mac bssid_addr, struct dawn_mac client_addr, uint32_t rssi, int send_network) probe_entry* probe_array_update_rssi(struct dawn_mac client_addr, struct dawn_mac bssid_addr, uint32_t rssi, int send_network)
{ {
int updated = 0;
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
probe_entry* i = probe_array_get_entry(bssid_addr, client_addr); probe_entry* entry = probe_array_get_entry(client_addr, bssid_addr);
if (i != NULL) { if (entry) {
i->signal = rssi; entry->signal = rssi;
updated = 1;
if (send_network)
{
ubus_send_probe_via_network(i);
}
}
return updated;
}
int probe_array_update_rcpi_rsni(struct dawn_mac bssid_addr, struct dawn_mac client_addr, uint32_t rcpi, uint32_t rsni, int send_network)
{
int updated = 0;
dawnlog_debug_func("Entering...");
pthread_mutex_lock(&probe_array_mutex);
probe_entry* i = probe_array_get_entry(bssid_addr, client_addr);
if (i != NULL) {
i->rcpi = rcpi;
i->rsni = rsni;
updated = 1;
if (send_network) if (send_network)
ubus_send_probe_via_network(i); ubus_send_probe_via_network(entry);
} }
pthread_mutex_unlock(&probe_array_mutex); return entry;
return updated;
} }
probe_entry *probe_array_get_entry(struct dawn_mac bssid_mac, struct dawn_mac client_mac) { 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..."); dawnlog_debug_func("Entering...");
probe_entry* ret = *probe_array_find_first_entry(client_mac, bssid_mac, true); probe_entry* entry = probe_array_get_entry(client_addr, bssid_addr);
// Check if we've been given the insert position rather than actually finding the entry if (entry) {
if ((ret == NULL) || !mac_is_equal_bb(ret->client_addr, client_mac) || !mac_is_equal_bb(ret->bssid_addr, bssid_mac)) // FIXME: Do we need the -1 tests here?
ret = NULL; if (rcpi != -1)
entry->rcpi = rcpi;
if (rsni != -1)
entry->rsni = rsni;
if (send_network)
ubus_send_probe_via_network(entry);
}
return entry;
}
probe_entry *probe_array_get_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac) {
dawnlog_debug_func("Entering...");
probe_entry* ret = probe_array_find_first_entry(client_mac, bssid_mac, true);
return ret; return ret;
} }
@ -1043,79 +969,105 @@ void print_probe_array() {
if (dawnlog_showing(DAWNLOG_DEBUG)) if (dawnlog_showing(DAWNLOG_DEBUG))
{ {
dawnlog_debug("------------------\n"); dawnlog_debug("------------------\n");
dawnlog_debug("Probe Entry Last: %d\n", probe_entry_last); // dawnlog_debug("Probe Entry Last: %d\n", probe_entry_last);
for (probe_entry* i = probe_set; i != NULL; i = i->next_probe) { for (probe_entry* i = probe_set.first_probe; i != NULL; i = i->next_probe) {
print_probe_entry(DAWNLOG_DEBUG, i); print_probe_entry(DAWNLOG_DEBUG, i);
} }
dawnlog_debug("------------------\n"); dawnlog_debug("------------------\n");
} }
} }
static struct probe_entry_s* insert_to_skip_array(struct probe_entry_s* entry) { probe_entry* insert_to_probe_array(probe_entry* entry, int is_local, int save_80211k, int is_beacon, time_t expiry) {
dawnlog_debug_func("Entering...");
struct probe_entry_s** insert_pos = probe_skip_array_find_first_entry(entry->client_addr, entry->bssid_addr, true);
entry->next_probe_skip = *insert_pos;
*insert_pos = entry;
probe_skip_entry_last++;
return entry;
}
probe_entry* insert_to_array(probe_entry* entry, int inc_counter, int save_80211k, int is_beacon, time_t expiry) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
pthread_mutex_lock(&probe_array_mutex); pthread_mutex_lock(&probe_array_mutex);
entry->time = expiry; struct probe_entry_s** node_ref = &probe_set.first_probe;
struct probe_entry_s** skip_ref = &probe_set.first_probe_skip;
// TODO: Add a packed / unpacked wrapper pair? int cmp = 0;
probe_entry** existing_entry = probe_array_find_first_entry(entry->client_addr, entry->bssid_addr, true); while ((*skip_ref) != NULL) {
cmp = mac_compare_bb((*skip_ref)->client_addr, entry->client_addr);
if (((*existing_entry) != NULL) if (cmp == 0)
&& mac_is_equal_bb((*existing_entry)->client_addr, entry->client_addr) cmp = mac_compare_bb((*skip_ref)->bssid_addr, entry->bssid_addr);
&& mac_is_equal_bb((*existing_entry)->bssid_addr, entry->bssid_addr)) {
(*existing_entry)->time = expiry;
if (inc_counter)
(*existing_entry)->counter++;
if (entry->signal) if (cmp >= 0) {
(*existing_entry)->signal = entry->signal; break;
}
else {
node_ref = &((*skip_ref)->next_probe);
skip_ref = &((*skip_ref)->next_probe_skip);
}
}
if(entry->ht_capabilities) while ((*node_ref) != NULL) {
(*existing_entry)->ht_capabilities = entry->ht_capabilities; cmp = mac_compare_bb((*node_ref)->client_addr, entry->client_addr);
if(entry->vht_capabilities) if (cmp == 0)
(*existing_entry)->vht_capabilities = entry->vht_capabilities; cmp = mac_compare_bb((*node_ref)->bssid_addr, entry->bssid_addr);
if (cmp >= 0) {
break;
}
else {
node_ref = &((*node_ref)->next_probe);
}
}
if (*node_ref && cmp == 0) {
dawnlog_debug("Updating...\n");
if (!is_beacon)
{
if (is_local)
(*node_ref)->counter++;
// Beacon reports don't have these fields, so only update them from probes
(*node_ref)->signal = entry->signal;
(*node_ref)->ht_capabilities = entry->ht_capabilities;
(*node_ref)->vht_capabilities = entry->vht_capabilities;
}
else
{
// FIXME: Equivalent to inserting BEACON based entry
(*node_ref)->counter = dawn_metric.min_probe_count;
}
if (save_80211k && entry->rcpi != -1) if (save_80211k && entry->rcpi != -1)
(*existing_entry)->rcpi = entry->rcpi; (*node_ref)->rcpi = entry->rcpi;
if (save_80211k && entry->rsni != -1) if (save_80211k && entry->rsni != -1)
(*existing_entry)->rsni = entry->rsni; (*node_ref)->rsni = entry->rsni;
entry = *existing_entry; entry = *node_ref;
} }
else else
{ {
dawnlog_debug("Adding...\n"); dawnlog_debug("Adding...\n");
if (inc_counter) if (is_local && !is_beacon)
entry->counter = 1; entry->counter = 1;
else else
entry->counter = 0; entry->counter = 0;
entry->next_probe_skip = NULL; entry->next_probe = *node_ref;
entry->next_probe = *existing_entry; *node_ref = entry;
*existing_entry = entry;
probe_entry_last++;
// Try to keep skip list density stable probe_set.node_count++;
if ((probe_entry_last / DAWN_PROBE_SKIP_RATIO) > probe_skip_entry_last)
if (probe_set.node_count > (probe_set.skip_count * probe_set.skip_ratio))
{ {
insert_to_skip_array(entry); probe_set.skip_count++;
entry->next_probe_skip = *skip_ref;
*skip_ref = entry;
} }
else
{
entry->next_probe_skip = NULL;
}
entry->time = expiry;
} }
pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&probe_array_mutex);
@ -1280,12 +1232,29 @@ void remove_old_client_entries(time_t current_time, long long int threshold) {
void remove_old_probe_entries(time_t current_time, long long int threshold) { void remove_old_probe_entries(time_t current_time, long long int threshold) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
probe_entry **i = &probe_set; probe_entry** i = &(probe_set.first_probe);
probe_entry** s = &(probe_set.first_probe_skip);
while (*i != NULL ) { while (*i != NULL ) {
if (((*i)->time < current_time - threshold) && !is_connected((*i)->bssid_addr, (*i)->client_addr)) { if (((*i)->time < current_time - threshold) && !is_connected((*i)->bssid_addr, (*i)->client_addr)) {
probe_array_unlink_next(i); probe_entry* victim = *i;
*i = victim->next_probe;
if (*s == victim)
{
*s = victim->next_probe_skip;
}
dawn_free(victim);
victim = NULL;
} }
else { else {
if ((*i)->next_probe_skip != NULL)
{
s = &((*i)->next_probe_skip);
}
i = &((*i)->next_probe); i = &((*i)->next_probe);
} }
} }

View file

@ -11,9 +11,9 @@
#include "test_storage.h" #include "test_storage.h"
/*** Test Stub Functions - Called by SUT ***/ /*** Test Stub Functions - Called by SUT ***/
void ubus_send_beacon_report(client *c, ap *a, int id) void ubus_send_beacon_request(client *c, ap *a, int id)
{ {
printf("send_beacon_report() was called...\n"); printf("ubus_send_beacon_request() was called...\n");
} }
int send_set_probe(struct dawn_mac client_addr) int send_set_probe(struct dawn_mac client_addr)
@ -213,32 +213,21 @@ static int array_auto_helper(int action, int i0, int i1)
probe0->client_addr = this_mac; probe0->client_addr = this_mac;
probe0->bssid_addr = this_mac; probe0->bssid_addr = this_mac;
insert_to_array(probe0, true, true, true, 0); // TODO: Check bool flags insert_to_probe_array(probe0, true, true, true, 0); // TODO: Check bool flags
} }
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) { else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
probe0 = dawn_malloc(sizeof(probe_entry)); probe0 = dawn_malloc(sizeof(probe_entry));
set_random_mac(probe0->client_addr.u8); set_random_mac(probe0->client_addr.u8);
set_random_mac(probe0->bssid_addr.u8); set_random_mac(probe0->bssid_addr.u8);
insert_to_array(probe0, true, true, true, faketime); insert_to_probe_array(probe0, true, true, true, faketime);
remove_old_probe_entries(faketime, 10); remove_old_probe_entries(faketime, 10);
time_moves_on(); time_moves_on();
} }
else else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_DEL) {
{ probe_array_delete(this_mac, this_mac);
probe0 = probe_array_get_entry(this_mac, this_mac);
if (probe0 == NULL)
{
printf("Can't find entry to delete!\n");
}
else
{
probe_array_delete(probe0);
}
} }
break; break;
default: default:
printf("HELPER error - which entity?\n"); printf("HELPER error - which entity?\n");
ret = -1; ret = -1;
@ -385,15 +374,6 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
dawn_memory_audit(); dawn_memory_audit();
} }
else if (strcmp(*argv, "probe_sort") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
// sort_string is a datastorage.c global used for sorting probe entries
strcpy(sort_string, argv[1]);
}
}
else if (strcmp(*argv, "faketime") == 0) else if (strcmp(*argv, "faketime") == 0)
{ {
args_required = 2; args_required = 2;
@ -823,7 +803,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
key_check = -1; key_check = -1;
// See if this entry already exists // See if this entry already exists
pr0 = probe_array_get_entry(bmac, cmac); pr0 = probe_array_get_entry(cmac, bmac);
// If not, create and initialise it // If not, create and initialise it
if (pr0 != NULL) if (pr0 != NULL)
@ -855,7 +835,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
pr0->rcpi = 0; pr0->rcpi = 0;
pr0->rsni = 0; pr0->rsni = 0;
insert_to_array(pr0, true, true, true, pr0->time); insert_to_probe_array(pr0, true, true, true, pr0->time);
} }
} }
@ -932,7 +912,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
hwaddr_aton(argv[2], client_mac.u8); hwaddr_aton(argv[2], client_mac.u8);
hwaddr_aton(argv[1], bssid_mac.u8); hwaddr_aton(argv[1], bssid_mac.u8);
probe_entry *pr0 = probe_array_get_entry(bssid_mac, client_mac); probe_entry *pr0 = probe_array_get_entry(client_mac, bssid_mac);
if (pr0 == NULL ) if (pr0 == NULL )
{ {
@ -1075,7 +1055,6 @@ int main(int argc, char* argv[])
} }
else else
{ {
strcpy(sort_string, "bcfs");
init_mutex(); init_mutex();
// Step past command name on args, ie argv[0] // Step past command name on args, ie argv[0]

View file

@ -399,23 +399,6 @@ bool uci_get_dawn_hostapd_dir() {
return false; return false;
} }
bool uci_get_dawn_sort_order() {
dawnlog_debug_func("Entering...");
struct uci_element *e;
uci_foreach_element(&uci_pkg->sections, e)
{
struct uci_section *s = uci_to_section(e);
if (strcmp(s->type, "ordering") == 0) {
const char* str = uci_lookup_option_string(uci_ctx, s, "sort_order");
strncpy(sort_string, str, SORT_LENGTH);
return true;
}
}
return false;
}
int uci_reset() int uci_reset()
{ {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");

View file

@ -300,7 +300,7 @@ int handle_network_msg(char* msg) {
if (strncmp(method, "probe", 5) == 0) { if (strncmp(method, "probe", 5) == 0) {
probe_entry *entry = parse_to_probe_req(data_buf.head); probe_entry *entry = parse_to_probe_req(data_buf.head);
if (entry != NULL) { if (entry != NULL) {
if (entry != insert_to_array(entry, false, true, false, time(0))) // use 802.11k values if (entry != insert_to_probe_array(entry, false, true, false, time(0))) // use 802.11k values
{ {
// insert found an existing entry, rather than linking in our new one // insert found an existing entry, rather than linking in our new one
dawn_free(entry); dawn_free(entry);

View file

@ -214,7 +214,7 @@ bool subscriber_to_interface(const char *ifname);
bool subscribe(struct ubus_context *ctx_local, struct hostapd_sock_entry *hostapd_entry); bool subscribe(struct ubus_context *ctx_local, struct hostapd_sock_entry *hostapd_entry);
int parse_to_beacon_rep(struct blob_attr *msg); static probe_entry* parse_to_beacon_rep(struct blob_attr *msg);
void ubus_set_nr(); void ubus_set_nr();
@ -264,7 +264,8 @@ int parse_to_client_req(struct blob_attr *msg, client_req_entry *client_req) {
return 0; return 0;
} }
int parse_to_beacon_rep(struct blob_attr *msg) { static probe_entry* parse_to_beacon_rep(struct blob_attr *msg) {
probe_entry* beacon_rep = NULL;
struct blob_attr *tb[__BEACON_REP_MAX]; struct blob_attr *tb[__BEACON_REP_MAX];
struct dawn_mac msg_bssid; struct dawn_mac msg_bssid;
struct dawn_mac msg_client; struct dawn_mac msg_client;
@ -273,78 +274,49 @@ int parse_to_beacon_rep(struct blob_attr *msg) {
blobmsg_parse(beacon_rep_policy, __BEACON_REP_MAX, tb, blob_data(msg), blob_len(msg)); blobmsg_parse(beacon_rep_policy, __BEACON_REP_MAX, tb, blob_data(msg), blob_len(msg));
if(!tb[BEACON_REP_BSSID] || !tb[BEACON_REP_ADDR]) if (!tb[BEACON_REP_BSSID] ||
!tb[BEACON_REP_ADDR] ||
hwaddr_aton(blobmsg_data(tb[BEACON_REP_BSSID]), msg_bssid.u8) ||
hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), msg_client.u8))
{ {
return -1; dawnlog_warning("Parse of beacon report failed!\n");
} }
else
if (hwaddr_aton(blobmsg_data(tb[BEACON_REP_BSSID]), msg_bssid.u8))
return UBUS_STATUS_INVALID_ARGUMENT;
if(mac_is_null(msg_bssid.u8))
{ {
dawnlog_warning("Received NULL MAC! Client is strange!\n"); ap* ap_entry_rep = ap_array_get_ap(msg_bssid);
return -1;
}
const uint8_t *ssid = (const uint8_t*)blobmsg_get_string(tb[BEACON_REP_SSID]); // no client from network!!
ap *ap_entry_rep = ap_array_get_ap(msg_bssid); if (!ap_entry_rep) {
dawnlog_warning("No AP for beacon report entry!\n");
// no client from network!!
if (ap_entry_rep == NULL) {
return -1; //TODO: Check this
}
if (hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), msg_client.u8))
return UBUS_STATUS_INVALID_ARGUMENT;
int rcpi = blobmsg_get_u16(tb[BEACON_REP_RCPI]);
int rsni = blobmsg_get_u16(tb[BEACON_REP_RSNI]);
// HACKY WORKAROUND!
dawnlog_debug("Try update RCPI and RSNI for beacon report!\n");
if(!probe_array_update_rcpi_rsni(msg_bssid, msg_client, rcpi, rsni, true))
{
dawnlog_debug("Beacon: No Probe Entry Existing!\n");
probe_entry* beacon_rep = dawn_malloc(sizeof(probe_entry));
probe_entry* beacon_rep_updated = NULL;
if (beacon_rep == NULL)
{
dawnlog_error("dawn_malloc of probe_entry failed!\n");
return -1;
}
beacon_rep->next_probe = NULL;
beacon_rep->bssid_addr = msg_bssid;
beacon_rep->client_addr = msg_client;
strncpy((char*)beacon_rep->ssid, (char*)ssid, SSID_MAX_LEN);
beacon_rep->ssid[SSID_MAX_LEN] = '\0';
beacon_rep->counter = dawn_metric.min_probe_count;
hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), beacon_rep->target_addr.u8); // TODO: What is this for?
beacon_rep->signal = 0;
beacon_rep->freq = ap_entry_rep->freq;
beacon_rep->rcpi = rcpi;
beacon_rep->rsni = rsni;
beacon_rep->ht_capabilities = false; // that is very problematic!!!
beacon_rep->vht_capabilities = false; // that is very problematic!!!
dawnlog_debug("Inserting to array!\n");
// TODO: kept original code order here - send on network first to simplify?
beacon_rep_updated = insert_to_array(beacon_rep, false, false, true, time(0));
if (beacon_rep != beacon_rep_updated) // use 802.11k values // TODO: Change 0 to false?
{
// insert found an existing entry, rather than linking in our new one
ubus_send_probe_via_network(beacon_rep_updated);
dawn_free(beacon_rep);
beacon_rep = NULL;
} }
else else
ubus_send_probe_via_network(beacon_rep_updated); {
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!!!
}
}
} }
return 0;
return beacon_rep;
} }
int handle_auth_req(struct blob_attr* msg) { int handle_auth_req(struct blob_attr* msg) {
@ -377,7 +349,7 @@ bool discard_entry = true;
if (dawnlog_showing(DAWNLOG_DEBUG)) if (dawnlog_showing(DAWNLOG_DEBUG))
print_probe_array(); print_probe_array();
probe_entry *tmp = probe_array_get_entry(auth_req->bssid_addr, auth_req->client_addr); probe_entry *tmp = probe_array_get_entry(auth_req->client_addr, auth_req->bssid_addr);
pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&probe_array_mutex);
@ -449,7 +421,7 @@ int discard_entry = true;
if (dawnlog_showing(DAWNLOG_DEBUG)) if (dawnlog_showing(DAWNLOG_DEBUG))
print_probe_array(); print_probe_array();
probe_entry *tmp = probe_array_get_entry(assoc_req->bssid_addr, assoc_req->client_addr); probe_entry *tmp = probe_array_get_entry(assoc_req->client_addr, assoc_req->bssid_addr);
pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&probe_array_mutex);
@ -496,11 +468,10 @@ int discard_entry = true;
} }
static int handle_probe_req(struct blob_attr* msg) { static int handle_probe_req(struct blob_attr* msg) {
// MUSTDO: Untangle dawn_malloc() and linking of probe_entry
probe_entry* probe_req = parse_to_probe_req(msg);
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
// MUSTDO: Untangle dawn_malloc() and linking of probe_entry
probe_entry* probe_req = parse_to_probe_req(msg);
if (probe_req == NULL) if (probe_req == NULL)
{ {
@ -509,7 +480,7 @@ static int handle_probe_req(struct blob_attr* msg) {
} }
else else
{ {
probe_entry* probe_req_updated = insert_to_array(probe_req, true, true, false, time(0)); probe_entry* probe_req_updated = insert_to_probe_array(probe_req, true, true, false, time(0));
// If insert finds an existing entry, rather than linking in our new one, // If insert finds an existing entry, rather than linking in our new one,
// send new probe req because we want to stay synced. // send new probe req because we want to stay synced.
// If not, probe_req and probe_req_updated should be equivalent // If not, probe_req and probe_req_updated should be equivalent
@ -558,17 +529,48 @@ static int handle_probe_req(struct blob_attr* msg) {
return WLAN_STATUS_SUCCESS; return WLAN_STATUS_SUCCESS;
} }
// FIXME: Seems to do nothing...
static int handle_beacon_rep(struct blob_attr *msg) { static int handle_beacon_rep(struct blob_attr *msg) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
int ret = UBUS_STATUS_INVALID_ARGUMENT;
if (parse_to_beacon_rep(msg) == 0) { probe_entry* entry = parse_to_beacon_rep(msg);
// dawnlog_debug("Inserting beacon Report!\n");
// insert_to_array(beacon_rep, 1); if (entry)
// dawnlog_debug("Sending via network!\n"); {
// send_blob_attr_via_network(msg, "beacon-report"); if (mac_is_null(entry->bssid_addr.u8))
{
dawnlog_warning("Received NULL MAC! Client is strange!\n");
dawn_free(entry);
}
else
{
// Update RxxI of current entry if it exists
pthread_mutex_lock(&probe_array_mutex);
probe_entry* entry_updated = probe_array_update_rcpi_rsni(entry->client_addr, entry->bssid_addr, entry->rcpi, entry->rsni, true);
pthread_mutex_unlock(&probe_array_mutex);
if (entry_updated)
{
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);
}
else
{
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
entry = insert_to_probe_array(entry, false, false, true, time(0));
ubus_send_probe_via_network(entry);
ret = 0;
}
}
} }
return 0;
return ret;
} }
@ -944,7 +946,7 @@ static int get_mode_from_capability(int capability) {
return -1; return -1;
} }
void ubus_send_beacon_report(client *c, ap *a, int id) void ubus_send_beacon_request(client *c, ap *a, int id)
{ {
struct blob_buf b = {0}; struct blob_buf b = {0};
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
@ -961,7 +963,7 @@ void ubus_send_beacon_report(client *c, ap *a, int id)
blobmsg_add_u32(&b, "mode", get_mode_from_capability(c->rrm_enabled_capa)); blobmsg_add_u32(&b, "mode", get_mode_from_capability(c->rrm_enabled_capa));
blobmsg_add_string(&b, "ssid", (char*)a->ssid); blobmsg_add_string(&b, "ssid", (char*)a->ssid);
dawnlog_debug("Invoking beacon report!\n"); dawnlog_debug("Invoking beacon request!\n");
ubus_invoke(ctx, id, "rrm_beacon_req", b.head, NULL, NULL, timeout * 1000); ubus_invoke(ctx, id, "rrm_beacon_req", b.head, NULL, NULL, timeout * 1000);
blob_buf_free(&b); blob_buf_free(&b);
dawn_unregmem(&b); dawn_unregmem(&b);
@ -976,13 +978,13 @@ void update_beacon_reports(struct uloop_timeout *t) {
{ {
return; return;
} }
dawnlog_debug("Sending beacon report!\n"); dawnlog_debug("Sending beacon requests!\n");
struct hostapd_sock_entry *sub; struct hostapd_sock_entry *sub;
list_for_each_entry(sub, &hostapd_sock_list, list) list_for_each_entry(sub, &hostapd_sock_list, list)
{ {
if (sub->subscribed && (a = ap_array_get_ap(sub->bssid_addr))) { if (sub->subscribed && (a = ap_array_get_ap(sub->bssid_addr))) {
dawnlog_debug("Sending beacon report Sub!\n"); dawnlog_debug("Sending beacon request Sub!\n");
send_beacon_reports(a, sub->id); send_beacon_requests(a, sub->id);
} }
} }
uloop_timeout_set(&beacon_reports_timer, timeout_config.update_beacon_reports * 1000); uloop_timeout_set(&beacon_reports_timer, timeout_config.update_beacon_reports * 1000);
@ -1326,7 +1328,6 @@ static int reload_config(struct ubus_context *ctx_local, struct ubus_object *obj
dawn_metric = uci_get_dawn_metric(); dawn_metric = uci_get_dawn_metric();
timeout_config = uci_get_time_config(); timeout_config = uci_get_time_config();
uci_get_dawn_hostapd_dir(); uci_get_dawn_hostapd_dir();
uci_get_dawn_sort_order();
if(timeout_config.update_beacon_reports) // allow setting timeout to 0 if(timeout_config.update_beacon_reports) // allow setting timeout to 0
uloop_timeout_add(&beacon_reports_timer); // callback = update_beacon_reports uloop_timeout_add(&beacon_reports_timer); // callback = update_beacon_reports
@ -1696,6 +1697,20 @@ int uci_send_via_network()
return 0; return 0;
} }
// FIXME: Not sure if we need to create a NUL terminated string. Is unterminated length of 8 enough?
static void blobmsg_add_rrm_string(struct blob_buf* b, char* n, uint8_t caps)
{
char* s = blobmsg_alloc_string_buffer(b, n, 9);
s[8] = '\0';
for (int i = 7; i >= 0; i--)
{
// Treat string literal as char[] to get a mnemonic character for the capability
s[i] = (caps & 0x01) ? "?TAP??NL"[i] : '.';
caps >>= 1;
}
blobmsg_add_string_buffer(b);
}
int build_hearing_map_sort_client(struct blob_buf *b) { int build_hearing_map_sort_client(struct blob_buf *b) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
@ -1714,7 +1729,7 @@ int build_hearing_map_sort_client(struct blob_buf *b) {
// Scan AP list to find first of each SSID // Scan AP list to find first of each SSID
if (!same_ssid) { if (!same_ssid) {
ssid_list = blobmsg_open_table(b, (char*)m->ssid); ssid_list = blobmsg_open_table(b, (char*)m->ssid);
probe_entry* i = probe_set; probe_entry* i = probe_set.first_probe;
while (i != NULL) { while (i != NULL) {
ap *ap_entry_i = ap_array_get_ap(i->bssid_addr); ap *ap_entry_i = ap_array_get_ap(i->bssid_addr);
@ -1830,34 +1845,38 @@ int build_network_overview(struct blob_buf *b) {
blobmsg_add_string_buffer(b); blobmsg_add_string_buffer(b);
// TODO: Could optimise this by exporting search func, but not a core process // TODO: Could optimise this by exporting search func, but not a core process
client *k = client_set_bc; client *k = *client_find_first_bc_entry(m->bssid_addr, dawn_mac_null, false);
while (k != NULL) { while (k != NULL && mac_is_equal_bb(m->bssid_addr, k->bssid_addr)) {
if (mac_is_equal_bb(m->bssid_addr, k->bssid_addr)) { sprintf(client_mac_buf, MACSTR, MAC2STR(k->client_addr.u8));
sprintf(client_mac_buf, MACSTR, MAC2STR(k->client_addr.u8)); client_list = blobmsg_open_table(b, client_mac_buf);
client_list = blobmsg_open_table(b, client_mac_buf);
if(strlen(k->signature) != 0) if (strlen(k->signature) != 0)
{ {
char *s; char* s;
s = blobmsg_alloc_string_buffer(b, "signature", 1024); s = blobmsg_alloc_string_buffer(b, "signature", 1024);
sprintf(s, "%s", k->signature); sprintf(s, "%s", k->signature);
blobmsg_add_string_buffer(b); blobmsg_add_string_buffer(b);
}
blobmsg_add_u8(b, "ht", k->ht);
blobmsg_add_u8(b, "vht", k->vht);
//blobmsg_add_u32(b, "collision_count", ap_get_collision_count(m->collision_domain));
pthread_mutex_lock(&probe_array_mutex);
probe_entry* n = probe_array_get_entry(k->bssid_addr, k->client_addr);
pthread_mutex_unlock(&probe_array_mutex);
if (n != NULL) {
blobmsg_add_u32(b, "signal", n->signal);
}
blobmsg_close_table(b, client_list);
} }
blobmsg_add_u8(b, "ht", k->ht);
blobmsg_add_u8(b, "vht", k->vht);
blobmsg_add_rrm_string(b, "rrm-caps", k->rrm_enabled_capa);
pthread_mutex_lock(&probe_array_mutex);
probe_entry* n = probe_array_get_entry(k->client_addr, k->bssid_addr);
if (n != NULL) {
{
blobmsg_add_u32(b, "signal", n->signal);
blobmsg_add_u32(b, "rcpi", n->rcpi);
blobmsg_add_u32(b, "rsni", n->rsni);
}
}
pthread_mutex_unlock(&probe_array_mutex);
blobmsg_close_table(b, client_list);
k = k->next_entry_bc; k = k->next_entry_bc;
} }
blobmsg_close_table(b, ap_list); blobmsg_close_table(b, ap_list);
@ -1948,16 +1967,15 @@ void uloop_add_data_cbs() {
uloop_timeout_add(&ap_timeout); // callback = remove_ap_array_cb uloop_timeout_add(&ap_timeout); // callback = remove_ap_array_cb
} }
// TODO: Move mutex handling to remove_??? function to make test harness simpler?
// Or not needed as test harness not threaded?
void remove_probe_array_cb(struct uloop_timeout* t) { void remove_probe_array_cb(struct uloop_timeout* t) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("[Thread] : Removing old probe entries!\n");
pthread_mutex_lock(&probe_array_mutex); pthread_mutex_lock(&probe_array_mutex);
dawnlog_debug("[Thread] : Removing old probe entries!\n");
remove_old_probe_entries(time(0), timeout_config.remove_probe); remove_old_probe_entries(time(0), timeout_config.remove_probe);
dawnlog_debug("[Thread] : Removing old entries finished!\n");
pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&probe_array_mutex);
dawnlog_debug("[Thread] : Removing old entries finished!\n");
uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000); uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000);
} }