1 /*
2 * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <inttypes.h>
9
10 #include "utils/includes.h"
11 #include "common.h"
12 #include "eloop.h"
13 #include "rsn_supp/wpa.h"
14 #include "utils/common.h"
15 #include "common/eapol_common.h"
16 #include "utils/wpa_debug.h"
17 #include "common/ieee802_11_defs.h"
18 #include "crypto/dh_group5.h"
19 #include "wps/wps_i.h"
20 #include "wps/wps_dev_attr.h"
21 #include "eap_peer/eap_defs.h"
22 #include "eap_peer/eap_common.h"
23 #include "esp_wifi_driver.h"
24 #include "esp_event.h"
25 #include "esp_wifi.h"
26 #include "esp_err.h"
27 #include "esp_private/wifi.h"
28 #include "esp_wps_i.h"
29 #include "esp_dpp_i.h"
30 #include "esp_wps.h"
31 #include "eap_common/eap_wsc_common.h"
32 #include "esp_wpas_glue.h"
33
34 void *s_wps_api_lock = NULL; /* Used in WPS/WPS-REG public API only, never be freed */
35 void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS/WPS-REG public API caller task and WPS task, never be freed */
36 bool s_wps_enabled = false;
37 #ifdef USE_WPS_TASK
38 struct wps_rx_param {
39 u8 sa[ETH_ALEN];
40 u8 *buf;
41 int len;
42 STAILQ_ENTRY(wps_rx_param) bqentry;
43 };
44 static STAILQ_HEAD(,wps_rx_param) s_wps_rxq;
45
46 struct wps_sm_funcs *s_wps_sm_cb = NULL;
47 static void *s_wps_task_hdl = NULL;
48 static void *s_wps_queue = NULL;
49 static void *s_wps_data_lock = NULL;
50 static void *s_wps_task_create_sem = NULL;
51 static uint8_t s_wps_sig_cnt[SIG_WPS_NUM] = {0};
52
53 #endif
54
55 void wifi_wps_scan_done(void *arg, ETS_STATUS status);
56 void wifi_wps_scan(void *data, void *user_ctx);
57 int wifi_station_wps_start(void);
58 int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len);
59 void wifi_wps_start_internal(void);
60 int wifi_wps_enable_internal(const esp_wps_config_t *config);
61 int wifi_wps_disable_internal(void);
62 void wifi_station_wps_timeout_internal(void);
63 void wifi_station_wps_msg_timeout_internal(void);
64 void wifi_station_wps_success_internal(void);
65 void wifi_wps_scan_internal(void);
66 void wifi_station_wps_eapol_start_handle_internal(void);
67 void wps_add_discard_ap(u8 *bssid);
68
69 void wifi_station_wps_msg_timeout(void *data, void *user_ctx);
70 void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx);
71 void wifi_station_wps_success(void *data, void *user_ctx);
72 void wifi_station_wps_timeout(void *data, void *user_ctx);
73 int wps_delete_timer(void);
74
75 struct wps_sm *gWpsSm = NULL;
76 static wps_factory_information_t *s_factory_info = NULL;
77
wps_rxq_init(void)78 static void wps_rxq_init(void)
79 {
80 DATA_MUTEX_TAKE();
81 STAILQ_INIT(&s_wps_rxq);
82 DATA_MUTEX_GIVE();
83 }
84
wps_rxq_enqueue(struct wps_rx_param * param)85 static void wps_rxq_enqueue(struct wps_rx_param *param)
86 {
87 DATA_MUTEX_TAKE();
88 STAILQ_INSERT_TAIL(&s_wps_rxq,param, bqentry);
89 DATA_MUTEX_GIVE();
90 }
91
wps_rxq_dequeue(void)92 static struct wps_rx_param * wps_rxq_dequeue(void)
93 {
94 struct wps_rx_param *param = NULL;
95 DATA_MUTEX_TAKE();
96 if ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
97 STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
98 STAILQ_NEXT(param,bqentry) = NULL;
99 }
100 DATA_MUTEX_GIVE();
101 return param;
102 }
103
wps_rxq_deinit(void)104 static void wps_rxq_deinit(void)
105 {
106 struct wps_rx_param *param = NULL;
107 DATA_MUTEX_TAKE();
108 while ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
109 STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
110 STAILQ_NEXT(param,bqentry) = NULL;
111 os_free(param->buf);
112 os_free(param);
113 }
114 DATA_MUTEX_GIVE();
115 }
116
117 #ifdef USE_WPS_TASK
wps_task(void * pvParameters)118 void wps_task(void *pvParameters )
119 {
120 ETSEvent *e;
121 wps_ioctl_param_t *param;
122 bool del_task = false;
123
124 os_semphr_give(s_wps_task_create_sem);
125
126 wpa_printf(MSG_DEBUG, "wps_Task enter");
127 for (;;) {
128 if ( TRUE == os_queue_recv(s_wps_queue, &e, OS_BLOCK) ) {
129
130 if ( (e->sig >= SIG_WPS_ENABLE) && (e->sig < SIG_WPS_NUM) ) {
131 DATA_MUTEX_TAKE();
132 if (s_wps_sig_cnt[e->sig]) {
133 s_wps_sig_cnt[e->sig]--;
134 } else {
135 wpa_printf(MSG_ERROR, "wpsT: invalid sig cnt, sig=%" PRId32 " cnt=%d", e->sig, s_wps_sig_cnt[e->sig]);
136 }
137 DATA_MUTEX_GIVE();
138 }
139
140 wpa_printf(MSG_DEBUG, "wpsT: rx sig=%" PRId32 "", e->sig);
141
142 switch (e->sig) {
143 case SIG_WPS_ENABLE:
144 case SIG_WPS_DISABLE:
145 case SIG_WPS_START:
146 param = (wps_ioctl_param_t *)e->par;
147 if (!param) {
148 wpa_printf(MSG_ERROR, "wpsT: invalid param sig=%" PRId32 "", e->sig);
149 os_semphr_give(s_wps_api_sem);
150 break;
151 }
152
153 if (e->sig == SIG_WPS_ENABLE) {
154 param->ret = wifi_wps_enable_internal((esp_wps_config_t *)(param->arg));
155 } else if (e->sig == SIG_WPS_DISABLE) {
156 DATA_MUTEX_TAKE();
157 param->ret = wifi_wps_disable_internal();
158 del_task = true;
159 s_wps_task_hdl = NULL;
160 DATA_MUTEX_GIVE();
161 } else {
162 param->ret = wifi_station_wps_start();
163 }
164
165 os_semphr_give(s_wps_api_sem);
166 break;
167
168 case SIG_WPS_RX: {
169 struct wps_rx_param *param = NULL;
170 while ((param = wps_rxq_dequeue()) != NULL) {
171 wps_sm_rx_eapol_internal(param->sa, param->buf, param->len);
172 os_free(param->buf);
173 os_free(param);
174 }
175 break;
176 }
177
178 case SIG_WPS_TIMER_TIMEOUT:
179 wifi_station_wps_timeout_internal();
180 break;
181
182 case SIG_WPS_TIMER_MSG_TIMEOUT:
183 wifi_station_wps_msg_timeout_internal();
184 break;
185
186 case SIG_WPS_TIMER_SUCCESS_CB:
187 wifi_station_wps_success_internal();
188 break;
189
190 case SIG_WPS_TIMER_SCAN:
191 wifi_wps_scan_internal();
192 break;
193
194 case SIG_WPS_TIMER_EAPOL_START:
195 wifi_station_wps_eapol_start_handle_internal();
196 break;
197
198 default:
199 wpa_printf(MSG_ERROR, "wpsT: invalid sig=%" PRId32 "", e->sig);
200 break;
201 }
202 os_free(e);
203
204 if (del_task) {
205 wpa_printf(MSG_DEBUG, "wpsT: delete task");
206 break;
207 }
208 }
209 }
210 os_task_delete(NULL);
211 }
212
213 /* wps_post() is thread-safe
214 *
215 */
wps_post(uint32_t sig,uint32_t par)216 int wps_post(uint32_t sig, uint32_t par)
217 {
218 wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " cnt=%d", sig, s_wps_sig_cnt[sig]);
219
220 DATA_MUTEX_TAKE();
221
222 if (!s_wps_task_hdl) {
223 wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " failed as wps task has been deinited", sig);
224 DATA_MUTEX_GIVE();
225 return ESP_FAIL;
226 }
227 if (s_wps_sig_cnt[sig]) {
228 wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " processing", sig);
229 DATA_MUTEX_GIVE();
230 return ESP_OK;
231 } else {
232 ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
233
234 if (evt == NULL) {
235 wpa_printf(MSG_ERROR, "WPS: E N M");
236 DATA_MUTEX_GIVE();
237 return ESP_FAIL;
238 }
239
240 s_wps_sig_cnt[sig]++;
241 evt->sig = sig;
242 evt->par = par;
243 DATA_MUTEX_GIVE();
244
245 if (os_queue_send(s_wps_queue, &evt, os_task_ms_to_tick(10)) != TRUE) {
246 wpa_printf(MSG_ERROR, "WPS: Q S E");
247 DATA_MUTEX_TAKE();
248 s_wps_sig_cnt[sig]--;
249 DATA_MUTEX_GIVE();
250 return ESP_FAIL;
251 }
252 }
253 return ESP_OK;
254 }
255 #endif
256
257 /*
258 * wps_sm_ether_send - Send Ethernet frame
259 * @wpa_s: Pointer to wpa_supplicant data
260 * @proto: Ethertype in host byte order
261 * @buf: Frame payload starting from IEEE 802.1X header
262 * @len: Frame payload length
263 * Returns: >=0 on success, <0 on failure
264 */
wps_sm_ether_send(struct wps_sm * sm,u16 proto,const u8 * data,size_t data_len)265 static inline int wps_sm_ether_send(struct wps_sm *sm, u16 proto,
266 const u8 *data, size_t data_len)
267 {
268 u8 bssid[ETH_ALEN];
269 int ret = esp_wifi_get_assoc_bssid_internal(bssid);
270
271 if (ret != 0) {
272 wpa_printf(MSG_ERROR, "bssid is empty!");
273 return -1;
274 }
275
276 return wpa_ether_send(sm, bssid, proto, data, data_len);
277 }
278
279
wps_sm_alloc_eapol(struct wps_sm * sm,u8 type,const void * data,u16 data_len,size_t * msg_len,void ** data_pos)280 u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
281 const void *data, u16 data_len,
282 size_t *msg_len, void **data_pos)
283 {
284 return wpa_alloc_eapol(sm, type, data, data_len, msg_len, data_pos);
285 }
286
287
wps_sm_free_eapol(u8 * buffer)288 void wps_sm_free_eapol(u8 *buffer)
289 {
290 return wpa_free_eapol(buffer);
291 }
292
293 static void
wps_build_ic_appie_wps_pr(void)294 wps_build_ic_appie_wps_pr(void)
295 {
296 struct wpabuf *extra_ie = NULL;
297 struct wpabuf *wps_ie;
298 struct wps_sm *sm = gWpsSm;
299 u16 pw_id;
300
301 wpa_printf(MSG_DEBUG, "wps build: wps pr");
302
303 if (wps_get_type() == WPS_TYPE_PBC) {
304 pw_id = DEV_PW_PUSHBUTTON;
305 } else {
306 pw_id = DEV_PW_DEFAULT;
307 }
308 wps_ie = wps_build_probe_req_ie(pw_id, sm->dev, sm->uuid,
309 WPS_REQ_ENROLLEE, 0, NULL);
310
311 if (!wps_ie) {
312 return;
313 }
314
315 if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) {
316 wpabuf_put_buf(extra_ie, wps_ie);
317 } else {
318 wpabuf_free(wps_ie);
319 return;
320 }
321 wpabuf_free(wps_ie);
322
323 esp_wifi_set_appie_internal(WIFI_APPIE_WPS_PR, (uint8_t *)wpabuf_head(extra_ie), extra_ie->used, 0);
324 wpabuf_free(extra_ie);
325 }
326
327 static void
wps_build_ic_appie_wps_ar(void)328 wps_build_ic_appie_wps_ar(void)
329 {
330 struct wpabuf *buf = wps_build_assoc_req_ie(WPS_REQ_ENROLLEE);
331
332 wpa_printf(MSG_DEBUG, "wps build: wps ar");
333
334 if (buf) {
335 esp_wifi_set_appie_internal(WIFI_APPIE_WPS_AR, (uint8_t *)wpabuf_head(buf), buf->used, 0);
336 wpabuf_free(buf);
337 }
338 }
339
ap_supports_sae(struct wps_scan_ie * scan)340 static bool ap_supports_sae(struct wps_scan_ie *scan)
341 {
342 struct wpa_ie_data rsn_info;
343
344 if (!scan->rsn) {
345 return false;
346 }
347
348 wpa_parse_wpa_ie_rsn(scan->rsn, scan->rsn[1] + 2, &rsn_info);
349
350 if (rsn_info.key_mgmt & WPA_KEY_MGMT_SAE) {
351 return true;
352 }
353
354 return false;
355 }
356
357 static bool
wps_parse_scan_result(struct wps_scan_ie * scan)358 wps_parse_scan_result(struct wps_scan_ie *scan)
359 {
360 struct wps_sm *sm = gWpsSm;
361 wifi_mode_t op_mode = 0;
362
363 if (!sm->is_wps_scan || !scan->bssid) {
364 return false;
365 }
366
367 if (wps_get_type() == WPS_TYPE_DISABLE
368 || (wps_get_status() != WPS_STATUS_DISABLE
369 && wps_get_status() != WPS_STATUS_SCANNING)
370 ) {
371 return false;
372 }
373
374 esp_wifi_get_mode(&op_mode);
375 if ((op_mode != ESP32_WIFI_MODE_STA)
376 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
377 && (op_mode != ESP32_WIFI_MODE_APSTA)
378 #endif
379 ) {
380 return false;
381 }
382
383 if (!scan->rsn && !scan->wpa && (scan->capinfo & WLAN_CAPABILITY_PRIVACY)) {
384 wpa_printf(MSG_DEBUG, "WEP not suppported in WPS");
385 return false;
386 }
387
388 if (sm->ignore_sel_reg && !is_zero_ether_addr(sm->bssid)) {
389 /* We have selected candidate for this scan */
390 return false;
391 }
392
393 if (scan->wps) {
394 bool ap_found = false;
395 struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
396 int count;
397
398 if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) ||
399 (wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) {
400 /* Found one AP with selected registrar true */
401 sm->ignore_sel_reg = false;
402 sm->discard_ap_cnt = 0;
403 ap_found = true;
404 }
405 if (wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
406 /* AP is in discard list? */
407 for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
408 if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) {
409 wpa_printf(MSG_INFO, "discard ap bssid "MACSTR, MAC2STR(scan->bssid));
410 wpabuf_free(buf);
411 return false;
412 }
413 }
414 }
415
416 if (ap_found || sm->ignore_sel_reg) {
417 wpabuf_free(buf);
418 if (scan->ssid[1] > SSID_MAX_LEN) {
419 return false;
420 }
421 esp_wifi_enable_sta_privacy_internal();
422 os_memset(sm->creds[0].ssid, 0, SSID_MAX_LEN);
423 os_memcpy(sm->creds[0].ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
424 sm->creds[0].ssid_len = scan->ssid[1];
425 if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) {
426 wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR,
427 MAC2STR(sm->bssid), MAC2STR(scan->bssid));
428 sm->discover_ssid_cnt++;
429 os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
430 if (ap_supports_sae(scan)) {
431 wpa_printf(MSG_INFO, "AP supports SAE, get password in passphrase");
432 sm->dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY;
433 sm->wps->wps->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY;
434 /* Reset assoc req, probe reset not needed */
435 wps_build_ic_appie_wps_ar();
436 }
437 }
438 wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->creds[0].ssid);
439 sm->channel = scan->chan;
440
441 return true;
442 }
443 wpabuf_free(buf);
444 }
445
446 return false;
447 }
448
wps_send_eap_identity_rsp(u8 id)449 int wps_send_eap_identity_rsp(u8 id)
450 {
451 struct wps_sm *sm = gWpsSm;
452 struct wpabuf *eap_buf = NULL;
453 u8 *buf = NULL;
454 int len;
455 int ret = ESP_OK;
456
457 wpa_printf(MSG_DEBUG, "wps send eapol id rsp");
458 eap_buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, sm->identity_len,
459 EAP_CODE_RESPONSE, id);
460 if (!eap_buf) {
461 wpa_printf(MSG_ERROR, "eap buf allocation failed");
462 ret = ESP_FAIL;
463 goto _err;
464 }
465
466
467 wpabuf_put_data(eap_buf, sm->identity, sm->identity_len);
468
469 buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
470 if (!buf) {
471 wpa_printf(MSG_ERROR, "buf allocation failed");
472 ret = ESP_ERR_NO_MEM;
473 goto _err;
474 }
475
476 ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
477 if (ret) {
478 wpa_printf(MSG_ERROR, "wps sm ether send failed ret=%d", ret);
479 ret = ESP_FAIL;
480 goto _err;
481 }
482
483 _err:
484 wps_sm_free_eapol(buf);
485 wpabuf_free(eap_buf);
486 return ret;
487 }
488
wps_send_frag_ack(u8 id)489 int wps_send_frag_ack(u8 id)
490 {
491 struct wps_sm *sm = gWpsSm;
492 struct wpabuf *eap_buf = NULL;
493 u8 *buf;
494 int len;
495 int ret = 0;
496
497 wpa_printf(MSG_DEBUG, "send frag ack id:%d", id);
498
499 if (!sm) {
500 return ESP_FAIL;
501 }
502
503 eap_buf = eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE);
504 if (!eap_buf) {
505 ret = ESP_ERR_NO_MEM;
506 goto _err;
507 }
508
509 buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
510 if (!buf) {
511 ret = ESP_ERR_NO_MEM;
512 goto _err;
513 }
514
515 ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
516 wps_sm_free_eapol(buf);
517 if (ret) {
518 ret = ESP_ERR_NO_MEM;
519 goto _err;
520 }
521
522 _err:
523 wpabuf_free(eap_buf);
524 return ret;
525 }
526
wps_enrollee_process_msg_frag(struct wpabuf ** buf,int tot_len,u8 * frag_data,int frag_len,u8 flag)527 int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *frag_data, int frag_len, u8 flag)
528 {
529 struct wps_sm *sm = gWpsSm;
530 u8 identifier;
531
532 if (!sm) {
533 return ESP_FAIL;
534 }
535
536 identifier = sm->current_identifier;
537
538 if (buf == NULL || frag_data == NULL) {
539 wpa_printf(MSG_ERROR, "fun:%s. line:%d, frag buf or frag data is null", __FUNCTION__, __LINE__);
540 return ESP_FAIL;
541 }
542
543 if (*buf == NULL) {
544 if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) {
545 wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
546 return ESP_FAIL;
547 }
548
549 *buf = wpabuf_alloc(tot_len);
550 if (*buf == NULL) {
551 return ESP_ERR_NO_MEM;
552 }
553
554 wpabuf_put_data(*buf, frag_data, frag_len);
555 return wps_send_frag_ack(identifier);
556 }
557
558 if (flag & WPS_MSG_FLAG_LEN) {
559 wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
560 return ESP_FAIL;
561 }
562
563 wpabuf_put_data(*buf, frag_data, frag_len);
564
565 if (flag & WPS_MSG_FLAG_MORE) {
566 return wps_send_frag_ack(identifier);
567 }
568
569 return ESP_OK;
570 }
571
wps_process_wps_mX_req(u8 * ubuf,int len,enum wps_process_res * res)572 int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
573 {
574 struct wps_sm *sm = gWpsSm;
575 static struct wpabuf *wps_buf = NULL;
576 struct eap_expand *expd;
577 int tlen = 0;
578 u8 *tbuf;
579 u8 flag;
580 int frag_len;
581 u16 be_tot_len = 0;
582
583 if (!sm || !res) {
584 return ESP_FAIL;
585 }
586
587 expd = (struct eap_expand *) ubuf;
588 wpa_printf(MSG_DEBUG, "wps process mX req: len %d, tlen %d", len, tlen);
589
590 if (sm->state == WAIT_START) {
591 if (expd->opcode != WSC_Start) {
592 wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
593 "in WAIT_START state", expd->opcode);
594 return ESP_ERR_INVALID_STATE;
595 }
596 wpa_printf(MSG_DEBUG, "EAP-WSC: Received start");
597 sm->state = WPA_MESG;
598 } else if (expd->opcode == WSC_Start) {
599 wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
600 expd->opcode);
601 return ESP_ERR_INVALID_STATE;
602 }
603
604 flag = *(u8 *)(ubuf + sizeof(struct eap_expand));
605 if (flag & WPS_MSG_FLAG_LEN) {
606 tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length
607 frag_len = len - (sizeof(struct eap_expand) + 1 + 2);
608 be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1);
609 tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff);
610 } else {
611 tbuf = ubuf + sizeof(struct eap_expand) + 1;
612 frag_len = len - (sizeof(struct eap_expand) + 1);
613 tlen = frag_len;
614 }
615
616 if ((flag & WPS_MSG_FLAG_MORE) || wps_buf != NULL) {//frag msg
617 if (tlen > 50000) {
618 wpa_printf(MSG_ERROR, "EAP-WSC: Invalid Message Length");
619 return ESP_FAIL;
620 }
621 wpa_printf(MSG_DEBUG, "rx frag msg id:%d, flag:%d, frag_len: %d, tot_len: %d, be_tot_len:%d", sm->current_identifier, flag, frag_len, tlen, be_tot_len);
622 if (ESP_OK != wps_enrollee_process_msg_frag(&wps_buf, tlen, tbuf, frag_len, flag)) {
623 if (wps_buf) {
624 wpabuf_free(wps_buf);
625 wps_buf = NULL;
626 }
627 return ESP_FAIL;
628 }
629 if (flag & WPS_MSG_FLAG_MORE) {
630 *res = WPS_FRAGMENT;
631 return ESP_OK;
632 }
633 } else { //not frag msg
634 if (wps_buf) {//if something wrong, frag msg buf is not freed, free first
635 wpa_printf(MSG_ERROR, "something is wrong, frag buf is not freed");
636 wpabuf_free(wps_buf);
637 wps_buf = NULL;
638 }
639 wps_buf = wpabuf_alloc_copy(tbuf, tlen);
640 }
641
642 if (!wps_buf) {
643 return ESP_FAIL;
644 }
645
646 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
647
648 *res = wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf);
649
650 if (*res == WPS_FAILURE) {
651 sm->state = WPA_FAIL;
652 }
653
654 if (wps_buf) {
655 wpabuf_free(wps_buf);
656 wps_buf = NULL;
657 }
658 return ESP_OK;
659 }
660
wps_send_wps_mX_rsp(u8 id)661 int wps_send_wps_mX_rsp(u8 id)
662 {
663 struct wps_sm *sm = gWpsSm;
664 struct wpabuf *eap_buf = NULL;
665 struct wpabuf *wps_buf = NULL;
666 u8 *buf;
667 int len;
668 int ret = 0;
669 enum wsc_op_code opcode;
670
671 wpa_printf(MSG_DEBUG, "wps send wps mX rsp");
672
673 if (!sm) {
674 return ESP_FAIL;
675 }
676
677 wps_buf = wps_enrollee_get_msg(sm->wps, &opcode);
678 if (!wps_buf) {
679 ret = ESP_FAIL;
680 goto _err;
681 }
682
683 eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, wpabuf_len(wps_buf) + 2, EAP_CODE_RESPONSE, id);
684 if (!eap_buf) {
685 ret = ESP_FAIL;
686 goto _err;
687 }
688
689 wpabuf_put_u8(eap_buf, opcode);
690 wpabuf_put_u8(eap_buf, 0x00); /* flags */
691 wpabuf_put_data(eap_buf, wpabuf_head_u8(wps_buf), wpabuf_len(wps_buf));
692
693 wpabuf_free(wps_buf);
694
695 buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
696 if (!buf) {
697 ret = ESP_FAIL;
698 goto _err;
699 }
700
701 ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
702 wps_sm_free_eapol(buf);
703 if (ret) {
704 ret = ESP_FAIL;
705 goto _err;
706 }
707
708 _err:
709 wpabuf_free(eap_buf);
710 return ret;
711 }
712
713
714
wps_tx_start(void)715 int wps_tx_start(void)
716 {
717 struct wps_sm *sm = gWpsSm;
718 u8 *buf;
719 int len;
720
721 if (!sm) {
722 return ESP_FAIL;
723 }
724
725 wpa_printf(MSG_DEBUG, "WPS: Send EAPOL START.");
726 buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, (size_t *)&len, NULL);
727 if (!buf) {
728 return ESP_ERR_NO_MEM;
729 }
730
731 wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
732 wps_sm_free_eapol(buf);
733
734 eloop_register_timeout(3, 0, wifi_station_wps_eapol_start_handle, NULL, NULL);
735
736 return ESP_OK;
737 }
738
wps_start_pending(void)739 int wps_start_pending(void)
740 {
741 if (!gWpsSm) {
742 return ESP_FAIL;
743 }
744
745 wpa_printf(MSG_DEBUG, "wps start pending");
746 return wps_tx_start();
747 }
748
wps_stop_connection_timers(struct wps_sm * sm)749 static void wps_stop_connection_timers(struct wps_sm *sm)
750 {
751 esp_wifi_disarm_sta_connection_timer_internal();
752 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
753 eloop_cancel_timeout(wifi_station_wps_success, NULL, NULL);
754 }
755
wps_sm_init(struct wps_sm * sm)756 static int wps_sm_init(struct wps_sm *sm)
757 {
758 if (!sm) {
759 return -1;
760 }
761 sm->ignore_sel_reg = false;
762 sm->discard_ap_cnt = 0;
763 sm->scan_cnt = 0;
764 sm->discover_ssid_cnt = 0;
765 os_bzero(sm->bssid, ETH_ALEN);
766 os_bzero(sm->creds, sizeof(sm->creds));
767 sm->ap_cred_cnt = 0;
768
769 return 0;
770 }
771
wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)772 int wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)
773 {
774 struct wps_sm *sm = gWpsSm;
775
776 if (!gWpsSm) {
777 return ESP_FAIL;
778 }
779
780 wps_set_status(WPS_STATUS_DISABLE);
781 wps_sm_init(sm);
782
783 sm->wps->state = SEND_M1;
784 wps_stop_connection_timers(sm);
785 esp_wifi_disconnect();
786
787 sm->state = WPA_FAIL;
788 wpa_printf(MSG_DEBUG, "Write wps_fail_information");
789
790 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), OS_BLOCK);
791
792 return ESP_OK;
793 }
794
wps_finish(void)795 int wps_finish(void)
796 {
797 struct wps_sm *sm = gWpsSm;
798 int ret = ESP_FAIL;
799
800 if (!gWpsSm) {
801 return ESP_FAIL;
802 }
803
804 if (sm->wps->state == WPS_FINISHED) {
805 wpa_printf(MSG_DEBUG, "wps finished------>");
806 wps_set_status(WPS_STATUS_SUCCESS);
807 /* WPS finished, dequeue all timers */
808 wps_delete_timer();
809
810 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR);
811 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR);
812 esp_wifi_set_wps_cb_internal(NULL);
813
814 if (sm->ap_cred_cnt == 1) {
815 wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
816
817 if (config == NULL) {
818 return ESP_FAIL;
819 }
820
821 esp_wifi_get_config(WIFI_IF_STA, config);
822 esp_wifi_disconnect();
823 os_memcpy(config->sta.ssid, sm->creds[0].ssid, sm->creds[0].ssid_len);
824 os_memcpy(config->sta.password, sm->creds[0].key, sm->creds[0].key_len);
825 os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
826 #ifndef CONFIG_WPS_STRICT
827 /* Some APs support AES in WPA IE, enable connection with them */
828 if (sm->creds[0].auth_type == WPS_AUTH_WPAPSK &&
829 (sm->creds[0].encr_type & WPS_ENCR_AES)) {
830 config->sta.threshold.authmode = WIFI_AUTH_WPA_PSK;
831 }
832 #endif
833 config->sta.bssid_set = 0;
834 config->sta.sae_pwe_h2e = 0;
835 esp_wifi_set_config(WIFI_IF_STA, config);
836 esp_wifi_connect();
837
838 os_free(config);
839 }
840 eloop_cancel_timeout(wifi_station_wps_success, NULL, NULL);
841 eloop_register_timeout(1, 0, wifi_station_wps_success, NULL, NULL);
842
843 ret = 0;
844 } else {
845 wpa_printf(MSG_ERROR, "wps failed-----> ignore_sel_reg=%d", sm->ignore_sel_reg);
846 if (sm->ignore_sel_reg) {
847 sm->discover_ssid_cnt = 0;
848 esp_wifi_disconnect();
849 os_bzero(sm->creds, sizeof(sm->creds));
850 wps_add_discard_ap(sm->bssid);
851 } else {
852 ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
853 }
854 }
855
856 return ret;
857 }
858
wps_sm_notify_deauth(void)859 static void wps_sm_notify_deauth(void)
860 {
861 if (gWpsSm && gWpsSm->wps->state != WPS_FINISHED) {
862 wps_stop_process(WPS_FAIL_REASON_RECV_DEAUTH);
863 }
864 }
865
866 /* Add current ap to discard ap list */
wps_add_discard_ap(u8 * bssid)867 void wps_add_discard_ap(u8 *bssid)
868 {
869 struct wps_sm *sm = gWpsSm;
870 u8 cnt = sm->discard_ap_cnt;
871
872 if (!gWpsSm || !bssid) {
873 return;
874 }
875
876 if (sm->discard_ap_cnt < WPS_MAX_DIS_AP_NUM) {
877 sm->discard_ap_cnt++;
878 } else {
879 for (cnt = 0; cnt < WPS_MAX_DIS_AP_NUM - 2; cnt++) {
880 os_memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6);
881 }
882 sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM;
883 }
884 os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, ETH_ALEN);
885 wpa_printf(MSG_INFO, "Added BSSID:"MACSTR" to discard list cnt=%d" , MAC2STR(bssid), sm->discard_ap_cnt);
886 }
887
wps_start_msg_timer(void)888 int wps_start_msg_timer(void)
889 {
890 struct wps_sm *sm = gWpsSm;
891 uint32_t msg_timeout;
892 int ret = ESP_FAIL;
893
894 if (!gWpsSm) {
895 return ESP_FAIL;
896 }
897
898 if (sm->wps->state == WPS_FINISHED) {
899 msg_timeout = 100;
900 wpa_printf(MSG_DEBUG, "start msg timer WPS_FINISHED %" PRId32 " ms", msg_timeout);
901 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
902 eloop_register_timeout(0, msg_timeout*1000, wifi_station_wps_msg_timeout, NULL, NULL);
903 ret = 0;
904 } else if (sm->wps->state == RECV_M2) {
905 msg_timeout = 5;
906 wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " s", msg_timeout);
907 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
908 eloop_register_timeout(msg_timeout, 0, wifi_station_wps_msg_timeout, NULL, NULL);
909 ret = 0;
910 }
911 return ret;
912 }
913
914 /**
915 * wps_sm_rx_eapol - Process received WPA EAPOL frames
916 * @sm: Pointer to WPA state machine data from wpa_sm_init()
917 * @src_addr: Source MAC address of the EAPOL packet
918 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
919 * @len: Length of the EAPOL frame
920 * Returns: 1 = WPA EAPOL-Key processed, ESP_OK = not a WPA EAPOL-Key, ESP_FAIL failure
921 *
922 * This function is called for each received EAPOL frame. Other than EAPOL-Key
923 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
924 * only processing WPA and WPA2 EAPOL-Key frames.
925 *
926 * The received EAPOL-Key packets are validated and valid packets are replied
927 * to. In addition, key material (PTK, GTK) is configured at the end of a
928 * successful key handshake.
929 * buf begin from version, so remove mac header ,snap header and ether_type
930 */
wps_sm_rx_eapol(u8 * src_addr,u8 * buf,u32 len)931 int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
932 {
933 if (!gWpsSm) {
934 return ESP_FAIL;
935 }
936
937 #ifdef USE_WPS_TASK
938 {
939 struct wps_rx_param *param = os_zalloc(sizeof(struct wps_rx_param)); /* free in task */
940
941 if (!param) {
942 return ESP_ERR_NO_MEM;
943 }
944
945 param->buf = os_zalloc(len); /* free in task */
946 if (!param->buf) {
947 os_free(param);
948 return ESP_ERR_NO_MEM;
949 }
950 os_memcpy(param->buf, buf, len);
951 param->len = len;
952 os_memcpy(param->sa, src_addr, ETH_ALEN);
953
954 wps_rxq_enqueue(param);
955 return wps_post(SIG_WPS_RX, 0);
956 }
957 #else
958 return wps_sm_rx_eapol_internal(src_addr, buf, len);
959 #endif
960 }
961
wps_sm_rx_eapol_internal(u8 * src_addr,u8 * buf,u32 len)962 int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
963 {
964 struct wps_sm *sm = gWpsSm;
965 u32 plen, data_len, eap_len;
966 struct ieee802_1x_hdr *hdr;
967 struct eap_hdr *ehdr;
968 u8 *tmp;
969 u8 eap_code;
970 u8 eap_type;
971 int ret = ESP_FAIL;
972 enum wps_process_res res = WPS_DONE;
973
974 if (!gWpsSm) {
975 return ESP_FAIL;
976 }
977
978 if (len < sizeof(*hdr) + sizeof(*ehdr)) {
979 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA "
980 "EAPOL-Key (len %lu, expecting at least %lu)",
981 (unsigned long) len,
982 (unsigned long) sizeof(*hdr) + sizeof(*ehdr));
983 return ESP_OK;
984 }
985
986 tmp = buf;
987
988 hdr = (struct ieee802_1x_hdr *) tmp;
989 ehdr = (struct eap_hdr *) (hdr + 1);
990 plen = be_to_host16(hdr->length);
991 data_len = plen + sizeof(*hdr);
992 eap_len = be_to_host16(ehdr->length);
993
994 wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%" PRId32 "",
995 hdr->version, hdr->type, plen);
996
997 if (hdr->version < EAPOL_VERSION) {
998 /* TODO: backwards compatibility */
999 }
1000 if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) {
1001 wpa_printf(MSG_DEBUG, "WPS: EAP frame (type %u) discarded, "
1002 "not a EAP PACKET frame", hdr->type);
1003 ret = 0;
1004 goto out;
1005 }
1006 if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) {
1007 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %lu "
1008 "invalid (frame size %lu)",
1009 (unsigned long) plen, (unsigned long) len);
1010 ret = 0;
1011 goto out;
1012 }
1013
1014 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-EAP PACKET", tmp, len);
1015
1016 if (data_len < len) {
1017 wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "
1018 "802.1X data", (unsigned long) len - data_len);
1019 }
1020
1021 if (eap_len != plen) {
1022 wpa_printf(MSG_DEBUG, "WPA: EAPOL length %lu "
1023 "invalid (eapol length %lu)",
1024 (unsigned long) eap_len, (unsigned long) plen);
1025 ret = 0;
1026 goto out;
1027 }
1028
1029 eap_code = ehdr->code;
1030 switch (eap_code) {
1031 case EAP_CODE_SUCCESS:
1032 wpa_printf(MSG_DEBUG, "error: receive eapol success frame!");
1033 ret = 0;
1034 break;
1035 case EAP_CODE_FAILURE:
1036 wpa_printf(MSG_DEBUG, "receive eap code failure!");
1037 ret = wps_finish();
1038 break;
1039 case EAP_CODE_RESPONSE:
1040 wpa_printf(MSG_DEBUG, "error: receive eapol response frame!");
1041 ret = 0;
1042 break;
1043 case EAP_CODE_REQUEST: {
1044 eap_type = ((u8 *)ehdr)[sizeof(*ehdr)];
1045 switch (eap_type) {
1046 case EAP_TYPE_IDENTITY:
1047 wpa_printf(MSG_DEBUG, "=========identity===========");
1048 sm->current_identifier = ehdr->identifier;
1049 eloop_cancel_timeout(wifi_station_wps_eapol_start_handle, NULL, NULL);
1050 wpa_printf(MSG_DEBUG, "WPS: Build EAP Identity.");
1051 ret = wps_send_eap_identity_rsp(ehdr->identifier);
1052 eloop_register_timeout(3, 0, wifi_station_wps_eapol_start_handle, NULL, NULL);
1053 break;
1054 case EAP_TYPE_EXPANDED:
1055 wpa_printf(MSG_DEBUG, "=========expanded plen[%" PRId32 "], %d===========", plen, sizeof(*ehdr));
1056 sm->current_identifier = ehdr->identifier;
1057
1058 tmp = (u8 *)(ehdr + 1) + 1;
1059 ret = wps_process_wps_mX_req(tmp, plen - sizeof(*ehdr) - 1, &res);
1060 if (res == WPS_FRAGMENT) {
1061 wpa_printf(MSG_DEBUG, "wps frag, silently exit", res);
1062 ret = ESP_OK;
1063 break;
1064 }
1065 if (ret == ESP_OK && res != WPS_FAILURE) {
1066 ret = wps_send_wps_mX_rsp(ehdr->identifier);
1067
1068 if (ret == ESP_OK) {
1069 wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state);
1070 wps_start_msg_timer();
1071 }
1072 } else if (ret == ESP_ERR_INVALID_STATE) {
1073 ret = ESP_OK;
1074 } else {
1075 ret = ESP_FAIL;
1076 }
1077 break;
1078 default:
1079 break;
1080 }
1081 break;
1082 }
1083 default:
1084 break;
1085 }
1086 out:
1087 if (ret != 0 && sm->ignore_sel_reg) {
1088 wifi_wps_scan(NULL, NULL);
1089 } else if ((ret != 0 || res == WPS_FAILURE)) {
1090 wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
1091 wpa_printf(MSG_DEBUG, "wpa rx eapol internal: fail ret=%d", ret);
1092 wps_set_status(WPS_STATUS_DISABLE);
1093 esp_wifi_disarm_sta_connection_timer_internal();
1094 eloop_cancel_timeout(wifi_station_wps_timeout, NULL, NULL);
1095
1096 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), OS_BLOCK);
1097
1098 return ret;
1099 }
1100
1101 return ret;
1102 }
1103
wps_set_default_factory(void)1104 int wps_set_default_factory(void)
1105 {
1106 if (!s_factory_info) {
1107 s_factory_info = os_zalloc(sizeof(wps_factory_information_t));
1108 if (!s_factory_info) {
1109 wpa_printf(MSG_ERROR, "wps factory info malloc failed");
1110 return ESP_ERR_NO_MEM;
1111 }
1112 }
1113
1114 os_snprintf(s_factory_info->manufacturer, WPS_MAX_MANUFACTURER_LEN, "ESPRESSIF");
1115 os_snprintf(s_factory_info->model_name, WPS_MAX_MODEL_NUMBER_LEN, "ESPRESSIF IOT");
1116 os_snprintf(s_factory_info->model_number, WPS_MAX_MODEL_NAME_LEN, "%s", CONFIG_SOC_SERIES);
1117 os_snprintf(s_factory_info->device_name, WPS_MAX_DEVICE_NAME_LEN, "%s STATION", CONFIG_SOC_SERIES);
1118
1119 return ESP_OK;
1120 }
1121
wps_set_factory_info(const esp_wps_config_t * config)1122 int wps_set_factory_info(const esp_wps_config_t *config)
1123 {
1124 int ret;
1125
1126 ret = wps_set_default_factory();
1127 if (ret != 0) {
1128 return ret;
1129 }
1130
1131 if (config->factory_info.manufacturer[0] != 0) {
1132 os_memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1);
1133 }
1134
1135 if (config->factory_info.model_number[0] != 0) {
1136 os_memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1);
1137 }
1138
1139 if (config->factory_info.model_name[0] != 0) {
1140 os_memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1);
1141 }
1142
1143 if (config->factory_info.device_name[0] != 0) {
1144 os_memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1);
1145 }
1146
1147 wpa_printf(MSG_INFO, "manufacturer: %s, model number: %s, model name: %s, device name: %s", s_factory_info->manufacturer,
1148 s_factory_info->model_number, s_factory_info->model_name, s_factory_info->device_name);
1149
1150 return ESP_OK;
1151 }
1152
1153
wps_dev_init(void)1154 int wps_dev_init(void)
1155 {
1156 int ret = 0;
1157 struct wps_sm *sm = gWpsSm;
1158 struct wps_device_data *dev = NULL;
1159
1160 if (!sm) {
1161 ret = ESP_FAIL;
1162 goto _out;
1163 }
1164
1165 dev = &sm->wps_ctx->dev;
1166 sm->dev = dev;
1167
1168 if (!dev) {
1169 ret = ESP_FAIL;
1170 goto _out;
1171 }
1172 dev->config_methods = WPS_CONFIG_VIRT_PUSHBUTTON;
1173 #ifdef CONFIG_ESP_WIFI_WPS_PASSPHRASE
1174 dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY;
1175 #endif
1176 dev->rf_bands = WPS_RF_24GHZ;
1177
1178 WPA_PUT_BE16(dev->pri_dev_type, WPS_DEV_PHONE);
1179 WPA_PUT_BE32(dev->pri_dev_type + 2, WPS_DEV_OUI_WFA);
1180 WPA_PUT_BE16(dev->pri_dev_type + 6, WPS_DEV_PHONE_SINGLE_MODE);
1181
1182 if (!s_factory_info) {
1183 ret = wps_set_default_factory();
1184 if (ret != 0) {
1185 goto _out;
1186 }
1187 }
1188
1189 dev->manufacturer = os_zalloc(WPS_MAX_MANUFACTURER_LEN);
1190 if (!dev->manufacturer) {
1191 ret = ESP_FAIL;
1192 goto _out;
1193 }
1194 os_snprintf(dev->manufacturer, WPS_MAX_MANUFACTURER_LEN, "%s", s_factory_info->manufacturer);
1195
1196 dev->model_name = os_zalloc(WPS_MAX_MODEL_NAME_LEN);
1197 if (!dev->model_name) {
1198 ret = ESP_FAIL;
1199 goto _out;
1200 }
1201 os_snprintf(dev->model_name, WPS_MAX_MODEL_NAME_LEN, "%s", s_factory_info->model_name);
1202
1203 dev->model_number = os_zalloc(WPS_MAX_MODEL_NAME_LEN);
1204 if (!dev->model_number) {
1205 ret = ESP_FAIL;
1206 goto _out;
1207 }
1208 os_snprintf(dev->model_number, WPS_MAX_MODEL_NAME_LEN, "%s", s_factory_info->model_number);
1209
1210 dev->device_name = os_zalloc(WPS_MAX_DEVICE_NAME_LEN);
1211 if (!dev->device_name) {
1212 ret = ESP_FAIL;
1213 goto _out;
1214 }
1215 os_snprintf(dev->device_name, WPS_MAX_DEVICE_NAME_LEN, "%s", s_factory_info->device_name);
1216
1217 dev->serial_number = os_zalloc(16);
1218 if (!dev->serial_number) {
1219 ret = ESP_FAIL;
1220 goto _out;
1221 }
1222 os_snprintf(dev->serial_number, 16, "%02x%02x%02x%02x%02x%02x",
1223 sm->ownaddr[0], sm->ownaddr[1], sm->ownaddr[2],
1224 sm->ownaddr[3], sm->ownaddr[4], sm->ownaddr[5]);
1225
1226 uuid_gen_mac_addr(sm->ownaddr, sm->uuid);
1227 os_memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN);
1228
1229 return ESP_OK;
1230
1231 _out:
1232 wps_dev_deinit(dev);
1233 return ret;
1234 }
1235
1236
wps_dev_deinit(struct wps_device_data * dev)1237 int wps_dev_deinit(struct wps_device_data *dev)
1238 {
1239 int ret = 0;
1240
1241 if (!dev) {
1242 return ESP_FAIL;
1243 }
1244 wps_device_data_free(dev);
1245
1246 if (s_factory_info) {
1247 os_free(s_factory_info);
1248 s_factory_info = NULL;
1249 }
1250
1251 return ret;
1252 }
1253
1254 void
wifi_station_wps_timeout_internal(void)1255 wifi_station_wps_timeout_internal(void)
1256 {
1257 struct wps_sm *sm = gWpsSm;
1258
1259 if (!sm) {
1260 return;
1261 }
1262
1263 esp_wifi_disarm_sta_connection_timer_internal();
1264
1265 wps_set_status(WPS_STATUS_DISABLE);
1266
1267 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_TIMEOUT, 0, 0, OS_BLOCK);
1268 }
1269
wifi_station_wps_timeout(void * data,void * user_ctx)1270 void wifi_station_wps_timeout(void *data, void *user_ctx)
1271 {
1272 #ifdef USE_WPS_TASK
1273 wps_post(SIG_WPS_TIMER_TIMEOUT, 0);
1274 return;
1275 #else
1276 wifi_station_wps_timeout_internal();
1277 #endif
1278 }
1279
1280 void
wifi_station_wps_msg_timeout_internal(void)1281 wifi_station_wps_msg_timeout_internal(void)
1282 {
1283 struct wps_sm *sm = gWpsSm;
1284 if (!sm) {
1285 return;
1286 }
1287
1288 if (sm->wps->state == WPS_FINISHED) {
1289 wpa_printf(MSG_DEBUG, "wps msg timeout WPS_FINISHED");
1290 wps_finish();
1291 return;
1292 } else if (sm->wps->state == RECV_M2) {
1293 wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
1294 if (!sm->ignore_sel_reg) {
1295 wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
1296 }
1297 }
1298 if (sm->ignore_sel_reg) {
1299 esp_wifi_disconnect();
1300 wps_add_discard_ap(sm->bssid);
1301 os_bzero(sm->creds, sizeof(sm->creds));
1302 os_bzero(sm->bssid, ETH_ALEN);
1303 sm->discover_ssid_cnt = 0;
1304 wifi_wps_scan(NULL, NULL);
1305 }
1306 }
1307
wifi_station_wps_msg_timeout(void * data,void * user_ctx)1308 void wifi_station_wps_msg_timeout(void *data, void *user_ctx)
1309 {
1310 #ifdef USE_WPS_TASK
1311 wps_post(SIG_WPS_TIMER_MSG_TIMEOUT, 0);
1312 return;
1313 #else
1314 wifi_station_wps_msg_timeout_internal();
1315 #endif
1316 }
1317
wifi_station_wps_success_internal(void)1318 void wifi_station_wps_success_internal(void)
1319 {
1320 wifi_event_sta_wps_er_success_t evt = {0};
1321 struct wps_sm *sm = gWpsSm;
1322 int i;
1323
1324 /*
1325 * For only one AP credential don't send event data, wps_finish() has already set
1326 * the config. This is for backward compatibility.
1327 */
1328 if (sm->ap_cred_cnt > 1) {
1329 evt.ap_cred_cnt = sm->ap_cred_cnt;
1330 for (i = 0; i < MAX_WPS_AP_CRED; i++) {
1331 os_memcpy(evt.ap_cred[i].ssid, sm->creds[i].ssid, sm->creds[i].ssid_len);
1332 os_memcpy(evt.ap_cred[i].passphrase, sm->creds[i].key, sm->creds[i].key_len);
1333 }
1334 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt,
1335 sizeof(evt), OS_BLOCK);
1336 } else {
1337 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS,
1338 0, 0, OS_BLOCK);
1339 }
1340 }
1341
wifi_station_wps_success(void * data,void * user_ctx)1342 void wifi_station_wps_success(void *data, void *user_ctx)
1343 {
1344 #ifdef USE_WPS_TASK
1345 wps_post(SIG_WPS_TIMER_SUCCESS_CB, 0);
1346 return;
1347 #else
1348 wifi_station_wps_success_internal();
1349 #endif
1350 }
1351
wifi_station_wps_eapol_start_handle_internal(void)1352 void wifi_station_wps_eapol_start_handle_internal(void)
1353 {
1354 wpa_printf(MSG_DEBUG, "Resend EAPOL-Start.");
1355 wps_tx_start();
1356 }
1357
wifi_station_wps_eapol_start_handle(void * data,void * user_ctx)1358 void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx)
1359 {
1360 #ifdef USE_WPS_TASK
1361 wps_post(SIG_WPS_TIMER_EAPOL_START, 0);
1362 return;
1363 #else
1364 wifi_station_wps_eapol_start_handle_internal();
1365 #endif
1366 }
1367
save_credentials_cb(void * ctx,const struct wps_credential * cred)1368 static int save_credentials_cb(void *ctx, const struct wps_credential *cred)
1369 {
1370 struct wps_credential *creds;
1371 if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt >= MAX_CRED_COUNT) {
1372 return ESP_FAIL;
1373 }
1374
1375 creds = &gWpsSm->creds[gWpsSm->ap_cred_cnt];
1376 memcpy(creds, cred, sizeof(*creds));
1377
1378 gWpsSm->ap_cred_cnt++;
1379
1380 wpa_hexdump_ascii(MSG_DEBUG, "ssid ", cred->ssid, cred->ssid_len);
1381 wpa_hexdump_ascii(MSG_DEBUG, "key ", cred->key, cred->key_len);
1382
1383 return ESP_OK;
1384 }
1385
wps_init_cfg_pin(struct wps_config * cfg)1386 int wps_init_cfg_pin(struct wps_config *cfg)
1387 {
1388 if (wps_get_type() != WPS_TYPE_PIN) {
1389 cfg->pbc = 1;
1390 return 0;
1391 }
1392
1393 cfg->pbc = 0;
1394
1395 if ((os_strncmp((char *)cfg->pin, "00000000", 8) == 0) || !wps_pin_str_valid((char *)cfg->pin)) {
1396 unsigned int spin = 0;
1397
1398 cfg->dev_pw_id = DEV_PW_DEFAULT;
1399 cfg->pin_len = 8;
1400 if (wps_generate_pin(&spin) < 0) {
1401 return -1;
1402 }
1403 wpa_printf(MSG_INFO, "Provided PIN %s is not valid, generated a new PIN %08d", (char *)cfg->pin, spin);
1404 os_snprintf((char *)cfg->pin, 9, "%08d", spin);
1405 }
1406
1407 return 0;
1408 }
1409
wps_get_wps_sm_cb(void)1410 struct wps_sm_funcs* wps_get_wps_sm_cb(void)
1411 {
1412 return s_wps_sm_cb;
1413 }
1414
wifi_station_wps_init(const esp_wps_config_t * config)1415 static int wifi_station_wps_init(const esp_wps_config_t *config)
1416 {
1417 struct wps_funcs *wps_cb;
1418 struct wps_sm *sm = NULL;
1419 struct wps_config cfg = {0};
1420
1421 if (gWpsSm) {
1422 goto _out;
1423 }
1424
1425 wpa_printf(MSG_DEBUG, "wifi sta wps init");
1426
1427 gWpsSm = os_zalloc(sizeof(struct wps_sm)); /* alloc Wps_sm */
1428 if (!gWpsSm) {
1429 goto _out;
1430 }
1431
1432 sm = gWpsSm;
1433
1434 esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
1435 os_memcpy(gWpaSm.own_addr, sm->ownaddr, ETH_ALEN);
1436
1437 sm->identity_len = WSC_ID_ENROLLEE_LEN;
1438 os_memcpy(sm->identity, WSC_ID_ENROLLEE, sm->identity_len);
1439
1440 sm->wps_ctx = os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
1441 if (!sm->wps_ctx) {
1442 goto _err;
1443 }
1444
1445 if (wps_dev_init() != 0) {
1446 goto _err;
1447 }
1448
1449 cfg.wps = sm->wps_ctx;
1450
1451 os_memcpy((void *)cfg.pin, config->pin, 8);
1452 if (wps_init_cfg_pin(&cfg) < 0) {
1453 goto _err;
1454 }
1455
1456 os_memcpy(cfg.wps->uuid, sm->uuid, WPS_UUID_LEN);
1457 cfg.wps->config_methods = sm->wps_ctx->dev.config_methods;
1458 if ((sm->wps = wps_init(&cfg)) == NULL) { /* alloc wps_data */
1459 goto _err;
1460 }
1461
1462 /* Report PIN */
1463 if (wps_get_type() == WPS_TYPE_PIN) {
1464 wifi_event_sta_wps_er_pin_t evt;
1465 os_memcpy(evt.pin_code, sm->wps->dev_password, 8);
1466 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), OS_BLOCK);
1467 }
1468
1469 sm->wps->wps->cred_cb = save_credentials_cb;
1470 /**************80211 reference***************/
1471
1472 if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_PR) == NULL) { /* alloc probe req wps ie */
1473 wps_build_ic_appie_wps_pr();
1474 }
1475
1476 if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_AR) == NULL) { /* alloc assoc req wps ie */
1477 wps_build_ic_appie_wps_ar();
1478 }
1479
1480 eloop_cancel_timeout(wifi_station_wps_timeout, NULL, NULL);
1481 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
1482 eloop_cancel_timeout(wifi_station_wps_success, NULL, NULL);
1483 eloop_cancel_timeout(wifi_wps_scan, NULL, NULL);
1484 eloop_cancel_timeout(wifi_station_wps_eapol_start_handle, NULL, NULL);
1485
1486 wps_cb = os_malloc(sizeof(struct wps_funcs));
1487 if (wps_cb == NULL) {
1488 goto _err;
1489 }
1490 wps_cb->wps_parse_scan_result = wps_parse_scan_result;
1491 wps_cb->wifi_station_wps_start = wifi_station_wps_start;
1492 wps_cb->wps_sm_rx_eapol = wps_sm_rx_eapol;
1493 wps_cb->wps_start_pending = wps_start_pending;
1494 esp_wifi_set_wps_cb_internal(wps_cb);
1495
1496 s_wps_sm_cb = os_malloc(sizeof(struct wps_sm_funcs));
1497 if (s_wps_sm_cb == NULL) {
1498 goto _err;
1499 }
1500 s_wps_sm_cb->wps_sm_notify_deauth = wps_sm_notify_deauth;
1501
1502 return ESP_OK;
1503
1504 _err:
1505 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR);
1506 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR);
1507
1508 if (sm->dev) {
1509 wps_dev_deinit(sm->dev);
1510 sm->dev = NULL;
1511 }
1512 if (sm->wps_ctx) {
1513 if (sm->wps_ctx->dh_privkey) {
1514 wpabuf_free(sm->wps_ctx->dh_privkey);
1515 }
1516 os_free(sm->wps_ctx);
1517 sm->wps_ctx = NULL;
1518 }
1519 if (sm->wps) {
1520 wps_deinit(sm->wps);
1521 sm->wps = NULL;
1522 }
1523 os_free(gWpsSm);
1524 gWpsSm = NULL;
1525 return ESP_FAIL;
1526 _out:
1527 return ESP_FAIL;
1528 }
1529
wps_delete_timer(void)1530 int wps_delete_timer(void)
1531 {
1532 struct wps_sm *sm = gWpsSm;
1533
1534 if (!sm) {
1535 return ESP_OK;
1536 }
1537
1538 eloop_cancel_timeout(wifi_station_wps_success, NULL, NULL);
1539 eloop_cancel_timeout(wifi_station_wps_timeout, NULL, NULL);
1540 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
1541 eloop_cancel_timeout(wifi_wps_scan, NULL, NULL);
1542 eloop_cancel_timeout(wifi_station_wps_eapol_start_handle, NULL, NULL);
1543 esp_wifi_disarm_sta_connection_timer_internal();
1544 return ESP_OK;
1545 }
1546
1547 int
wifi_station_wps_deinit(void)1548 wifi_station_wps_deinit(void)
1549 {
1550 struct wps_sm *sm = gWpsSm;
1551
1552 if (gWpsSm == NULL) {
1553 return ESP_FAIL;
1554 }
1555
1556 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR);
1557 esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR);
1558 esp_wifi_set_wps_cb_internal(NULL);
1559
1560 if (sm->dev) {
1561 wps_dev_deinit(sm->dev);
1562 sm->dev = NULL;
1563 }
1564 if (sm->wps_ctx) {
1565 if (sm->wps_ctx->dh_privkey) {
1566 wpabuf_free(sm->wps_ctx->dh_privkey);
1567 }
1568 os_free(sm->wps_ctx);
1569 sm->wps_ctx = NULL;
1570 }
1571 if (sm->wps) {
1572 wps_deinit(sm->wps);
1573 sm->wps = NULL;
1574 }
1575 if (s_wps_sm_cb) {
1576 os_free(s_wps_sm_cb);
1577 s_wps_sm_cb = NULL;
1578 }
1579
1580 os_free(gWpsSm);
1581 gWpsSm = NULL;
1582
1583 return ESP_OK;
1584 }
1585
1586 struct wps_sm *
wps_sm_get(void)1587 wps_sm_get(void)
1588 {
1589 return gWpsSm;
1590 }
1591
1592 void
wifi_wps_scan_done(void * arg,ETS_STATUS status)1593 wifi_wps_scan_done(void *arg, ETS_STATUS status)
1594 {
1595 struct wps_sm *sm = gWpsSm;
1596 wifi_config_t wifi_config = {0};
1597
1598 wpa_printf(MSG_INFO, "WPS: scan done");
1599 if (wps_get_type() == WPS_TYPE_DISABLE) {
1600 return;
1601 }
1602
1603 if (!sm) {
1604 return;
1605 }
1606
1607 if (sm->discover_ssid_cnt == 1) {
1608 wps_set_status(WPS_STATUS_PENDING);
1609 } else if (sm->discover_ssid_cnt == 0) {
1610 wps_set_status(WPS_STATUS_SCANNING);
1611 } else {
1612 if (wps_get_type() == WPS_TYPE_PBC) {
1613 wpa_printf(MSG_INFO, "PBC session overlap!");
1614 wps_set_status(WPS_STATUS_DISABLE);
1615 esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK);
1616 } else {
1617 wps_set_status(WPS_STATUS_PENDING);
1618 }
1619 }
1620
1621 wpa_printf(MSG_DEBUG, "wps scan_done discover_ssid_cnt = %d", sm->discover_ssid_cnt);
1622
1623 sm->discover_ssid_cnt = 0;
1624
1625 if (wps_get_status() == WPS_STATUS_PENDING) {
1626 esp_wifi_disconnect();
1627
1628 os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN);
1629 os_memcpy(wifi_config.sta.ssid, (char *)sm->creds[0].ssid, sm->creds[0].ssid_len);
1630 wifi_config.sta.bssid_set = 1;
1631 wifi_config.sta.channel = sm->channel;
1632 wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR,
1633 (char *)sm->creds[0].ssid, MAC2STR(wifi_config.sta.bssid));
1634 esp_wifi_set_config(0, &wifi_config);
1635
1636 wpa_printf(MSG_DEBUG, "WPS: neg start");
1637 wifi_config.sta.failure_retry_cnt = 2;
1638 esp_wifi_connect();
1639 sm->state = WAIT_START;
1640 eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
1641 eloop_register_timeout(2, 0, wifi_station_wps_msg_timeout, NULL, NULL);
1642 } else if (wps_get_status() == WPS_STATUS_SCANNING) {
1643 if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) {
1644 wpa_printf(MSG_INFO, "WPS: ignore selected registrar after %d scans", sm->scan_cnt);
1645 sm->ignore_sel_reg = true;
1646 }
1647 eloop_cancel_timeout(wifi_wps_scan, NULL, NULL);
1648 eloop_register_timeout(0, 100*1000, wifi_wps_scan, NULL, NULL);
1649 } else {
1650 return;
1651 }
1652 }
1653
1654 void
wifi_wps_scan_internal(void)1655 wifi_wps_scan_internal(void)
1656 {
1657 struct wps_sm *sm = gWpsSm;
1658
1659 sm->scan_cnt++;
1660 wpa_printf(MSG_DEBUG, "wifi_wps_scan : %d", sm->scan_cnt);
1661
1662 typedef void (* scan_done_cb_t)(void *arg, ETS_STATUS status);
1663 extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb);
1664 esp_wifi_promiscuous_scan_start(NULL, wifi_wps_scan_done);
1665 }
1666
wifi_wps_scan(void * data,void * user_ctx)1667 void wifi_wps_scan(void *data, void *user_ctx)
1668 {
1669 #ifdef USE_WPS_TASK
1670 wps_post(SIG_WPS_TIMER_SCAN, 0);
1671 return;
1672 #else
1673 wifi_wps_scan_internal();
1674 #endif
1675 }
1676
wps_rf_band_cb(void * ctx)1677 static int wps_rf_band_cb(void *ctx)
1678 {
1679 return WPS_RF_24GHZ;
1680 }
1681
wifi_station_wps_start(void)1682 int wifi_station_wps_start(void)
1683 {
1684 struct wps_sm *sm = wps_sm_get();
1685
1686 if (!sm) {
1687 wpa_printf(MSG_ERROR, "WPS: wps is not initialized");
1688 return ESP_FAIL;
1689 }
1690
1691 eloop_register_timeout(120, 0, wifi_station_wps_timeout, NULL, NULL);
1692
1693 switch (wps_get_status()) {
1694 case WPS_STATUS_DISABLE: {
1695 sm->is_wps_scan = true;
1696
1697 wps_build_public_key(sm->wps, NULL);
1698 if (sm->wps->wps->dh_privkey) {
1699 wpabuf_free(sm->wps->wps->dh_privkey);
1700 }
1701 sm->wps->wps->dh_privkey = sm->wps->dh_privkey;
1702 sm->wps->wps->dh_ctx = sm->wps->dh_ctx;
1703 sm->wps->wps->dh_pubkey = sm->wps->dh_pubkey_e;
1704 sm->wps->wps->rf_band_cb = wps_rf_band_cb;
1705 sm->wps->dh_privkey = NULL;
1706 wifi_wps_scan(NULL, NULL);
1707 break;
1708 }
1709 case WPS_STATUS_SCANNING:
1710 sm->scan_cnt = 0;
1711 eloop_cancel_timeout(wifi_station_wps_timeout, NULL, NULL);
1712 eloop_register_timeout(120, 0, wifi_station_wps_timeout, NULL, NULL);
1713 break;
1714 default:
1715 break;
1716 }
1717 sm->discard_ap_cnt = 0;
1718 os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
1719 esp_wifi_set_wps_start_flag_internal(true);
1720 return ESP_OK;
1721 }
1722
wps_task_deinit(void)1723 int wps_task_deinit(void)
1724 {
1725 wpa_printf(MSG_DEBUG, "wps task deinit");
1726
1727 if (s_wps_api_sem) {
1728 os_semphr_delete(s_wps_api_sem);
1729 s_wps_api_sem = NULL;
1730 wpa_printf(MSG_DEBUG, "wps task deinit: free api sem");
1731 }
1732
1733 if (s_wps_task_create_sem) {
1734 os_semphr_delete(s_wps_task_create_sem);
1735 s_wps_task_create_sem = NULL;
1736 wpa_printf(MSG_DEBUG, "wps task deinit: free task create sem");
1737 }
1738
1739 if (s_wps_queue) {
1740 os_queue_delete(s_wps_queue);
1741 s_wps_queue = NULL;
1742 wpa_printf(MSG_DEBUG, "wps task deinit: free queue");
1743 }
1744
1745 if (STAILQ_FIRST(&s_wps_rxq) != NULL){
1746 wps_rxq_deinit();
1747 }
1748
1749 if (s_wps_data_lock) {
1750 os_mutex_delete(s_wps_data_lock);
1751 s_wps_data_lock = NULL;
1752 }
1753
1754 return ESP_OK;
1755 }
1756
wps_task_init(void)1757 int wps_task_init(void)
1758 {
1759 int ret = 0;
1760
1761 /* Call wps_task_deinit() first in case esp_wifi_wps_disable() fails
1762 */
1763 wps_task_deinit();
1764
1765 if (!s_wps_data_lock) {
1766 s_wps_data_lock = os_recursive_mutex_create();
1767 if (!s_wps_data_lock) {
1768 wpa_printf(MSG_ERROR, "wps task init: failed to alloc data lock");
1769 goto _wps_no_mem;
1770 }
1771 }
1772
1773 s_wps_api_sem = os_semphr_create(1, 0);
1774 if (!s_wps_api_sem) {
1775 wpa_printf(MSG_ERROR, "wps task init: failed to create api sem");
1776 goto _wps_no_mem;
1777 }
1778
1779 s_wps_task_create_sem = os_semphr_create(1, 0);
1780 if (!s_wps_task_create_sem) {
1781 wpa_printf(MSG_ERROR, "wps task init: failed to create task sem");
1782 goto _wps_no_mem;
1783 }
1784
1785 os_bzero(s_wps_sig_cnt, SIG_WPS_NUM);
1786 s_wps_queue = os_queue_create(SIG_WPS_NUM, sizeof(ETSEvent));
1787 if (!s_wps_queue) {
1788 wpa_printf(MSG_ERROR, "wps task init: failed to alloc queue");
1789 goto _wps_no_mem;
1790 }
1791
1792 wps_rxq_init();
1793
1794 ret = os_task_create(wps_task, "wpsT", WPS_TASK_STACK_SIZE, NULL, 2, &s_wps_task_hdl);
1795 if (TRUE != ret) {
1796 wpa_printf(MSG_ERROR, "wps enable: failed to create task");
1797 goto _wps_no_mem;
1798 }
1799
1800 os_semphr_take(s_wps_task_create_sem, OS_BLOCK);
1801 os_semphr_delete(s_wps_task_create_sem);
1802 s_wps_task_create_sem = NULL;
1803
1804 wpa_printf(MSG_DEBUG, "wifi wps enable: task prio:%d, stack:%d", 2, WPS_TASK_STACK_SIZE);
1805 return ESP_OK;
1806
1807 _wps_no_mem:
1808 wps_task_deinit();
1809 return ESP_ERR_NO_MEM;
1810 }
1811
wps_post_block(uint32_t sig,void * arg)1812 int wps_post_block(uint32_t sig, void *arg)
1813 {
1814 wps_ioctl_param_t param;
1815
1816 param.ret = ESP_FAIL;
1817 param.arg = arg;
1818
1819 if (ESP_OK != wps_post(sig, (uint32_t)¶m)) {
1820 return ESP_FAIL;
1821 }
1822
1823 if (TRUE == os_semphr_take(s_wps_api_sem, OS_BLOCK)) {
1824 return param.ret;
1825 } else {
1826 return ESP_FAIL;
1827 }
1828 }
1829
wps_check_wifi_mode(void)1830 int wps_check_wifi_mode(void)
1831 {
1832 wifi_mode_t mode;
1833 int ret;
1834
1835 ret = esp_wifi_get_mode(&mode);
1836 if (ESP_OK != ret) {
1837 wpa_printf(MSG_ERROR, "wps check wifi mode: failed to get wifi mode ret=%d", ret);
1838 return ESP_FAIL;
1839 }
1840
1841 if (
1842 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
1843 mode == ESP32_WIFI_MODE_AP ||
1844 #endif
1845 mode == ESP32_WIFI_MODE_NULL) {
1846 wpa_printf(MSG_ERROR, "wps check wifi mode: wrong wifi mode=%d ", mode);
1847 return ESP_ERR_WIFI_MODE;
1848 }
1849
1850 return ESP_OK;
1851 }
1852
esp_wifi_wps_enable(const esp_wps_config_t * config)1853 int esp_wifi_wps_enable(const esp_wps_config_t *config)
1854 {
1855 int ret = ESP_OK;
1856 struct wps_sm *sm = gWpsSm;
1857
1858 if (esp_wifi_get_user_init_flag_internal() == 0) {
1859 wpa_printf(MSG_ERROR, "wps enable: wifi not started cannot disable wpsreg");
1860 return ESP_ERR_WIFI_STATE;
1861 }
1862
1863 if (ESP_OK != wps_check_wifi_mode()) {
1864 return ESP_ERR_WIFI_MODE;
1865 }
1866
1867 if (is_dpp_enabled()) {
1868 wpa_printf(MSG_ERROR, "wps enabled failed since DPP is initialized");
1869 return ESP_FAIL;
1870 }
1871
1872 API_MUTEX_TAKE();
1873 if (s_wps_enabled) {
1874 if (sm && os_memcmp(sm->identity, WSC_ID_REGISTRAR, sm->identity_len) == 0) {
1875 wpa_printf(MSG_ERROR, "wps enable: wpsreg already enabled cannot enable wps enrollee");
1876 ret = ESP_ERR_WIFI_MODE;
1877 } else {
1878 wpa_printf(MSG_DEBUG, "wps enable: already enabled");
1879 }
1880 API_MUTEX_GIVE();
1881 return ret;
1882 }
1883
1884 #ifdef USE_WPS_TASK
1885 ret = wps_task_init();
1886 if (ESP_OK != ret) {
1887 API_MUTEX_GIVE();
1888 return ret;
1889 }
1890
1891 ret = wps_post_block(SIG_WPS_ENABLE, (esp_wps_config_t *)config);
1892 if (ESP_OK != ret) {
1893 wps_task_deinit();
1894 API_MUTEX_GIVE();
1895 return ret;
1896 }
1897
1898 s_wps_enabled = true;
1899 wpa_printf(MSG_DEBUG, "wifi wps task: prio:%d, stack:%d", 2, WPS_TASK_STACK_SIZE);
1900 API_MUTEX_GIVE();
1901 return ret;
1902 #else
1903 ret = wifi_wps_enable_internal(config);
1904 API_MUTEX_GIVE();
1905 return ret;
1906 #endif
1907 }
1908
is_wps_enabled(void)1909 bool is_wps_enabled(void)
1910 {
1911 return s_wps_enabled;
1912 }
1913
wifi_wps_enable_internal(const esp_wps_config_t * config)1914 int wifi_wps_enable_internal(const esp_wps_config_t *config)
1915 {
1916 int ret = 0;
1917 struct wpa_sm *wpa_sm = &gWpaSm;
1918
1919 wpa_printf(MSG_DEBUG, "ESP WPS crypto initialize!");
1920 if (config->wps_type == WPS_TYPE_DISABLE) {
1921 wpa_printf(MSG_ERROR, "wps enable: invalid wps type");
1922 return ESP_ERR_WIFI_WPS_TYPE;
1923 }
1924 if (is_dpp_enabled()) {
1925 wpa_printf(MSG_ERROR, "wps enabled failed since DPP is initialized");
1926 return ESP_FAIL;
1927 }
1928 wpa_printf(MSG_DEBUG, "Set factory information.");
1929 ret = wps_set_factory_info(config);
1930 if (ret != 0) {
1931 return ret;
1932 }
1933
1934 wpa_printf(MSG_INFO, "wifi_wps_enable");
1935
1936 wps_set_type(config->wps_type);
1937 wps_set_status(WPS_STATUS_DISABLE);
1938
1939 ret = wifi_station_wps_init(config);
1940
1941 if (ret != 0) {
1942 wps_set_type(WPS_TYPE_DISABLE);
1943 wps_set_status(WPS_STATUS_DISABLE);
1944 return ESP_FAIL;
1945 }
1946 wpa_sm->wpa_sm_wps_disable = esp_wifi_wps_disable;
1947 return ESP_OK;
1948 }
1949
wifi_wps_disable_internal(void)1950 int wifi_wps_disable_internal(void)
1951 {
1952 wps_set_status(WPS_STATUS_DISABLE);
1953
1954 /* Call wps_delete_timer to delete all WPS timer, no timer will call wps_post()
1955 * to post message to wps_task once this function returns.
1956 */
1957 wps_delete_timer();
1958 wifi_station_wps_deinit();
1959 return ESP_OK;
1960 }
1961
esp_wifi_wps_disable(void)1962 int esp_wifi_wps_disable(void)
1963 {
1964 int ret = 0;
1965 int wps_status;
1966 struct wps_sm *wps_sm = gWpsSm;
1967 struct wpa_sm *wpa_sm = &gWpaSm;
1968
1969 if (wps_sm && os_memcmp(wps_sm->identity, WSC_ID_REGISTRAR, wps_sm->identity_len) == 0) {
1970 return ESP_ERR_WIFI_MODE;
1971 }
1972
1973 API_MUTEX_TAKE();
1974
1975 if (!s_wps_enabled) {
1976 wpa_printf(MSG_DEBUG, "wps disable: already disabled");
1977 API_MUTEX_GIVE();
1978 return ESP_OK;
1979 }
1980
1981 wps_status = wps_get_status();
1982 wpa_printf(MSG_INFO, "wifi_wps_disable");
1983 wps_set_type(WPS_TYPE_DISABLE); /* Notify WiFi task */
1984
1985 #ifdef USE_WPS_TASK
1986 ret = wps_post_block(SIG_WPS_DISABLE, 0);
1987 #else
1988 ret = wifi_wps_disable_internal();
1989 #endif
1990
1991 if (ESP_OK != ret) {
1992 wpa_printf(MSG_ERROR, "wps disable: failed to disable wps, ret=%d", ret);
1993 }
1994
1995 /* Only disconnect in case of WPS pending/done */
1996 if ((wps_status == WPS_STATUS_PENDING) || (wps_status == WPS_STATUS_SUCCESS)) {
1997 esp_wifi_disconnect();
1998 }
1999 esp_wifi_set_wps_start_flag_internal(false);
2000 wps_task_deinit();
2001 s_wps_enabled = false;
2002 API_MUTEX_GIVE();
2003 wpa_sm->wpa_sm_wps_disable = NULL;
2004 return ESP_OK;
2005 }
2006
esp_wifi_wps_start(int timeout_ms)2007 int esp_wifi_wps_start(int timeout_ms)
2008 {
2009 if (ESP_OK != wps_check_wifi_mode()) {
2010 return ESP_ERR_WIFI_MODE;
2011 }
2012
2013 API_MUTEX_TAKE();
2014
2015 if (!s_wps_enabled) {
2016 wpa_printf(MSG_ERROR, "wps start: wps not enabled");
2017 API_MUTEX_GIVE();
2018 return ESP_ERR_WIFI_WPS_SM;
2019 }
2020
2021 if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) {
2022 API_MUTEX_GIVE();
2023 return ESP_ERR_WIFI_WPS_TYPE;
2024 }
2025
2026 if (esp_wifi_get_user_init_flag_internal() == 0) {
2027 API_MUTEX_GIVE();
2028 return ESP_ERR_WIFI_STATE;
2029 }
2030
2031 wpa_printf(MSG_DEBUG, "wps scan");
2032 #ifdef USE_WPS_TASK
2033 wps_post_block(SIG_WPS_START, 0);
2034 #else
2035 ic_pp_post(SIG_PP_WPS, 0);
2036 #endif
2037 API_MUTEX_GIVE();
2038 return ESP_OK;
2039 }
2040