diff --git a/src/agent.c b/src/agent.c index 187711c537367b6904f1fcb62c5ee4f9dc2dea65..c4709fd9778f938538ff32e34cc7f7198daf8b42 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1650,6 +1650,19 @@ static void mlsta_update_sta_mld(struct agent *a, struct netif_ap *ap, // __func__, __LINE__, // mld->num_affiliated_sta); } + +/* get netif_mld based on bssid */ +struct netif_mld *wifi_get_mld_by_mac(struct agent *a, uint8_t *macaddr) +{ + struct netif_mld *mld; + + list_for_each_entry(mld, &a->apmldlist, list) { + if (hwaddr_equal(mld->macaddr, macaddr)) + return mld; + } + + return NULL; +} #endif #define STA_STALE_STATS_CNT_MAX 60 @@ -6524,6 +6537,12 @@ static int agent_radio_update_scanresults_element(struct wifi_radio_element *re, scanres_el->nbrlist[idx].bw = wifi_bw_to_bw(bsss->curr_bw); scanres_el->nbrlist[idx].utilization = bsss->load.utilization; scanres_el->nbrlist[idx].num_stations = bsss->load.sta_count; +#if (EASYMESH_VERSION >= 6) + scanres_el->nbrlist[idx].mld_link_id = bsss->mlo_link_id; + if (bsss->mlo_link_id != WIFI_MLO_INVALID_LINK_ID) + memcpy(scanres_el->nbrlist[idx].mld_macaddr, bsss->mld_macaddr, 6); +#endif + return 0; } diff --git a/src/agent.h b/src/agent.h index 1a9eac6b62ce6b8507a7e6c1a024fe4d0a6c5c77..76bc693fa75c9b55db7e85f928e6cac714263cf4 100644 --- a/src/agent.h +++ b/src/agent.h @@ -569,6 +569,10 @@ struct wifi_scanres_neighbor_element { uint32_t bw; uint8_t utilization; uint32_t num_stations; +#if (EASYMESH_VERSION >= 6) + uint8_t mld_link_id; + uint8_t mld_macaddr[6]; +#endif }; struct wifi_scanres_channel_element { @@ -1111,6 +1115,7 @@ int agent_switch_according_to_pref(struct agent *a); #if (EASYMESH_VERSION >= 6) bool wifi_is_affiliated_ap(struct agent *a, uint8_t *bssid); const char *wifi_ifname_to_mld(struct agent *a, char *ifname); +struct netif_mld *wifi_get_mld_by_bssid(struct agent *a, uint8_t *bssid); bool agent_radio_support_ap_wifi7(struct wifi7_radio_capabilities *wifi7_caps); bool agent_radio_support_bsta_wifi7(struct wifi7_radio_capabilities *wifi7_caps); int wifi_sta_mld_del_bsta(struct agent *a, struct netif_bk *bk); diff --git a/src/agent_cmdu.c b/src/agent_cmdu.c index de97f9ba2e68b37ff8e32b914ee7948fa88c4273..e07cf7c2a603cf6f197fa6cf24dddc71a8dccabc 100644 --- a/src/agent_cmdu.c +++ b/src/agent_cmdu.c @@ -947,7 +947,8 @@ static int agent_gen_ch_scan_response_opc(struct agent *a, op->opclass, ch->channel, ch->num_neighbors); for (k = 0; k < ch->num_neighbors; k++) { struct wifi_scanres_neighbor_element *nbr = ch->nbrlist + k; - trace("trace \tneigh " MACFMT " ssid %s\n", MAC2STR(nbr->bssid), nbr->ssid); + trace("trace \tneigh " MACFMT " ssid %s\n", + MAC2STR(nbr->bssid), nbr->ssid); } } @@ -1023,14 +1024,48 @@ error: return NULL; } +#if (EASYMESH_VERSION >= 6) +#define MAX_NUM_MLD_STRUCT 16 +/* TODO: update srmld properly */ +void agent_update_srmld(struct wifi_scan_res_mld_struct *srmld, + int *num_mld_struct, uint8_t *mld_mac, uint8_t *aff_mac) +{ + dbg("%s --->\n", __func__); + + int i; + + /* Lookup mld_mac (key) in smrld */ + for (i = 0; i < *num_mld_struct; i++) { + if (!memcmp(srmld[i].mld_macaddr, mld_mac, 6)) + break; + } + + /* Add affiliated mac in table for found key */ + if (*num_mld_struct < MAX_NUM_MLD_STRUCT && i == *num_mld_struct) { + int n_aff = srmld[i].num_affiliated; + + memcpy(srmld[i].mld_macaddr, mld_mac, 6); + memcpy(srmld[i].affiliated_mac[n_aff], aff_mac, 6); + srmld[i].num_affiliated++; + *num_mld_struct += 1; + } +} +#endif + struct cmdu_buff *agent_gen_ch_scan_response_radio(struct agent *a, struct wifi_radio_element *re, struct wifi_scan_request_radio *req, uint8_t status) { trace("%s --->\n", __func__); - int i, ret; struct cmdu_buff *cmdu_data; /* The response cmdu */ + int i, ret; +#if (EASYMESH_VERSION >= 6) + struct wifi_scan_res_mld_struct srmld[MAX_NUM_MLD_STRUCT]; + struct wifi_scanres_element *sl; + int num_mld_struct = 0; + int j; +#endif if (WARN_ON(!req)) return NULL; @@ -1081,6 +1116,62 @@ struct cmdu_buff *agent_gen_ch_scan_response_radio(struct agent *a, goto free_cmdu; /* err */ } +#if (EASYMESH_VERSION >= 6) + sl = re->scanlist; + if (!sl) + goto free_cmdu; /* err */ + + for (j = 0; j < sl->num_opclass; j++) { + struct wifi_scanres_opclass_element *op; + int k; + + op = sl->opclass_scanlist + j; + if (!op) + continue; + + for (k = 0; k < op->num_channels; k++) { + struct wifi_scanres_channel_element *ch; + int l; + + ch = op->channel_scanlist + k; + if (!ch) + continue; + + dbg("%s: opclass %d, channel %d, num_neighbors %d\n", + __func__, op->opclass, + ch->channel, ch->num_neighbors); + + for (l = 0; l < ch->num_neighbors; l++) { + struct wifi_scanres_neighbor_element *nbr + = ch->nbrlist + l; + + if (!nbr) + continue; + + dbg("%s: neigh " MACFMT " mld_link_id %d\ + mld_macaddr " MACFMT "\n", + __func__, MAC2STR(nbr->bssid), + nbr->mld_link_id, MAC2STR(nbr->mld_macaddr)); + + agent_update_srmld(srmld, &num_mld_struct, + nbr->mld_macaddr, nbr->bssid); + + if (num_mld_struct >= MAX_NUM_MLD_STRUCT) + goto put_mld_structure; + } + } + } + +put_mld_structure: + for (i = 0; i < num_mld_struct; i++) { + ret = agent_gen_mld_structure(a, cmdu_data, &srmld[i]); + if (ret) { + dbg("%s: failed to gen MLD structure\n", __func__); + goto free_cmdu; /* err */ + } + } +#endif + put_tlv: cmdu_put_eom(cmdu_data); return cmdu_data; diff --git a/src/agent_tlv.c b/src/agent_tlv.c index 40979f9fee433c0fffbcb565897720f587c53c05..746b7da2f22219f38aee0389eef49f5da2a41b55 100644 --- a/src/agent_tlv.c +++ b/src/agent_tlv.c @@ -4935,4 +4935,51 @@ int agent_gen_associated_sta_mld_config(struct agent *a, struct cmdu_buff *frm, return 0; } + +int agent_gen_mld_structure(struct agent *a, struct cmdu_buff *frm, + struct wifi_scan_res_mld_struct *srmld) +{ + trace("%s ---->\n", __func__); + + struct tlv_mld_structure *data; + struct tlv *t; + int offset = 0; + int ret; + int i; + + t = cmdu_reserve_tlv(frm, 256); + if (!t) + return -1; + + t->type = MAP_TLV_MLD_STRUCTURE; + data = (struct tlv_mld_structure *)t->data; + + /* MLD_MAC_Addr */ + memcpy(data->mld_macaddr, srmld->mld_macaddr, 6); + offset += 6; + offset += 25; /* rsvd = 25 */ + + /* Num_Affiliated */ + data->num_affiliated = srmld->num_affiliated; + offset += 1; + + for (i = 0; i < srmld->num_affiliated; i++) { + struct _mld_structure_affiliated *aff = &data->affiliated[i]; + + /* Affiliated_MAC_Addr */ + memcpy(aff->macaddr, &srmld->affiliated_mac[i], 6); + offset += 6; + offset += 26; /* Reserved */ + } + + t->len = offset; + + ret = cmdu_put_tlv(frm, t); + if (ret) { + err("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; +} #endif diff --git a/src/agent_tlv.h b/src/agent_tlv.h index 5ca39f6bdbc719562b974d3f63a6482e46df9955..ae97cd6be0071c6fe25bf20781869d66ab713f01 100644 --- a/src/agent_tlv.h +++ b/src/agent_tlv.h @@ -71,6 +71,15 @@ struct tlv_vendor_probe_req { #endif +#if (EASYMESH_VERSION >= 6) +#define MAX_AFFILIATED_AP_LINKS_NUM 14 +struct wifi_scan_res_mld_struct { + uint8_t mld_macaddr[6]; + uint8_t num_affiliated; + uint8_t affiliated_mac[MAX_AFFILIATED_AP_LINKS_NUM][6]; +}; +#endif + int get_radio_index(struct agent *a, uint8_t *mac); int get_bss_index(struct wifi_radio_element *radio, uint8_t *bssid); int get_radio_and_bss_index(struct agent *a, uint8_t *bssid, int *radio_index); @@ -256,9 +265,11 @@ int agent_gen_eht_operations(struct agent *a, struct cmdu_buff *frm); int agent_gen_affiliated_ap_metrics(struct agent *a, struct cmdu_buff *frm, struct wifi_bss_element *bss); int agent_gen_affiliated_sta_metrics(struct agent *a, struct cmdu_buff *frm, - struct sta *s); + struct sta *s); int agent_gen_associated_sta_mld_config(struct agent *a, struct cmdu_buff *frm, - struct sta_mld *s); + struct sta_mld *s); +int agent_gen_mld_structure(struct agent *a, struct cmdu_buff *frm, + struct wifi_scan_res_mld_struct *srmld); #endif #ifdef EASYMESH_VENDOR_EXT diff --git a/src/agent_ubus_dbg.c b/src/agent_ubus_dbg.c index d7a11b675f0cd20671684fd701b5b4933b951fd2..281c5437f3783f7d6c2a25a297da8238049bd578 100644 --- a/src/agent_ubus_dbg.c +++ b/src/agent_ubus_dbg.c @@ -407,6 +407,14 @@ static int dbg_wifi_radio_scanresults(struct ubus_context *ctx, struct ubus_obje blobmsg_add_u32(&bb, "load_stas", bss[i].load.sta_count); blobmsg_add_u32(&bb, "load_utilization", bss[i].load.utilization); +#if (EASYMESH_VERSION >= 6) + if (bss[i].mlo_link_id != WIFI_MLO_INVALID_LINK_ID) { + char mld_macaddrstr[18] = {}; + + hwaddr_ntoa(bss[i].mld_macaddr, mld_macaddrstr); + blobmsg_add_string(&bb, "mld_macaddr", mld_macaddrstr); + } +#endif blobmsg_close_table(&bb, t); } blobmsg_close_array(&bb, a); /* accesspoints */