From ec2b5173cedd8582f177395642a13cabfe9ce50e Mon Sep 17 00:00:00 2001 From: Tamizh chelvam Date: Fri, 9 Mar 2018 18:19:09 +0530 Subject: [PATCH] Make STA opmode change event available to upper layers Add an event callback for EVENT_STATION_OPMODE_CHANGED to allow user/application to get the notification whenever there is a change in a station's HT/VHT op mode. The new events: STA-OPMODE-MAX-BW-CHANGED <20(no-HT)|20|40|80|80+80|160> STA-OPMODE-SMPS-MODE-CHANGED STA-OPMODE-N_SS-CHANGED Signed-off-by: Tamizh chelvam --- src/ap/drv_callbacks.c | 73 +++++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.h | 3 ++ src/common/wpa_ctrl.h | 5 +++ wpa_supplicant/events.c | 12 +++++++ 4 files changed, 93 insertions(+) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index e4a458107..f0d6a4ccb 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -653,6 +653,73 @@ void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) } +void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr, + enum smps_mode smps_mode, + enum chan_width chan_width, u8 rx_nss) +{ + struct sta_info *sta = ap_get_sta(hapd, addr); + const char *txt; + + if (!sta) + return; + + switch (smps_mode) { + case SMPS_AUTOMATIC: + txt = "automatic"; + break; + case SMPS_OFF: + txt = "off"; + break; + case SMPS_DYNAMIC: + txt = "dynamic"; + break; + case SMPS_STATIC: + txt = "static"; + break; + default: + txt = NULL; + break; + } + if (txt) { + wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_SMPS_MODE_CHANGED + MACSTR " %s", MAC2STR(addr), txt); + } + + switch (chan_width) { + case CHAN_WIDTH_20_NOHT: + txt = "20(no-HT)"; + break; + case CHAN_WIDTH_20: + txt = "20"; + break; + case CHAN_WIDTH_40: + txt = "40"; + break; + case CHAN_WIDTH_80: + txt = "80"; + break; + case CHAN_WIDTH_80P80: + txt = "80+80"; + break; + case CHAN_WIDTH_160: + txt = "160"; + break; + default: + txt = NULL; + break; + } + if (txt) { + wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_MAX_BW_CHANGED + MACSTR " %s", MAC2STR(addr), txt); + } + + if (rx_nss != 0xff) { + wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_N_SS_CHANGED + MACSTR " %d", MAC2STR(addr), rx_nss); + } +} + + void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2) { @@ -1614,6 +1681,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, &data->acs_selected_channels); break; #endif /* CONFIG_ACS */ + case EVENT_STATION_OPMODE_CHANGED: + hostapd_event_sta_opmode_changed(hapd, data->sta_opmode.addr, + data->sta_opmode.smps_mode, + data->sta_opmode.chan_width, + data->sta_opmode.rx_nss); + break; default: wpa_printf(MSG_DEBUG, "Unknown event %d", event); break; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 53d0f9a9a..7743acf25 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -608,6 +608,9 @@ hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity, struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces, const char *ifname); +void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr, + enum smps_mode smps_mode, + enum chan_width chan_width, u8 rx_nss); #ifdef CONFIG_FST void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index c369ebb24..df4564b78 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -345,6 +345,11 @@ extern "C" { * parameters: sa= signal= */ #define RX_PROBE_REQUEST "RX-PROBE-REQUEST " +/* Event to indicate station's HT/VHT operation mode change information */ +#define STA_OPMODE_MAX_BW_CHANGED "STA-OPMODE-MAX-BW-CHANGED " +#define STA_OPMODE_SMPS_MODE_CHANGED "STA-OPMODE-SMPS-MODE-CHANGED " +#define STA_OPMODE_N_SS_CHANGED "STA-OPMODE-N_SS-CHANGED " + /* BSS command information masks */ #define WPA_BSS_MASK_ALL 0xFFFDFFFF diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 398f4f2f3..5a61e1714 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -4609,6 +4609,18 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, case EVENT_PORT_AUTHORIZED: wpa_supplicant_event_port_authorized(wpa_s); break; + case EVENT_STATION_OPMODE_CHANGED: +#ifdef CONFIG_AP + if (!wpa_s->ap_iface || !data) + break; + + hostapd_event_sta_opmode_changed(wpa_s->ap_iface->bss[0], + data->sta_opmode.addr, + data->sta_opmode.smps_mode, + data->sta_opmode.chan_width, + data->sta_opmode.rx_nss); +#endif /* CONFIG_AP */ + break; default: wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event); break;