diff --git a/src/core/agent_cmdu_generator.c b/src/core/agent_cmdu_generator.c index fd442e8d96e343d78d341b315bd7734bf900156c..73e84b74b560a5a32910bc70de6c82dc1af072c1 100644 --- a/src/core/agent_cmdu_generator.c +++ b/src/core/agent_cmdu_generator.c @@ -378,7 +378,7 @@ error: return NULL; } -struct cmdu_cstruct *agent_gen_assoc_sta_metric_response( +struct cmdu_cstruct *agent_gen_assoc_sta_metric_response_per_intf( struct agent *a, char *ifname) { int i; @@ -468,3 +468,114 @@ error: return NULL; } + +struct cmdu_cstruct *agent_gen_assoc_sta_metric_response( + struct agent *a, struct cmdu_cstruct *rec_cmdu) +{ + struct cmdu_cstruct *cmdu; + struct tlv_sta_mac *query; + struct netif_fh *fh; + struct sta *s; + struct tlv_assoc_sta_link_metrics *p1; + struct tlv_assoc_sta_ext_link_metric *p2; + struct tlv_error_code *p3; + uint8_t *tmp; + uint8_t reason_code; + int tlv_index = 0; + bool is_sta_found = false; + + if (!rec_cmdu) + return NULL; + + cmdu = calloc(1, sizeof(struct cmdu_cstruct)); + if (!cmdu) { + fprintf(stderr, "failed to malloc cmdu\n"); + return NULL; + } + + cmdu->message_type = CMDU_ASSOC_STA_LINK_METRICS_RESPONSE; + memcpy(cmdu->origin, rec_cmdu->origin, 6); + strncpy(cmdu->intf_name, rec_cmdu->intf_name, IFNAMESIZE - 1); + cmdu->message_id = rec_cmdu->message_id; + + if (!rec_cmdu->num_tlvs || (rec_cmdu->num_tlvs > 1)) + goto error; + + tmp = (uint8_t *)rec_cmdu->tlvs[0]; + if (*tmp != MAP_TLV_STA_MAC_ADDRESS) + goto error; + + query = (struct tlv_sta_mac *)tmp; + list_for_each_entry(fh, &a->fhlist, list) { + list_for_each_entry(s, &fh->stalist, list) { + if (hwaddr_equal(query->addr, s->macaddr)) { + is_sta_found = true; + break; + } + } + if (is_sta_found) + break; + } + + /* Associated STA Link Metrics TLV */ + cmdu->num_tlvs = 1; + if (is_sta_found) { +// #ifdef PROFILE2 + /* Associated STA Extended Link Metrics TLV */ + cmdu->num_tlvs++; +// #endif + } else + cmdu->num_tlvs++; /* Error Code TLV*/ + + cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *)); + if (!cmdu->tlvs) { + cmdu->num_tlvs = 0; + goto error; + } + + if (is_sta_found) { + /* Associated STA Link Metrics TLV */ + p1 = agent_gen_assoc_sta_link_metrics(a, s, fh->bssid); + if (!p1) + goto error; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p1; + +// #ifdef PROFILE2 + /* Associated STA Extended Link Metrics TLV */ + p2 = agent_gen_assoc_sta_ext_link_metric(a, s, fh->bssid); + if (!p2) + goto error; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p2; +// #endif + + } else { + /* Associated STA Link Metrics TLV */ + p1 = calloc(1, sizeof(*p1)); + if (!p1) + goto error; + + p1->tlv_type = MAP_TLV_ASSOCIATED_STA_LINK_METRICS; + memcpy(p1->addr, query->addr, 6); + /* Reported BSS for STA */ + p1->bssid_nr = 0; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p1; + + /* Error Code TLV */ + reason_code = 0x02; /* STA not associated with any BSS */ + p3 = agent_gen_tlv_error_code(a, NULL, query->addr, reason_code); + if (!p3) + goto error; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p3; + } + + return cmdu; + +error: + map_free_cmdu(cmdu); + + return NULL; +} diff --git a/src/core/agent_cmdu_generator.h b/src/core/agent_cmdu_generator.h index d416d15d6f0a1f13baccbe32d79cd5807e93d2a8..ced1c60c67929bb290b9b307173886305e0e3e40 100644 --- a/src/core/agent_cmdu_generator.h +++ b/src/core/agent_cmdu_generator.h @@ -15,7 +15,9 @@ struct cmdu_cstruct *agent_gen_ap_autoconfig_search(struct agent *a, uint8_t profile); struct cmdu_cstruct *agent_gen_ap_metrics_response(struct agent *a, struct cmdu_cstruct *rec_cmdu); -struct cmdu_cstruct *agent_gen_assoc_sta_metric_response( +struct cmdu_cstruct *agent_gen_assoc_sta_metric_response_per_intf( struct agent *a, char *ifname); +struct cmdu_cstruct *agent_gen_assoc_sta_metric_response( + struct agent *a, struct cmdu_cstruct *rec_cmdu); #endif diff --git a/src/core/agent_map.c b/src/core/agent_map.c index 41cccfead27866a75da456b424ac1bae1cd6fcb6..3bef6dcdd0bcf193c67e295270513ee1320da68a 100644 --- a/src/core/agent_map.c +++ b/src/core/agent_map.c @@ -1126,7 +1126,7 @@ static int prepare_assoc_sta_metric_response(void *agent, char *ifname) struct cmdu_cstruct *cmdu; struct agent *a = (struct agent *)agent; - cmdu = agent_gen_assoc_sta_metric_response(a, ifname); + cmdu = agent_gen_assoc_sta_metric_response_per_intf(a, ifname); if (!cmdu) return -1; @@ -1988,9 +1988,19 @@ int handle_ap_metrics_query(void *agent, struct cmdu_cstruct *cmdu) return 0; } -int handle_sta_link_metrics_query(void *agent, struct cmdu_cstruct *cmdu) +int handle_sta_link_metrics_query(void *agent, struct cmdu_cstruct *rec_cmdu) { trace("%s: --->\n", __func__); + struct cmdu_cstruct *cmdu; + struct agent *a = (struct agent *)agent; + + cmdu = agent_gen_assoc_sta_metric_response(a, rec_cmdu); + if (!cmdu) + return -1; + + agent_send_cmdu(a, cmdu); + map_free_cmdu(cmdu); + return 0; } @@ -2858,7 +2868,6 @@ char *get_timestamp(time_t *t, char **tbuf) static void scan_results(struct agent *a, struct tlv_ch_scan_res *p, uint32_t radio_index, uint32_t opclass_index, uint32_t channel_index) { - struct wifi_radio_element *radio = a->radios + radio_index; struct wifi_scanres_opclass_element *op = radio->scanlist[0].opclass_scanlist + opclass_index; struct wifi_scanres_channel_element *ch = op->channel_scanlist + channel_index; @@ -2870,7 +2879,7 @@ static void scan_results(struct agent *a, struct tlv_ch_scan_res *p, uint32_t ra p->ch = ch->channel; p->scan_res = CH_SCAN_STATUS_SUCCESS; if (p->scan_res == CH_SCAN_STATUS_SUCCESS) { - get_timestamp(NULL, &p->timestamp); + get_timestamp(NULL, &p->timestamp); p->time_len = strlen(p->timestamp); p->utilization = ch->utilization; p->noise = ch->anpi; @@ -2881,7 +2890,7 @@ static void scan_results(struct agent *a, struct tlv_ch_scan_res *p, uint32_t ra struct wifi_scanres_neighbor_element *nbr = ch->nbrlist + i; memcpy(p->neighbor_data[i].bssid, nbr->bssid, 6); - p->neighbor_data[i].ssid = strdup(nbr->ssid); + p->neighbor_data[i].ssid = strdup(nbr->ssid); p->neighbor_data[i].ssid_len = strlen(p->neighbor_data[i].ssid); p->neighbor_data[i].signal_strength = nbr->rssi; p->neighbor_data[i].bss_load_elm_present = 1; @@ -2912,7 +2921,7 @@ int handle_channel_scan_request(void *agent, struct cmdu_cstruct *cmdu) struct cmdu_cstruct *cmdu_data; int ret; - // The received TLV + // The received TLV uint8_t *tmp = NULL; tmp = cmdu->tlvs[0]; @@ -2964,7 +2973,7 @@ int handle_channel_scan_request(void *agent, struct cmdu_cstruct *cmdu) for (int j = 0; j < radio->scanlist->opclass_scanlist[i].num_channels_scanned; j++) { if (radio->scanlist->opclass_scanlist[i].channel_scanlist[j].channel == query_channel) { opclass_index = i; - channel_index = j; + channel_index = j; struct tlv_ch_scan_res *p1 = (struct tlv_ch_scan_res *)calloc(1, sizeof(struct tlv_ch_scan_res)); if (p1) {