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