1 /*
2  * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "utils/includes.h"
8 #include "utils/common.h"
9 #include "esp_event.h"
10 #include "esp_wifi.h"
11 #include "esp_wifi_types.h"
12 #include "esp_wifi_driver.h"
13 #include "drivers/driver.h"
14 #include "common/bss.h"
15 #include "common/rrm.h"
16 #include "common/wnm_sta.h"
17 #include "common/wpa_supplicant_i.h"
18 #include "esp_scan_i.h"
19 #include "esp_common_i.h"
20 #include "common/ieee802_11_common.h"
21 #include "esp_rrm.h"
22 #include "esp_wnm.h"
23 
24 struct wpa_supplicant g_wpa_supp;
25 
26 static void *s_supplicant_task_hdl = NULL;
27 static void *s_supplicant_evt_queue = NULL;
28 static void *s_supplicant_api_lock = NULL;
29 
handle_action_frm(u8 * frame,size_t len,u8 * sender,u32 rssi,u8 channel)30 static int handle_action_frm(u8 *frame, size_t len,
31 			     u8 *sender, u32 rssi, u8 channel)
32 {
33 	struct ieee_mgmt_frame *frm = os_malloc(sizeof(struct ieee_mgmt_frame) + len);
34 
35 	if (!frm) {
36 		wpa_printf(MSG_ERROR, "memory allocation failed");
37 		return -1;
38 	}
39 
40 	os_memcpy(frm->sender, sender, ETH_ALEN);
41 	frm->len = len;
42 	frm->channel = channel;
43 	frm->rssi = rssi;
44 
45 	os_memcpy(frm->payload, frame, len);
46 	if (esp_supplicant_post_evt(SIG_SUPPLICANT_RX_ACTION, (u32)frm) != 0) {
47 		os_free(frm);
48 		return -1;
49 	}
50 
51 	return 0;
52 }
53 
handle_rrm_frame(struct wpa_supplicant * wpa_s,u8 * sender,u8 * payload,size_t len,u32 rssi)54 static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender,
55 			     u8 *payload, size_t len, u32 rssi)
56 {
57 	if (payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
58 		/* neighbor report parsing */
59 		wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, len - 1);
60 	} else if (payload[0] == WLAN_RRM_RADIO_MEASUREMENT_REQUEST) {
61 		/* Beacon measurement */
62 		wpas_rrm_handle_radio_measurement_request(wpa_s, NULL,
63 				sender, payload + 1, len - 1);
64 	} else if (payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
65 		/* Link measurement */
66 		wpas_rrm_handle_link_measurement_request(wpa_s, NULL,
67 				payload + 1, len - 1, rssi);
68 	}
69 }
70 
mgmt_rx_action(u8 * sender,u8 * payload,size_t len,u8 channel,u32 rssi)71 static int mgmt_rx_action(u8 *sender, u8 *payload, size_t len, u8 channel, u32 rssi)
72 {
73 	u8 category;
74 	u8 bssid[ETH_ALEN];
75 	struct wpa_supplicant *wpa_s = &g_wpa_supp;
76 	int ret = esp_wifi_get_assoc_bssid_internal(bssid);
77 
78 	if (ret < 0) {
79 		wpa_printf(MSG_INFO, "STA not associated");
80 		return -1;
81 	}
82 
83 	category = *payload++;
84 	len--;
85 	if (category == WLAN_ACTION_WNM) {
86 		ieee802_11_rx_wnm_action(wpa_s, sender, payload, len);
87 	} else if (category == WLAN_ACTION_RADIO_MEASUREMENT) {
88 		handle_rrm_frame(wpa_s, sender, payload, len, rssi);
89 	}
90 
91 	return 0;
92 }
93 
btm_rrm_task(void * pvParameters)94 static void btm_rrm_task(void *pvParameters)
95 {
96 	supplicant_event_t *evt;
97 	bool task_del = false;
98 
99 	while(1) {
100 		if (xQueueReceive(s_supplicant_evt_queue, &evt, portMAX_DELAY) != pdTRUE)
101 			continue;
102 
103 		/* event validation failed */
104 		if (evt->id >= SIG_SUPPLICANT_MAX) {
105 			os_free(evt);
106 			continue;
107 		}
108 
109 		switch (evt->id) {
110 		case SIG_SUPPLICANT_RX_ACTION:
111 		{
112 			struct ieee_mgmt_frame *frm = (struct ieee_mgmt_frame *)evt->data;
113 			mgmt_rx_action(frm->sender, frm->payload, frm->len, frm->channel, frm->rssi);
114 			os_free(frm);
115 			break;
116 		}
117 
118 		case SIG_SUPPLICANT_SCAN_DONE:
119 			esp_supplicant_handle_scan_done_evt();
120 			break;
121 		case SIG_SUPPLICANT_DEL_TASK:
122 			task_del = true;
123 			break;
124 		default:
125 			break;
126 		}
127 
128 		os_free(evt);
129 
130 		if (task_del)
131 			break;
132 	}
133 
134 	vQueueDelete(s_supplicant_evt_queue);
135 	s_supplicant_evt_queue = NULL;
136 
137 	if (s_supplicant_api_lock) {
138 		vSemaphoreDelete(s_supplicant_api_lock);
139 		s_supplicant_api_lock = NULL;
140 	}
141 
142 	/* At this point, we completed */
143 	vTaskDelete(NULL);
144 }
145 
clear_bssid_flag(struct wpa_supplicant * wpa_s)146 static void clear_bssid_flag(struct wpa_supplicant *wpa_s)
147 {
148 	wifi_config_t *config;
149 
150 	/* Reset only if btm is enabled */
151 	if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA) == false)
152 		return;
153 
154 	config = os_zalloc(sizeof(wifi_config_t));
155 
156 	if (!config) {
157 		wpa_printf(MSG_ERROR, "failed to allocate memory");
158 		return;
159 	}
160 
161 	esp_wifi_get_config(WIFI_IF_STA, config);
162 	config->sta.bssid_set = 0;
163 	esp_wifi_set_config(WIFI_IF_STA, config);
164 	os_free(config);
165 	wpa_printf(MSG_DEBUG, "cleared bssid flag");
166 }
167 
register_action_frame(struct wpa_supplicant * wpa_s)168 static void register_action_frame(struct wpa_supplicant *wpa_s)
169 {
170 	wpa_s->type &= ~(1 << WLAN_FC_STYPE_ACTION);
171 	/* subtype is defined only for action frame */
172 	wpa_s->subtype = 0;
173 
174 	/* current supported features in supplicant: rrm and btm */
175 	if (esp_wifi_is_rm_enabled_internal(WIFI_IF_STA))
176 		wpa_s->subtype = 1 << WLAN_ACTION_RADIO_MEASUREMENT;
177 	if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA))
178 		wpa_s->subtype |= 1 << WLAN_ACTION_WNM;
179 
180 	if (wpa_s->subtype)
181 		wpa_s->type |= 1 << WLAN_FC_STYPE_ACTION;
182 
183 	esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
184 }
185 
supplicant_sta_conn_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)186 static void supplicant_sta_conn_handler(void* arg, esp_event_base_t event_base,
187 					int32_t event_id, void* event_data)
188 {
189 	u8 bssid[ETH_ALEN];
190 	u8 *ie;
191 	struct wpa_supplicant *wpa_s = &g_wpa_supp;
192 	int ret = esp_wifi_get_assoc_bssid_internal(bssid);
193 	if (ret < 0) {
194 		wpa_printf(MSG_ERROR, "Not able to get connected bssid");
195 		return;
196 	}
197 	struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, bssid);
198 	if (!bss) {
199 		wpa_printf(MSG_INFO, "connected bss entry not present in scan cache");
200 		return;
201 	}
202 	wpa_s->current_bss = bss;
203 	ie = (u8 *)bss;
204 	ie += sizeof(struct wpa_bss);
205 	ieee802_11_parse_elems(wpa_s, ie, bss->ie_len);
206 	wpa_bss_flush(wpa_s);
207 	/* Register for action frames */
208 	register_action_frame(wpa_s);
209 	/* clear set bssid flag */
210 	clear_bssid_flag(wpa_s);
211 }
212 
supplicant_sta_disconn_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)213 static void supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_base,
214 					   int32_t event_id, void* event_data)
215 {
216 	struct wpa_supplicant *wpa_s = &g_wpa_supp;
217 	wpas_rrm_reset(wpa_s);
218 	if (wpa_s->current_bss) {
219 		wpa_s->current_bss = NULL;
220 	}
221 }
222 
ieee80211_handle_rx_frm(u8 type,u8 * frame,size_t len,u8 * sender,u32 rssi,u8 channel,u64 current_tsf)223 static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
224 				   u32 rssi, u8 channel, u64 current_tsf)
225 {
226 	if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) {
227 		return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf);
228 	} else if (type ==  WLAN_FC_STYPE_ACTION) {
229 		return handle_action_frm(frame, len, sender, rssi, channel);
230 	}
231 
232 	return -1;
233 }
234 
235 #ifdef CONFIG_MBO
bss_profile_match(u8 * sender)236 static bool bss_profile_match(u8 *sender)
237 {
238 	/* Incase supplicant wants drivers to skip this BSS, return false */
239 	struct wpa_bss *bss = wpa_bss_get_bssid(&g_wpa_supp, sender);
240 	if (!bss) {
241 		return true;
242 	}
243 	const u8 *assoc_disallow = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_ASSOC_DISALLOW);
244 	if (assoc_disallow && assoc_disallow[1] >= 1) {
245 		wpa_printf(MSG_DEBUG,
246 				"skip - MBO association disallowed (reason %u)", assoc_disallow[2]);
247 		return false;
248 	}
249 
250 	if (wpa_is_bss_tmp_disallowed(&g_wpa_supp, bss)) {
251 		wpa_printf(MSG_DEBUG,
252 				"skip - BSS is temporary disallowed");
253 		return false;
254 	}
255 
256 	return true;
257 }
258 #endif
259 
esp_supplicant_common_init(struct wpa_funcs * wpa_cb)260 int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
261 {
262 	struct wpa_supplicant *wpa_s = &g_wpa_supp;
263 	int ret;
264 
265 	s_supplicant_evt_queue = xQueueCreate(3, sizeof(supplicant_event_t));
266 	ret = xTaskCreate(btm_rrm_task, "btm_rrm_t", SUPPLICANT_TASK_STACK_SIZE, NULL, 2, s_supplicant_task_hdl);
267 	if (ret != pdPASS) {
268 		wpa_printf(MSG_ERROR, "btm: failed to create task");
269 		return ret;
270 	}
271 
272 	s_supplicant_api_lock = xSemaphoreCreateRecursiveMutex();
273 	if (!s_supplicant_api_lock) {
274 		esp_supplicant_common_deinit();
275 		wpa_printf(MSG_ERROR, "%s: failed to create Supplicant API lock", __func__);
276 		return ret;
277 	}
278 
279 	esp_scan_init(wpa_s);
280 	wpas_rrm_reset(wpa_s);
281 	wpas_clear_beacon_rep_data(wpa_s);
282 
283 	esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
284 			&supplicant_sta_conn_handler, NULL);
285 	esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
286 			&supplicant_sta_disconn_handler, NULL);
287 
288 	wpa_s->type = 0;
289 	wpa_s->subtype = 0;
290 	wpa_s->type |= (1 << WLAN_FC_STYPE_BEACON) | (1 << WLAN_FC_STYPE_PROBE_RESP);
291 	esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
292 	wpa_cb->wpa_sta_rx_mgmt = ieee80211_handle_rx_frm;
293 	/* Matching is done only for MBO at the moment, this can be extended for other features*/
294 #ifdef CONFIG_MBO
295 	wpa_cb->wpa_sta_profile_match = bss_profile_match;
296 	dl_list_init(&wpa_s->bss_tmp_disallowed);
297 #else
298 	wpa_cb->wpa_sta_profile_match = NULL;
299 #endif
300 	return 0;
301 }
302 
esp_supplicant_common_deinit(void)303 void esp_supplicant_common_deinit(void)
304 {
305 	struct wpa_supplicant *wpa_s = &g_wpa_supp;
306 
307 	if (esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) {
308 		wpa_printf(MSG_ERROR, "failed to send task delete event");
309 	}
310 	esp_scan_deinit(wpa_s);
311 	wpas_rrm_reset(wpa_s);
312 	wpas_clear_beacon_rep_data(wpa_s);
313 	esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
314 			&supplicant_sta_conn_handler);
315 	esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
316 			&supplicant_sta_disconn_handler);
317 }
318 
esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,void * cb_ctx)319 int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
320 				      void *cb_ctx)
321 {
322 	struct wpa_ssid_value wpa_ssid = {0};
323 	struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal();
324 
325 	os_memcpy(wpa_ssid.ssid, ssid->ssid, ssid->len);
326 	wpa_ssid.ssid_len = ssid->len;
327 
328 	return wpas_rrm_send_neighbor_rep_request(&g_wpa_supp, &wpa_ssid, 0, 0, cb, cb_ctx);
329 }
330 
esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,const char * btm_candidates,int cand_list)331 int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
332 					   const char *btm_candidates,
333 					   int cand_list)
334 {
335 	return wnm_send_bss_transition_mgmt_query(&g_wpa_supp, query_reason, btm_candidates, cand_list);
336 }
337 
esp_mbo_update_non_pref_chan(struct non_pref_chan_s * non_pref_chan)338 int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
339 {
340 	int ret = wpas_mbo_update_non_pref_chan(&g_wpa_supp, non_pref_chan);
341 	if (ret == 0) {
342 		esp_set_assoc_ie();
343 	}
344 
345 	return ret;
346 }
347 
wpa_supplicant_connect(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,char * ssid)348 void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
349 			    struct wpa_bss *bss, char *ssid)
350 {
351 	wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
352 
353 	if (!config) {
354 		wpa_printf(MSG_ERROR, "failed to allocate memory");
355 		return;
356 	}
357 
358 	esp_wifi_get_config(WIFI_IF_STA, config);
359 	/* We only support roaming in same ESS, therefore only bssid setting is needed */
360 	os_memcpy(config->sta.bssid, bss->bssid, ETH_ALEN);
361 	config->sta.bssid_set = 1;
362 	/* supplicant connect will only be called in case of bss transition(roaming) */
363 	esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
364 	esp_wifi_set_config(WIFI_IF_STA, config);
365 	os_free(config);
366 	esp_wifi_connect();
367 }
368 
get_rm_enabled_ie(uint8_t * ie,size_t len)369 static size_t get_rm_enabled_ie(uint8_t *ie, size_t len)
370 {
371 	uint8_t rrm_ie[7] = {0};
372 	uint8_t rrm_ie_len = 5;
373 	uint8_t *pos = rrm_ie;
374 
375 	if (!esp_wifi_is_rm_enabled_internal(WIFI_IF_STA)) {
376 		return 0;
377 	}
378 
379 	*pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
380 	*pos++ = rrm_ie_len;
381 	*pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
382 
383 	*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
384 #ifdef SCAN_CACHE_SUPPORTED
385 		WLAN_RRM_CAPS_BEACON_REPORT_TABLE |
386 #endif
387 		WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE;
388 
389 	os_memcpy(ie, rrm_ie, sizeof(rrm_ie));
390 
391 	return rrm_ie_len + 2;
392 }
393 
394 #ifdef CONFIG_MBO
get_mbo_oce_scan_ie(uint8_t * ie,size_t len)395 static size_t get_mbo_oce_scan_ie(uint8_t *ie, size_t len)
396 {
397 	uint8_t mbo_ie[32] = {0};
398 	uint8_t mbo_ie_len = 32;
399 
400 	/* Return if MBO IE is not enabled in driver */
401 	if (!esp_wifi_is_mbo_enabled_internal(WIFI_IF_STA)) {
402 		return 0;
403 	}
404 
405 	struct wpabuf *default_ies = NULL;
406 	if (wpabuf_resize(&default_ies, 18) == 0) {
407 		wpas_mbo_scan_ie(&g_wpa_supp, default_ies);
408 		os_memcpy(mbo_ie, wpabuf_head_u8(default_ies), wpabuf_len(default_ies));
409 		mbo_ie_len = wpabuf_len(default_ies);
410 		wpabuf_free(default_ies);
411 	}
412 	os_memcpy(ie, mbo_ie, mbo_ie_len);
413 	return mbo_ie_len;
414 }
415 
get_mbo_oce_assoc_ie(uint8_t * ie,size_t len)416 static size_t get_mbo_oce_assoc_ie(uint8_t *ie, size_t len)
417 {
418 	uint8_t mbo_ie[32] = {0};
419 	uint8_t mbo_ie_len = 32;
420 
421 	/* Return if MBO IE is not enabled in driver */
422 	if (!esp_wifi_is_mbo_enabled_internal(WIFI_IF_STA)) {
423 		return 0;
424 	}
425 
426 	mbo_ie_len = wpas_mbo_ie(&g_wpa_supp, mbo_ie, mbo_ie_len, 0);
427 	os_memcpy(ie, mbo_ie, mbo_ie_len);
428 
429 	return mbo_ie_len;
430 }
431 #endif
432 
get_extended_caps_ie(uint8_t * ie,size_t len)433 static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
434 {
435 	uint8_t ext_caps_ie[5] = {0};
436 	uint8_t ext_caps_ie_len = 3;
437 	uint8_t *pos = ext_caps_ie;
438 
439 	if (!esp_wifi_is_btm_enabled_internal(WIFI_IF_STA)) {
440 		return 0;
441 	}
442 
443 	*pos++ = WLAN_EID_EXT_CAPAB;
444 	*pos++ = ext_caps_ie_len;
445 	*pos++ = 0;
446 	*pos++ = 0;
447 #define WLAN_EXT_CAPAB_BSS_TRANSITION BIT(3)
448 	*pos |= WLAN_EXT_CAPAB_BSS_TRANSITION;
449 #undef WLAN_EXT_CAPAB_BSS_TRANSITION
450 	os_memcpy(ie, ext_caps_ie, sizeof(ext_caps_ie));
451 
452 	return ext_caps_ie_len + 2;
453 }
454 
455 
get_operating_class_ie(uint8_t * ie,size_t len)456 static uint8_t get_operating_class_ie(uint8_t *ie, size_t len)
457 {
458 	uint8_t op_class_ie[4] = {0};
459 	uint8_t op_class_ie_len = 2;
460 	uint8_t *pos = op_class_ie;
461 
462 	*pos++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES;
463 	*pos++ = op_class_ie_len;
464 #define OPER_CLASS 0x51
465         /* Current Operating Class */
466         *pos++ = OPER_CLASS;
467 #undef OPER_CLASS
468         *pos = 0;
469 	os_memcpy(ie, op_class_ie, sizeof(op_class_ie));
470 
471 	return op_class_ie_len + 2;
472 }
473 
esp_set_scan_ie(void)474 void esp_set_scan_ie(void)
475 {
476 #define SCAN_IE_LEN 64
477 	uint8_t *ie, *pos;
478 	size_t len = SCAN_IE_LEN, ie_len;
479 
480 	ie = os_malloc(SCAN_IE_LEN);
481 	if (!ie) {
482 		wpa_printf(MSG_ERROR, "failed to allocate ie");
483 		return;
484 	}
485 	pos = ie;
486 	ie_len = get_extended_caps_ie(pos, len);
487 	pos += ie_len;
488 	len -= ie_len;
489 #ifdef CONFIG_MBO
490 	ie_len = get_mbo_oce_scan_ie(pos, len);
491 	pos += ie_len;
492 	len -= ie_len;
493 #endif
494 	esp_wifi_unset_appie_internal(WIFI_APPIE_PROBEREQ);
495 	esp_wifi_set_appie_internal(WIFI_APPIE_PROBEREQ, ie, SCAN_IE_LEN - len, 0);
496 	os_free(ie);
497 #undef SCAN_IE_LEN
498 }
499 
esp_set_assoc_ie(void)500 void esp_set_assoc_ie(void)
501 {
502 #define ASSOC_IE_LEN 128
503 	uint8_t *ie, *pos;
504 	size_t len = ASSOC_IE_LEN, ie_len;
505 
506 	ie = os_malloc(ASSOC_IE_LEN);
507 	if (!ie) {
508 		wpa_printf(MSG_ERROR, "failed to allocate ie");
509 		return;
510 	}
511 	pos = ie;
512 	ie_len = get_extended_caps_ie(pos, len);
513 	pos += ie_len;
514 	len -= ie_len;
515 	ie_len = get_operating_class_ie(pos, len);
516 	pos += ie_len;
517 	len -= ie_len;
518 	ie_len = get_rm_enabled_ie(pos, len);
519 	pos += ie_len;
520 	len -= ie_len;
521 #ifdef CONFIG_MBO
522 	ie_len = get_mbo_oce_assoc_ie(pos, len);
523 	pos += ie_len;
524 	len -= ie_len;
525 #endif
526 	esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_REQ);
527 	esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_REQ, ie, ASSOC_IE_LEN - len, 0);
528 	os_free(ie);
529 #undef ASSOC_IE_LEN
530 }
531 
esp_get_tx_power(uint8_t * tx_power)532 void esp_get_tx_power(uint8_t *tx_power)
533 {
534 #define DEFAULT_MAX_TX_POWER 19 /* max tx power is 19.5 dbm */
535 	s8 power;
536 	/* esp sends management frames at max tx power configured */
537 	int ret = esp_wifi_get_max_tx_power(&power);
538 	if (ret != 0) {
539 		wpa_printf(MSG_ERROR, "failed to get tx power");
540 		*tx_power = DEFAULT_MAX_TX_POWER;
541 		return;
542 	}
543 	*tx_power = power/4;
544 #undef DEFAULT_MAX_TX_POWER
545 }
546 
wpa_drv_send_action(struct wpa_supplicant * wpa_s,unsigned int channel,unsigned int wait,const u8 * data,size_t data_len,int no_cck)547 int wpa_drv_send_action(struct wpa_supplicant *wpa_s,
548 			unsigned int channel,
549 			unsigned int wait,
550 			const u8 *data, size_t data_len,
551 			int no_cck)
552 {
553 	int ret = 0;
554 	wifi_mgmt_frm_req_t *req = os_zalloc(sizeof(*req) + data_len);;
555 	if (!req)
556 		return -1;
557 
558 	if (!wpa_s->current_bss) {
559 		wpa_printf(MSG_ERROR, "STA not associated, return");
560 		ret = -1;
561 		goto cleanup;
562 	}
563 
564 	req->ifx = WIFI_IF_STA;
565 	req->subtype = WLAN_FC_STYPE_ACTION;
566 	req->data_len = data_len;
567 	os_memcpy(req->data, data, req->data_len);
568 
569 	if (esp_wifi_send_mgmt_frm_internal(req) != 0) {
570 		wpa_printf(MSG_ERROR, "action frame sending failed");
571 		ret = -1;
572 		goto cleanup;
573 	}
574 	wpa_printf(MSG_INFO, "action frame sent");
575 
576 cleanup:
577 	os_free(req);
578 	return ret;
579 }
580 
esp_supplicant_post_evt(uint32_t evt_id,uint32_t data)581 int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
582 {
583 	supplicant_event_t *evt = os_zalloc(sizeof(supplicant_event_t));
584 	if (evt == NULL) {
585 		return -1;
586 	}
587 	evt->id = evt_id;
588 	evt->data = data;
589 
590 	SUPPLICANT_API_LOCK();
591 	if (xQueueSend(s_supplicant_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
592 		SUPPLICANT_API_UNLOCK();
593 		os_free(evt);
594 		return -1;
595 	}
596 	SUPPLICANT_API_UNLOCK();
597 	return 0;
598 }
599