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