/** * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include "includes.h" #include "common.h" #include "ap/sta_info.h" #include "ap/ieee802_11.h" #include "ap/hostapd.h" #include "wpa_supplicant_i.h" #include #include "hapd_events.h" #include "supp_events.h" static enum wifi_link_mode hapd_get_sta_link_mode(struct hostapd_iface *iface, struct sta_info *sta) { if (sta->flags & WLAN_STA_HE) { return WIFI_6; } else if (sta->flags & WLAN_STA_VHT) { return WIFI_5; } else if (sta->flags & WLAN_STA_HT) { return WIFI_4; } else if ((sta->flags & WLAN_STA_NONERP) || (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B)) { return WIFI_1; } else if (iface->freq > 4000) { return WIFI_2; } else if (iface->freq > 2000) { return WIFI_3; } else { return WIFI_LINK_MODE_UNKNOWN; } } #define HE_MACCAP_TWT_REQUESTER BIT(1) static bool hapd_get_sta_he_twt_capable(struct hostapd_iface *iface, struct sta_info *sta) { #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX if (sta->flags & WLAN_STA_HE) { return (sta->he_capab->he_mac_capab_info[0] & HE_MACCAP_TWT_REQUESTER ? true : false); } else { return false; } #else return false; #endif } int hostapd_send_wifi_mgmt_ap_status(struct hostapd_iface *iface, enum net_event_wifi_cmd event, enum wifi_ap_status ap_status) { char *ifname = iface->conf->bss[0]->iface; int status = ap_status; return supplicant_send_wifi_mgmt_event(ifname, event, (void *)&status, sizeof(int)); } int hostapd_send_wifi_mgmt_ap_sta_event(struct hostapd_iface *ap_ctx, enum net_event_wifi_cmd event, void *data) { struct sta_info *sta = data; char *ifname; struct wifi_ap_sta_info sta_info = { 0 }; if (!ap_ctx || !sta) { return -EINVAL; } ifname = ap_ctx->bss[0]->conf->iface; memcpy(sta_info.mac, sta->addr, sizeof(sta_info.mac)); if (event == NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) { sta_info.link_mode = hapd_get_sta_link_mode(ap_ctx, sta); sta_info.twt_capable = hapd_get_sta_he_twt_capable(ap_ctx, sta); } return supplicant_send_wifi_mgmt_event(ifname, event, (void *)&sta_info, sizeof(sta_info)); } #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len) { struct hostapd_data *hapd = (struct hostapd_data *)ctx; if (hapd == NULL) { return; } struct hostapd_bss_config *conf = hapd->conf; if (conf == NULL || !(conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP)) { return; } /* check hostapd */ if (!strncmp(buf, DPP_EVENT_CONNECTOR, sizeof(DPP_EVENT_CONNECTOR) - 1)) { if (conf->dpp_connector) { os_free(conf->dpp_connector); } conf->dpp_connector = os_strdup(buf + sizeof(DPP_EVENT_CONNECTOR) - 1); } else if (!strncmp(buf, DPP_EVENT_C_SIGN_KEY, sizeof(DPP_EVENT_C_SIGN_KEY) - 1)) { if (conf->dpp_csign) { wpabuf_free(conf->dpp_csign); } conf->dpp_csign = wpabuf_parse_bin(buf + sizeof(DPP_EVENT_C_SIGN_KEY) - 1); } else if (!strncmp(buf, DPP_EVENT_NET_ACCESS_KEY, sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1)) { if (conf->dpp_netaccesskey) { wpabuf_free(conf->dpp_netaccesskey); } conf->dpp_netaccesskey = wpabuf_parse_bin(buf + sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1); } } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */