diff --git a/src/agent.c b/src/agent.c index a2bf644994aee5bd7bf42055519949a8a1e24181..8466fa6b942396d9eb359e6e6d8526087a21ee1a 100644 --- a/src/agent.c +++ b/src/agent.c @@ -3700,9 +3700,21 @@ static void wifi_radio_event_handler(void *c, struct blob_attr *msg) timer_set(&a->init_ifaces_scheduler, IFACE_TIMEOUT * 1000); } else if (!strcmp(event, "radar")) { + struct wifi_radio_element *re; struct cmdu_buff *cmdu; + uint16_t mid = 0; + + re = agent_get_radio_with_ifname(a, ifname); + if (!re) { +#if (EASYMESH_VERSION >= 6) + /* Fallback to 5GHz */ + re = agent_get_radio_by_band(a, BAND_5); + if (!re) +#endif + return; + } - cmdu = agent_gen_channel_preference_report(a, NULL); + cmdu = agent_gen_channel_preference_report(a, mid, a->cntlr_almac, re->macaddr); if (cmdu) { agent_send_cmdu(a, cmdu); cmdu_free(cmdu); @@ -4082,8 +4094,9 @@ static void preference_report_timer_cb(atimer_t *t) struct wifi_radio_element *re = container_of(t, struct wifi_radio_element, preference_report_timer); struct cmdu_buff *cmdu; + uint32_t mid = 0; - cmdu = agent_gen_channel_preference_report(re->agent, NULL); + cmdu = agent_gen_channel_preference_report(re->agent, mid, re->agent->cntlr_almac, re->macaddr); if (cmdu) { agent_send_cmdu(re->agent, cmdu); cmdu_free(cmdu); diff --git a/src/agent_cmdu.c b/src/agent_cmdu.c index 4d4d580be62145ed35c2e92d4f86dd7766e4168b..0ee7565100a20f70ec68e67bb73a0f9afc756207 100644 --- a/src/agent_cmdu.c +++ b/src/agent_cmdu.c @@ -1541,16 +1541,14 @@ out: } struct cmdu_buff *agent_gen_channel_preference_report(struct agent *a, - struct cmdu_buff *rx_cmdu) + uint16_t mid, + uint8_t *origin, + uint8_t *radioid) { struct wifi_radio_element *re = NULL; struct cmdu_buff *frm, *ext; - uint16_t mid = 0; int ret; - if (rx_cmdu) - mid = cmdu_get_mid(rx_cmdu); - frm = cmdu_alloc_simple(CMDU_CHANNEL_PREFERENCE_REPORT, &mid); if (!frm) { dbg("%s: -ENOMEM\n", __func__); @@ -1567,12 +1565,15 @@ struct cmdu_buff *agent_gen_channel_preference_report(struct agent *a, frm = ext; } - if (rx_cmdu) - memcpy(frm->origin, rx_cmdu->origin, 6); + if (origin) + memcpy(frm->origin, origin, 6); else memcpy(frm->origin, a->cntlr_almac, 6); list_for_each_entry(re, &a->radiolist, list) { + if (radioid && memcmp(re->macaddr, radioid, 6)) + continue; + /* Channel Preference TLV */ ret = agent_gen_channel_pref(a, frm, re); if (ret) @@ -1594,12 +1595,12 @@ struct cmdu_buff *agent_gen_channel_preference_report(struct agent *a, //#ifdef PROFILE2 /* CAC Completion Report TLV */ - ret = agent_gen_cac_complete_report(a, frm); + ret = agent_gen_cac_complete_report(a, frm, radioid); if (ret) goto error; /* CAC Status Report TLV */ - ret = agent_gen_cac_status_report(a, frm); + ret = agent_gen_cac_status_report(a, frm, radioid); if (ret) goto error; //#endif diff --git a/src/agent_cmdu.h b/src/agent_cmdu.h index fd100dc763bacceca911a29862d190fa9d79b2cc..b2a8d3198cba28565a693493ce19f1ba89f10047 100644 --- a/src/agent_cmdu.h +++ b/src/agent_cmdu.h @@ -83,7 +83,9 @@ struct cmdu_buff *agent_gen_link_metric_response(struct agent *a, struct cmdu_buff *agent_gen_client_disassoc(struct agent *a, struct sta *s, uint8_t *bssid, uint16_t reason); struct cmdu_buff *agent_gen_channel_preference_report(struct agent *a, - struct cmdu_buff *rx_cmdu); + uint16_t mid, + uint8_t *origin, + uint8_t *radioid); struct cmdu_buff *agent_gen_association_status_notify(struct agent *a, int num_data, void *data); struct cmdu_buff *agent_gen_sta_caps_response(struct agent *a, diff --git a/src/agent_map.c b/src/agent_map.c index dd1cc0ccef7dd7f442e757d6ef94d5676d41c6f0..8d0ebc228242bf3ac768ba5453aefdc0dc09cffd 100644 --- a/src/agent_map.c +++ b/src/agent_map.c @@ -3429,9 +3429,11 @@ int handle_channel_pref_query(void *agent, struct cmdu_buff *rx_cmdu, trace("%s: --->\n", __func__); struct agent *a = (struct agent *)agent; struct cmdu_buff *cmdu; + uint16_t mid; int ret; - cmdu = agent_gen_channel_preference_report(a, rx_cmdu); + mid = cmdu_get_mid(rx_cmdu); + cmdu = agent_gen_channel_preference_report(a, mid, rx_cmdu->origin, NULL); if (!cmdu) return -1; @@ -5648,6 +5650,7 @@ int wifi_radio_update_opclass_preferences(struct agent *a, struct wifi_radio_ele struct wifi_radio_opclass opclass = {}; int send_pref_report = 0; struct cmdu_buff *cmdu; + uint16_t mid = 0; int ret; if (WARN_ON(wifi_opclass_preferences(re->name, &opclass))) { @@ -5672,8 +5675,7 @@ int wifi_radio_update_opclass_preferences(struct agent *a, struct wifi_radio_ele if (!send_pref_report) return 0; - /* TODO send this for single radio element */ - cmdu = agent_gen_channel_preference_report(a, NULL); + cmdu = agent_gen_channel_preference_report(a, mid, a->cntlr_almac, re->macaddr); if (WARN_ON(!cmdu)) return 0; diff --git a/src/agent_tlv.c b/src/agent_tlv.c index 7a719da7855e556d7ebe28ae43d2d20a8b98a14a..d22fe4ef83a81115ecc1c7e5244035d4bbbc0946 100644 --- a/src/agent_tlv.c +++ b/src/agent_tlv.c @@ -912,7 +912,7 @@ int agent_gen_radio_oper_restrict(struct agent *a, struct cmdu_buff *frm, return 0; } -int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm) +int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm, uint8_t *radioid) { struct wifi_radio_element *re = NULL; uint8_t *num_radios_ptr; @@ -932,6 +932,9 @@ int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm) list_for_each_entry(re, &a->radiolist, list) { struct wifi_radio_opclass_channel *channel; + if (radioid && memcmp(re->macaddr, radioid, 6)) + continue; + /* Check if cac requested */ if (!re->cac_request.channel && !re->cac_request.report_failed) @@ -1046,7 +1049,7 @@ int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm) return 0; } -int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm) +int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm, uint8_t *radioid) { struct wifi_radio_opclass_channel *chan; struct wifi_radio_opclass_entry *entry; @@ -1078,6 +1081,9 @@ int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm) //if (!wifi_opclass_dfs_supported(opclass)) // continue; + if (radioid && memcmp(re->macaddr, radioid, 6)) + continue; + for (i = 0; i < opclass->entry_num; i++) { entry = &opclass->entry[i]; @@ -1113,6 +1119,9 @@ int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm) list_for_each_entry(re, &a->radiolist, list) { opclass = &re->opclass; + if (radioid && memcmp(re->macaddr, radioid, 6)) + continue; + if (!wifi_opclass_dfs_supported(opclass)) continue; @@ -1150,6 +1159,9 @@ int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm) list_for_each_entry(re, &a->radiolist, list) { opclass = &re->opclass; + if (radioid && memcmp(re->macaddr, radioid, 6)) + continue; + if (!wifi_opclass_dfs_supported(opclass)) continue; diff --git a/src/agent_tlv.h b/src/agent_tlv.h index 200cb8c9edb4b703dff4151e7e96e185d231459e..4a3223bbd8a264869765879b1a36c1297147e023 100644 --- a/src/agent_tlv.h +++ b/src/agent_tlv.h @@ -76,8 +76,8 @@ int agent_gen_channel_pref(struct agent *a, struct cmdu_buff *frm, struct wifi_radio_element *re); int agent_gen_radio_oper_restrict(struct agent *a, struct cmdu_buff *frm, struct wifi_radio_element *re); -int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm); -int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm); +int agent_gen_cac_complete_report(struct agent *a, struct cmdu_buff *frm, uint8_t *radioid); +int agent_gen_cac_status_report(struct agent *a, struct cmdu_buff *frm, uint8_t *radioid); int agent_gen_tlv_error_code(struct agent *a, struct cmdu_buff *cmdu, uint8_t *macaddr, uint8_t reason_code); int agent_gen_steer_btm_report(struct agent *a, struct cmdu_buff *frm,