diff --git a/src/cntlr.h b/src/cntlr.h index 4c48ee688a6dc5b5f08363332bf55c0694799385..503e1e09e9823d35d669ad7b2e08328bb421d83f 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -286,12 +286,6 @@ enum cntlr_state { CNTLR_START /* normal */ }; -#define STEER_MAX_CHANNEL 64 -struct steering { - int channels_num; - uint8_t channels[STEER_MAX_CHANNEL]; -}; - struct controller { enum cntlr_state state; unsigned char almac[6]; @@ -322,7 +316,6 @@ struct controller { struct hlist_head *as_table; /** active sta hash table */ struct controller_config cfg; struct cmdu_ackq cmdu_ack_q; - struct steering steer_params; /* Autoconfig */ uint16_t mid_5g; @@ -342,8 +335,9 @@ struct controller { struct sta_channel_report { uint8_t opclass; +#define STA_CHANNEL_REPORT_MAX_CHAN 64 uint8_t num_channel; - uint8_t channel[128]; + uint8_t channel[STA_CHANNEL_REPORT_MAX_CHAN]; }; #define MAX_UNASSOC_STAMACS 10 diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c index d733c7461f50c03b627f013e53ffb68bc377a700..24cc9051755b53f206734f65b0901ecff8f3d693 100644 --- a/src/cntlr_cmdu.c +++ b/src/cntlr_cmdu.c @@ -199,7 +199,7 @@ struct cmdu_buff *cntlr_gen_beacon_metrics_query(struct controller *c, cmdu_put_eom(resp); - cntlr_add_bcnreq(c, sta_addr, agent_mac, num_report); + cntlr_add_bcnreq(c, sta_addr, agent_mac, num_report ? num_report : 1); return resp; fail: diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 582217f0e8183c508915209176fd59db644f00af..fd8d492ccd20da3551f2ade3c1b519cfc6a1a809 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -222,40 +222,6 @@ int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu, return 0; } -static void cntlr_reset_steer_params(struct controller *c) -{ - c->steer_params.channels_num = 0; - memset(c->steer_params.channels, 0, - STEER_MAX_CHANNEL * sizeof(c->steer_params.channels[0])); -} - -static void cntlr_update_steer_params(struct controller *c, struct wifi_radio_opclass *op) -{ - int i, j, k; - bool found; - struct wifi_radio_opclass_entry *oe; - struct steering *sp; - - for (i = 0; i < op->num_opclass; i++) { - oe = &op->opclass[i]; - for (j = 0; j < oe->num_channel; j++) { - sp = &c->steer_params; - found = false; - for (k = 0; k < sp->channels_num; k++) { - if(sp->channels[k] == oe->channel[j].channel) { - found = true; - break; - } - } - - if (!found) { - sp->channels[sp->channels_num] = oe->channel[j].channel; - sp->channels_num++; - } - } - } -} - int handle_topology_query(void *cntlr, struct cmdu_buff *cmdu, struct node *n) { trace("%s: --->\n", __func__); @@ -556,7 +522,6 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n uint16_t conntime; struct sta *s; struct netif_iface *bsta; - struct netif_radio *r = NULL; memcpy(macaddr, &tv_data[offset], 6); @@ -587,11 +552,6 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n //s->de_sta->mapsta.stats.failed_steer_attempts = 0; //timestamp_reset(s->stats.last_steer_time); } - - /* New sta, update params for steering and beacon requests */ - r = find_radio_by_bssid(c, s->fh->bss->bssid); - if (r) - cntlr_update_steer_params(c, &r->radio_el->cur_opclass); } } } @@ -1721,10 +1681,6 @@ int handle_oper_channel_report(void *cntlr, struct cmdu_buff *cmdu, struct node offset++; cntlr_radio_cur_opclass_dump(r->radio_el); - - /* Channel changed, update ctrl's steer params accordingly */ - cntlr_reset_steer_params(c); - cntlr_update_steer_params(c, &r->radio_el->cur_opclass); } return 0; @@ -1916,22 +1872,77 @@ static void cntlr_request_bcn_metrics_bsta(struct controller *c, struct sta *s) } } -static uint8_t cntlr_get_classid_ht20(struct controller *c, uint8_t channel) +static void _cntlr_create_sta_channel_reports(struct wifi_radio_element *radio, + struct sta_channel_report *reports, uint8_t *num_report) { - struct node *n = NULL; - struct netif_radio *r = NULL; - uint8_t id; + struct wifi_radio_opclass *cur_opclass = &radio->cur_opclass; + int i; + + for (i = 0; i < cur_opclass->num_opclass; i++) { + struct wifi_radio_opclass_entry *oe; + struct wifi_radio_opclass *pref_opclass = &radio->pref_opclass; + uint8_t cl_id; + int j, k; + + oe = &cur_opclass->opclass[i]; + if (!oe->num_channel) + continue; + + /* Always use /20 classid for beacon metrics */ + cl_id = wifi_opclass_get_id(pref_opclass, oe->channel[0].channel, 20); - list_for_each_entry(n, &c->nodelist, list) { - list_for_each_entry(r, &n->radiolist, list) { - id = wifi_opclass_get_id(&r->radio_el->pref_opclass, - channel, 20); - if (id) - return id; - } - } + for (j = 0; j < *num_report; j++) { + if (reports[j].opclass == cl_id) + /* opclass already present in report */ + break; + } - return 0; /* Not found */ + if (j == *num_report) { + /* add this opclass to the report */ + reports[(*num_report)++].opclass = cl_id; + } + + for (k = 0; k < oe->num_channel; k++) { + int l; + + for (l = 0; l < reports[j].num_channel; l++) { + if (oe->channel[k].channel == reports[j].channel[l]) + /* channel already present in report */ + break; + } + + if (l == reports[j].num_channel) { + /* add this channel to the report */ + reports[j].channel[l] = oe->channel[k].channel; + reports[j].num_channel++; + dbg("|%s:%d| channel_report add: clid=%d|chan=%d\n", + __func__, __LINE__, + reports[j].opclass, + reports[j].channel[l]); + } + } + } +} + +static void cntlr_create_sta_channel_reports(struct controller *c, struct sta *s, + struct sta_channel_report *reports, uint8_t *num_report) +{ + struct node *n = NULL; + struct netif_radio *r = NULL; + struct netif_iface *p = NULL; + + list_for_each_entry(n, &c->nodelist, list) { + list_for_each_entry(r, &n->radiolist, list) { + list_for_each_entry(p, &r->iflist, list) { + if (!p->bss || !s->fh || !s->fh->bss) + continue; + if (p->bss->ssid && s->fh->bss->ssid + && !memcmp(p->bss->ssid, s->fh->bss->ssid, 33)) + _cntlr_create_sta_channel_reports(r->radio_el, + reports, num_report); + } + } + } } static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s) @@ -1939,60 +1950,22 @@ static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s) struct cmdu_buff *bcn_cmdu; uint8_t wildcard[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; uint8_t opclass = 0; - uint8_t channel = 0; - struct sta_channel_report *reports = NULL; - struct steering *sp; + uint8_t channel = 255; /* use channel report by default */ + struct sta_channel_report reports[16]; uint8_t num_report = 0; - struct { - uint8_t opclass; - uint8_t channel; - } op_ch[16]; - uint8_t opc; - int i; trace("%s: --->\n", __func__); - sp = &c->steer_params; - - dbg("|%s:%d| channels_num = %d\n", __func__, __LINE__, sp->channels_num); - - if (sp->channels_num < 1 || sp->channels_num > 16) - return -1; + cntlr_create_sta_channel_reports(c, s, reports, &num_report); - if (sp->channels_num == 1) { - /* won't use channel report */ - opclass = cntlr_get_classid_ht20(c, sp->channels[0]); /* /20 */ - if (!opclass) - return -1; - channel = sp->channels[0]; + if (num_report == 1 && reports[0].num_channel == 1) { + /* one channel & opclass pair only - don't use channel report */ + opclass = reports[0].opclass; + channel = reports[0].channel[0]; num_report = 0; - } else { - opclass = 0; - channel = 255; /* use channel report */ - for (i = 0; i < sp->channels_num; i++) { - opc = cntlr_get_classid_ht20(c, sp->channels[i]); - if (!opc) - continue; - op_ch[num_report].opclass = opc; - op_ch[num_report].channel = sp->channels[i]; - num_report++; - } - - if (!num_report) - return -1; - - reports = calloc(num_report, sizeof(struct sta_channel_report)); - if (!reports) - return -ENOMEM; - - for (i = 0; i < num_report; i++) { - reports[i].opclass = op_ch[i].opclass; - reports[i].num_channel = 1; - reports[i].channel[0] = op_ch[i].channel; - } } - dbg("|%s:%d| alid " MACFMT " s->de_sta->macaddr " MACFMT " num_report = %d\n", + dbg("|%s:%d| alid " MACFMT " STA mac " MACFMT " num_report = %d\n", __func__, __LINE__, MAC2STR(s->fh->agent->alid), MAC2STR(s->de_sta->macaddr), @@ -2009,9 +1982,6 @@ static int cntlr_request_bcn_metrics_sta(struct controller *c, struct sta *s) cmdu_free(bcn_cmdu); } - if (reports) - free(reports); - /* returns expected number of requests in agents */ return (num_report ? num_report : 1); }