blob: c71015f7f9209decc8b3dfdea590dde3d481699a [file] [log] [blame]
/**
* 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 <zephyr/net/wifi_mgmt.h>
#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;
}
}
static bool hapd_is_twt_capable(struct hostapd_iface *iface, struct sta_info *sta)
{
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
return hostapd_get_he_twt_responder(iface->bss[0], IEEE80211_MODE_AP);
#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 = ap_ctx->bss[0]->conf->iface;
struct wifi_ap_sta_info sta_info = { 0 };
if (!ap_ctx || !sta) {
return -EINVAL;
}
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_is_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 */