diff --git a/include/wifi_base.h b/include/wifi_base.h index def0ede47..2333c09fb 100644 --- a/include/wifi_base.h +++ b/include/wifi_base.h @@ -1503,6 +1503,16 @@ typedef struct { mac_address_t sta_mac; } client_assoc_ctrl_req_t; +// Disassociation parameters sent from em_agent to OneWifi via bus +// Must match em_disassoc_params_t in em_base.h +typedef struct { + mac_address_t sta_mac; + bssid_t bssid; + unsigned int disassoc_time; + unsigned int reason; + bool silent; +} __attribute__((__packed__)) disassoc_params_t; + typedef struct { bssid_t bssid; ssid_t ssid; diff --git a/source/apps/em/wifi_em.c b/source/apps/em/wifi_em.c index 7e5254255..c9e692f73 100644 --- a/source/apps/em/wifi_em.c +++ b/source/apps/em/wifi_em.c @@ -144,6 +144,34 @@ static int em_get_radio_index_from_mac(mac_addr_t ruuid) return RETURN_ERR; } +static int em_get_vap_index_from_bssid(mac_addr_t bssid) +{ + unsigned int num_of_radios = getNumberRadios(); + wifi_vap_info_map_t *vap_map; + mac_addr_str_t bssid_str; + + to_mac_str(bssid, bssid_str); + + for (unsigned int i = 0; i < num_of_radios; i++) { + vap_map = (wifi_vap_info_map_t *)get_wifidb_vap_map(i); + if (vap_map == NULL) { + continue; + } + for (unsigned int j = 0; j < (unsigned int)vap_map->num_vaps; j++) { + if (memcmp(bssid, vap_map->vap_array[j].u.bss_info.bssid, sizeof(mac_addr_t)) == 0) { + wifi_util_dbg_print(WIFI_EM, "%s:%d vap_index=%d found for BSSID=%s\n", + __func__, __LINE__, vap_map->vap_array[j].vap_index, bssid_str); + return (int)vap_map->vap_array[j].vap_index; + } + } + } + + wifi_util_error_print(WIFI_EM, "%s:%d vap_index not found for BSSID=%s\n", + __func__, __LINE__, bssid_str); + + return RETURN_ERR; +} + static int em_match_radio_index_to_policy_index(radio_metrics_policies_t *radio_metrics_policies, int radio_index) { @@ -3202,6 +3230,66 @@ static bus_error_t controller_set_client_acl_rules(char *event_name, raw_data_t return ret; } +static bus_error_t easymesh_disassoc_client_handler(char *event_name, raw_data_t *p_data, bus_user_data_t *userData) +{ + (void)userData; + disassoc_params_t *disassoc_param; + int vap_index; + mac_addr_str_t sta_mac_str; + mac_addr_str_t bssid_str; + + wifi_util_info_print(WIFI_EM, "%s:%d Received DisassocClient event from Agent\n", + __func__, __LINE__); + + if (event_name == NULL || strcmp(event_name, WIFI_EM_DISASSOC_CLIENT) != 0) { + wifi_util_error_print(WIFI_EM, "%s:%d Unexpected event: %s\n", + __func__, __LINE__, event_name ? event_name : "(null)"); + return bus_error_invalid_namespace; + } + + if (p_data == NULL || p_data->data_type != bus_data_type_bytes || + p_data->raw_data.bytes == NULL || + p_data->raw_data_len < sizeof(disassoc_params_t)) { + wifi_util_error_print(WIFI_EM, "%s:%d Invalid data: type=%d len=%u\n", + __func__, __LINE__, + p_data ? p_data->data_type : -1, + p_data ? p_data->raw_data_len : 0); + return bus_error_invalid_input; + } + + disassoc_param = (disassoc_params_t *)p_data->raw_data.bytes; + + to_mac_str(disassoc_param->sta_mac, sta_mac_str); + to_mac_str(disassoc_param->bssid, bssid_str); + + wifi_util_info_print(WIFI_EM, + "%s:%d DisassocClient STA=%s BSSID=%s reason=%u silent=%d\n", + __func__, __LINE__, sta_mac_str, bssid_str, disassoc_param->reason, disassoc_param->silent); + + if (disassoc_param->silent) { + wifi_util_info_print(WIFI_EM, + "%s:%d Silent disassoc requested for STA=%s, skipping HAL call\n", + __func__, __LINE__, sta_mac_str); + return bus_error_success; + } + + vap_index = em_get_vap_index_from_bssid(disassoc_param->bssid); + if (vap_index < 0) { + wifi_util_error_print(WIFI_EM, + "%s:%d Could not resolve vap_index for BSSID=%s\n", + __func__, __LINE__, bssid_str); + return bus_error_invalid_input; + } + + wifi_hal_disassoc(vap_index, (int)disassoc_param->reason, disassoc_param->sta_mac); + + wifi_util_info_print(WIFI_EM, + "%s:%d Successfully disassociated STA=%s from BSSID=%s (vap=%d)\n", + __func__, __LINE__, sta_mac_str, bssid_str, vap_index); + + return bus_error_success; +} + bus_error_t set_disconn_steady_state(char *name, raw_data_t *p_data, bus_user_data_t *user_data) { (void)p_data; @@ -3290,7 +3378,10 @@ int em_init(wifi_app_t *app, unsigned int create_flag) { bus_data_type_string, false, 0, 0, 0, NULL } }, { WIFI_EM_FAILED_CONNECTION, bus_element_type_event, { NULL, NULL, NULL, NULL, NULL, NULL }, slow_speed, ZERO_TABLE, - { bus_data_type_string, false, 0, 0, 0, NULL } } + { bus_data_type_string, false, 0, 0, 0, NULL } }, + { WIFI_EM_DISASSOC_CLIENT, bus_element_type_method, + { NULL, easymesh_disassoc_client_handler, NULL, NULL, NULL, NULL }, slow_speed, ZERO_TABLE, + { bus_data_type_bytes, false, 0, 0, 0, NULL } } }; policy_config->btm_steering_dslw_policy.sta_count = 0; diff --git a/source/apps/em/wifi_em.h b/source/apps/em/wifi_em.h index 43419ec49..1b9b39422 100644 --- a/source/apps/em/wifi_em.h +++ b/source/apps/em/wifi_em.h @@ -49,6 +49,7 @@ extern "C" { #define MAX_LOCAL_SSIDS 16 #define MAX_SSID_LEN 33 +#define WIFI_EM_DISASSOC_CLIENT "Device.WiFi.EM.DisassocClient" typedef struct wifi_app wifi_app_t;