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