1 /**
2 * Copyright 2023-2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "includes.h"
8 #include "common.h"
9 #include "ap/sta_info.h"
10 #include "ap/ieee802_11.h"
11 #include "ap/hostapd.h"
12 #include "wpa_supplicant_i.h"
13 #include <zephyr/net/wifi_mgmt.h>
14 #include "hapd_events.h"
15 #include "supp_events.h"
16
hapd_get_sta_link_mode(struct hostapd_iface * iface,struct sta_info * sta)17 static enum wifi_link_mode hapd_get_sta_link_mode(struct hostapd_iface *iface,
18 struct sta_info *sta)
19 {
20 if (sta->flags & WLAN_STA_HE) {
21 return WIFI_6;
22 } else if (sta->flags & WLAN_STA_VHT) {
23 return WIFI_5;
24 } else if (sta->flags & WLAN_STA_HT) {
25 return WIFI_4;
26 } else if ((sta->flags & WLAN_STA_NONERP) ||
27 (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B)) {
28 return WIFI_1;
29 } else if (iface->freq > 4000) {
30 return WIFI_2;
31 } else if (iface->freq > 2000) {
32 return WIFI_3;
33 } else {
34 return WIFI_LINK_MODE_UNKNOWN;
35 }
36 }
37
38 #define HE_MACCAP_TWT_REQUESTER BIT(1)
39
hapd_get_sta_he_twt_capable(struct hostapd_iface * iface,struct sta_info * sta)40 static bool hapd_get_sta_he_twt_capable(struct hostapd_iface *iface, struct sta_info *sta)
41 {
42 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
43 if (sta->flags & WLAN_STA_HE) {
44 return (sta->he_capab->he_mac_capab_info[0]
45 & HE_MACCAP_TWT_REQUESTER ? true : false);
46 } else {
47 return false;
48 }
49 #else
50 return false;
51 #endif
52 }
53
hostapd_send_wifi_mgmt_ap_status(struct hostapd_iface * iface,enum net_event_wifi_cmd event,enum wifi_ap_status ap_status)54 int hostapd_send_wifi_mgmt_ap_status(struct hostapd_iface *iface,
55 enum net_event_wifi_cmd event,
56 enum wifi_ap_status ap_status)
57 {
58 char *ifname = iface->conf->bss[0]->iface;
59 int status = ap_status;
60
61 return supplicant_send_wifi_mgmt_event(ifname,
62 event,
63 (void *)&status,
64 sizeof(int));
65 }
66
hostapd_send_wifi_mgmt_ap_sta_event(struct hostapd_iface * ap_ctx,enum net_event_wifi_cmd event,void * data)67 int hostapd_send_wifi_mgmt_ap_sta_event(struct hostapd_iface *ap_ctx,
68 enum net_event_wifi_cmd event,
69 void *data)
70 {
71 struct sta_info *sta = data;
72 char *ifname;
73 struct wifi_ap_sta_info sta_info = { 0 };
74
75 if (!ap_ctx || !sta) {
76 return -EINVAL;
77 }
78
79 ifname = ap_ctx->bss[0]->conf->iface;
80
81 memcpy(sta_info.mac, sta->addr, sizeof(sta_info.mac));
82
83 if (event == NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) {
84 sta_info.link_mode = hapd_get_sta_link_mode(ap_ctx, sta);
85 sta_info.twt_capable = hapd_get_sta_he_twt_capable(ap_ctx, sta);
86 }
87
88 return supplicant_send_wifi_mgmt_event(ifname,
89 event,
90 (void *)&sta_info,
91 sizeof(sta_info));
92 }
93
94 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
hostapd_handle_dpp_event(void * ctx,char * buf,size_t len)95 void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len)
96 {
97 struct hostapd_data *hapd = (struct hostapd_data *)ctx;
98
99 if (hapd == NULL) {
100 return;
101 }
102
103 struct hostapd_bss_config *conf = hapd->conf;
104
105 if (conf == NULL || !(conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP)) {
106 return;
107 }
108
109 /* check hostapd */
110 if (!strncmp(buf, DPP_EVENT_CONNECTOR, sizeof(DPP_EVENT_CONNECTOR) - 1)) {
111 if (conf->dpp_connector) {
112 os_free(conf->dpp_connector);
113 }
114
115 conf->dpp_connector = os_strdup(buf + sizeof(DPP_EVENT_CONNECTOR) - 1);
116 } else if (!strncmp(buf, DPP_EVENT_C_SIGN_KEY, sizeof(DPP_EVENT_C_SIGN_KEY) - 1)) {
117 if (conf->dpp_csign) {
118 wpabuf_free(conf->dpp_csign);
119 }
120
121 conf->dpp_csign = wpabuf_parse_bin(buf + sizeof(DPP_EVENT_C_SIGN_KEY) - 1);
122 } else if (!strncmp(buf, DPP_EVENT_NET_ACCESS_KEY, sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1)) {
123 if (conf->dpp_netaccesskey) {
124 wpabuf_free(conf->dpp_netaccesskey);
125 }
126
127 conf->dpp_netaccesskey =
128 wpabuf_parse_bin(buf + sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1);
129 }
130 }
131 #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
132