1 /*
2  * Copyright 2020-2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "wpl.h"
9 #include "wlan_bt_fw.h"
10 #include "wlan.h"
11 #include "wifi.h"
12 #include "wm_net.h"
13 #include <wm_os.h>
14 #include "dhcp-server.h"
15 #include <stdio.h>
16 #include "event_groups.h"
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 #define MAX_JSON_NETWORK_RECORD_LENGTH 185
23 
24 #define WPL_SYNC_TIMEOUT_MS portMAX_DELAY
25 
26 #define UAP_NETWORK_NAME "uap-network"
27 
28 #define EVENT_BIT(event) (1 << event)
29 
30 #define WPL_SYNC_INIT_GROUP EVENT_BIT(WLAN_REASON_INITIALIZED) | EVENT_BIT(WLAN_REASON_INITIALIZATION_FAILED)
31 
32 #define WPL_SYNC_CONNECT_GROUP                                                                  \
33     EVENT_BIT(WLAN_REASON_SUCCESS) | EVENT_BIT(WLAN_REASON_CONNECT_FAILED) |                    \
34         EVENT_BIT(WLAN_REASON_NETWORK_NOT_FOUND) | EVENT_BIT(WLAN_REASON_NETWORK_AUTH_FAILED) | \
35         EVENT_BIT(WLAN_REASON_ADDRESS_FAILED)
36 
37 #define WPL_SYNC_DISCONNECT_GROUP EVENT_BIT(WLAN_REASON_USER_DISCONNECT)
38 
39 #define WPL_SYNC_UAP_START_GROUP EVENT_BIT(WLAN_REASON_UAP_SUCCESS) | EVENT_BIT(WLAN_REASON_UAP_START_FAILED)
40 
41 #define WPL_SYNC_UAP_STOP_GROUP EVENT_BIT(WLAN_REASON_UAP_STOPPED) | EVENT_BIT(WLAN_REASON_UAP_STOP_FAILED)
42 
43 #define EVENT_SCAN_DONE     23
44 #define WPL_SYNC_SCAN_GROUP EVENT_BIT(EVENT_SCAN_DONE)
45 
46 typedef enum _wpl_state
47 {
48     WPL_NOT_INITIALIZED,
49     WPL_INITIALIZED,
50     WPL_STARTED,
51 } wpl_state_t;
52 
53 /*******************************************************************************
54  * Variables
55  ******************************************************************************/
56 static wpl_state_t s_wplState            = WPL_NOT_INITIALIZED;
57 static bool s_wplStaConnected            = false;
58 static bool s_wplUapActivated            = false;
59 static EventGroupHandle_t s_wplSyncEvent = NULL;
60 static linkLostCb_t s_linkLostCb         = NULL;
61 static char *ssids_json                  = NULL;
62 
63 /*******************************************************************************
64  * Prototypes
65  ******************************************************************************/
66 int wlan_event_callback(enum wlan_event_reason reason, void *data);
67 static int WLP_process_results(unsigned int count);
68 
69 /*******************************************************************************
70  * Code
71  ******************************************************************************/
72 /* Callback Function passed to WLAN Connection Manager. The callback function
73  * gets called when there are WLAN Events that need to be handled by the
74  * application.
75  */
wlan_event_callback(enum wlan_event_reason reason,void * data)76 int wlan_event_callback(enum wlan_event_reason reason, void *data)
77 {
78 #ifdef WPL_DEBUG
79     PRINTF("-------- wlan_event_callback %d --------\r\n", reason);
80 #endif
81     if (s_wplState >= WPL_INITIALIZED)
82     {
83         xEventGroupSetBits(s_wplSyncEvent, EVENT_BIT(reason));
84     }
85 
86     switch (reason)
87     {
88         case WLAN_REASON_SUCCESS:
89             if (s_wplStaConnected)
90             {
91                 s_linkLostCb(true);
92             }
93             break;
94 
95         case WLAN_REASON_AUTH_SUCCESS:
96             break;
97 
98         case WLAN_REASON_CONNECT_FAILED:
99         case WLAN_REASON_NETWORK_NOT_FOUND:
100         case WLAN_REASON_NETWORK_AUTH_FAILED:
101             if (s_wplStaConnected)
102             {
103                 s_linkLostCb(false);
104             }
105             break;
106 
107         case WLAN_REASON_ADDRESS_SUCCESS:
108             break;
109         case WLAN_REASON_ADDRESS_FAILED:
110             break;
111         case WLAN_REASON_LINK_LOST:
112             if (s_wplStaConnected)
113             {
114                 s_linkLostCb(false);
115             }
116             break;
117 
118         case WLAN_REASON_CHAN_SWITCH:
119             break;
120         case WLAN_REASON_WPS_DISCONNECT:
121             break;
122         case WLAN_REASON_USER_DISCONNECT:
123             break;
124         case WLAN_REASON_INITIALIZED:
125             break;
126         case WLAN_REASON_INITIALIZATION_FAILED:
127             break;
128         case WLAN_REASON_PS_ENTER:
129             break;
130         case WLAN_REASON_PS_EXIT:
131             break;
132         case WLAN_REASON_UAP_SUCCESS:
133             break;
134 
135         case WLAN_REASON_UAP_CLIENT_ASSOC:
136 #ifdef WPL_DEBUG
137             PRINTF("Client => ");
138             print_mac((const char *)data);
139             PRINTF("Associated with Soft AP\r\n");
140 #endif
141             break;
142         case WLAN_REASON_UAP_CLIENT_DISSOC:
143 #ifdef WPL_DEBUG
144             PRINTF("Client => ");
145             print_mac((const char *)data);
146             PRINTF("Dis-Associated from Soft AP\r\n");
147 #endif
148             break;
149 
150         case WLAN_REASON_UAP_START_FAILED:
151             break;
152         case WLAN_REASON_UAP_STOP_FAILED:
153             break;
154         case WLAN_REASON_UAP_STOPPED:
155             break;
156         default:
157 #ifdef WPL_DEBUG
158             PRINTF("Unknown Wifi CB Reason %d\r\n", reason);
159 #endif
160             break;
161     }
162 
163     return WM_SUCCESS;
164 }
165 
WPL_Init(void)166 wpl_ret_t WPL_Init(void)
167 {
168     wpl_ret_t status = WPLRET_SUCCESS;
169     int ret;
170 
171     if (s_wplState != WPL_NOT_INITIALIZED)
172     {
173         status = WPLRET_FAIL;
174     }
175 
176     if (status == WPLRET_SUCCESS)
177     {
178         if (s_wplSyncEvent == NULL)
179         {
180             s_wplSyncEvent = xEventGroupCreate();
181         }
182 
183         if (s_wplSyncEvent == NULL)
184         {
185             status = WPLRET_FAIL;
186         }
187     }
188 
189     if (status == WPLRET_SUCCESS)
190     {
191         ret = wlan_init(wlan_fw_bin, wlan_fw_bin_len);
192         if (ret != WM_SUCCESS)
193         {
194             status = WPLRET_FAIL;
195         }
196     }
197 
198     if (status == WPLRET_SUCCESS)
199     {
200         s_wplState = WPL_INITIALIZED;
201     }
202 
203     return status;
204 }
205 
WPL_Start(linkLostCb_t callbackFunction)206 wpl_ret_t WPL_Start(linkLostCb_t callbackFunction)
207 {
208     wpl_ret_t status = WPLRET_SUCCESS;
209     int ret;
210     EventBits_t syncBit;
211 
212     if (s_wplState != WPL_INITIALIZED)
213     {
214         status = WPLRET_NOT_READY;
215     }
216 
217     if (status == WPLRET_SUCCESS)
218     {
219         xEventGroupClearBits(s_wplSyncEvent, WPL_SYNC_INIT_GROUP);
220 
221         ret = wlan_start(wlan_event_callback);
222         if (ret != WM_SUCCESS)
223         {
224             status = WPLRET_FAIL;
225         }
226     }
227 
228     if (status == WPLRET_SUCCESS)
229     {
230         syncBit = xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_INIT_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
231         if (syncBit & EVENT_BIT(WLAN_REASON_INITIALIZED))
232         {
233             s_linkLostCb = callbackFunction;
234             status       = WPLRET_SUCCESS;
235         }
236         else if (syncBit & EVENT_BIT(WLAN_REASON_INITIALIZATION_FAILED))
237         {
238             status = WPLRET_FAIL;
239         }
240         else
241         {
242             status = WPLRET_TIMEOUT;
243         }
244     }
245 
246     if (status == WPLRET_SUCCESS)
247     {
248         s_wplState = WPL_STARTED;
249     }
250 
251     return status;
252 }
253 
WPL_Stop(void)254 wpl_ret_t WPL_Stop(void)
255 {
256     wpl_ret_t status = WPLRET_SUCCESS;
257     int ret;
258 
259     if (s_wplState != WPL_STARTED)
260     {
261         status = WPLRET_NOT_READY;
262     }
263 
264     if (status == WPLRET_SUCCESS)
265     {
266         ret = wlan_stop();
267         if (ret != WM_SUCCESS)
268         {
269             status = WPLRET_FAIL;
270         }
271     }
272 
273     if (status == WPLRET_SUCCESS)
274     {
275         s_wplState = WPL_INITIALIZED;
276     }
277 
278     return status;
279 }
280 
WPL_Start_AP(char * ssid,char * password,int chan)281 wpl_ret_t WPL_Start_AP(char *ssid, char *password, int chan)
282 {
283     wpl_ret_t status = WPLRET_SUCCESS;
284     int ret;
285     enum wlan_security_type security = WLAN_SECURITY_NONE;
286     EventBits_t syncBit;
287     struct wlan_network uap_network;
288 
289     if ((s_wplState != WPL_STARTED) || (s_wplUapActivated != false))
290     {
291         status = WPLRET_NOT_READY;
292     }
293 
294     if (status == WPLRET_SUCCESS)
295     {
296         if ((strlen(ssid) == 0) || (strlen(ssid) > IEEEtypes_SSID_SIZE))
297         {
298             status = WPLRET_BAD_PARAM;
299         }
300     }
301 
302     if (status == WPLRET_SUCCESS)
303     {
304         if (strlen(password) == 0)
305         {
306             security = WLAN_SECURITY_NONE;
307         }
308         else if ((strlen(password) >= WPL_WIFI_PASSWORD_MIN_LEN) && (strlen(password) <= WPL_WIFI_PASSWORD_LENGTH))
309         {
310             security = WLAN_SECURITY_WPA2;
311         }
312         else
313         {
314             status = WPLRET_BAD_PARAM;
315         }
316     }
317 
318     if (status == WPLRET_SUCCESS)
319     {
320         wlan_initialize_uap_network(&uap_network);
321 
322         memcpy(uap_network.ssid, ssid, strlen(ssid));
323         uap_network.ip.ipv4.address  = ipaddr_addr(WPL_WIFI_AP_IP_ADDR);
324         uap_network.ip.ipv4.gw       = ipaddr_addr(WPL_WIFI_AP_IP_ADDR);
325         uap_network.channel          = chan;
326         uap_network.security.type    = security;
327         uap_network.security.psk_len = strlen(password);
328         strncpy(uap_network.security.psk, password, strlen(password));
329     }
330 
331     if (status == WPLRET_SUCCESS)
332     {
333         ret = wlan_add_network(&uap_network);
334         if (ret != WM_SUCCESS)
335         {
336             status = WPLRET_FAIL;
337         }
338     }
339 
340     if (status == WPLRET_SUCCESS)
341     {
342         xEventGroupClearBits(s_wplSyncEvent, WPL_SYNC_UAP_START_GROUP);
343 
344         ret = wlan_start_network(uap_network.name);
345         if (ret != WM_SUCCESS)
346         {
347             status = WPLRET_FAIL;
348         }
349         else
350         {
351             syncBit =
352                 xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_UAP_START_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
353             if (syncBit & EVENT_BIT(WLAN_REASON_UAP_SUCCESS))
354             {
355                 status = WPLRET_SUCCESS;
356             }
357             else if (syncBit & EVENT_BIT(WLAN_REASON_UAP_START_FAILED))
358             {
359                 status = WPLRET_FAIL;
360             }
361             else
362             {
363                 status = WPLRET_TIMEOUT;
364             }
365         }
366 
367         if (status != WPLRET_SUCCESS)
368         {
369             wlan_remove_network(uap_network.name);
370         }
371     }
372 
373     if (status == WPLRET_SUCCESS)
374     {
375         ret = dhcp_server_start(net_get_uap_handle());
376         if (ret != WM_SUCCESS)
377         {
378             wlan_stop_network(uap_network.name);
379             wlan_remove_network(uap_network.name);
380             status = WPLRET_FAIL;
381         }
382     }
383 
384     if (status == WPLRET_SUCCESS)
385     {
386         s_wplUapActivated = true;
387     }
388 
389     return status;
390 }
391 
WPL_Stop_AP(void)392 wpl_ret_t WPL_Stop_AP(void)
393 {
394     wpl_ret_t status = WPLRET_SUCCESS;
395     int ret;
396     EventBits_t syncBit;
397 
398     if ((s_wplState != WPL_STARTED) || (s_wplUapActivated != true))
399     {
400         status = WPLRET_NOT_READY;
401     }
402 
403     if (status == WPLRET_SUCCESS)
404     {
405         dhcp_server_stop();
406 
407         xEventGroupClearBits(s_wplSyncEvent, WPL_SYNC_UAP_START_GROUP);
408 
409         ret = wlan_stop_network(UAP_NETWORK_NAME);
410         if (ret != WM_SUCCESS)
411         {
412             status = WPLRET_FAIL;
413         }
414         else
415         {
416             syncBit =
417                 xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_UAP_STOP_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
418             if (syncBit & EVENT_BIT(WLAN_REASON_UAP_STOPPED))
419             {
420                 status = WPLRET_SUCCESS;
421             }
422             else if (syncBit & EVENT_BIT(WLAN_REASON_UAP_STOP_FAILED))
423             {
424                 status = WPLRET_FAIL;
425             }
426             else
427             {
428                 status = WPLRET_TIMEOUT;
429             }
430         }
431     }
432 
433     if (status == WPLRET_SUCCESS)
434     {
435         ret = wlan_remove_network(UAP_NETWORK_NAME);
436         if (ret != WM_SUCCESS)
437         {
438             status = WPLRET_FAIL;
439         }
440     }
441 
442     if (status == WPLRET_SUCCESS)
443     {
444         s_wplUapActivated = false;
445     }
446 
447     return status;
448 }
449 
WLP_process_results(unsigned int count)450 static int WLP_process_results(unsigned int count)
451 {
452     int ret                             = 0;
453     struct wlan_scan_result scan_result = {0};
454     uint32_t ssids_json_len             = count * MAX_JSON_NETWORK_RECORD_LENGTH;
455 
456     /* Add length of "{"networks":[]}" */
457     ssids_json_len += 15;
458 
459     ssids_json = pvPortMalloc(ssids_json_len);
460     if (ssids_json == NULL)
461     {
462         PRINTF("[!] Memory allocation failed\r\n");
463         xEventGroupSetBits(s_wplSyncEvent, EVENT_BIT(EVENT_SCAN_DONE));
464         return WM_FAIL;
465     }
466 
467     /* Start building JSON */
468     strcpy(ssids_json, "{\"networks\":[");
469     uint32_t ssids_json_idx = strlen(ssids_json);
470 
471     for (int i = 0; i < count; i++)
472     {
473         wlan_get_scan_result(i, &scan_result);
474 
475         PRINTF("%s\r\n", scan_result.ssid);
476         PRINTF("     BSSID         : %02X:%02X:%02X:%02X:%02X:%02X\r\n", (unsigned int)scan_result.bssid[0],
477                (unsigned int)scan_result.bssid[1], (unsigned int)scan_result.bssid[2],
478                (unsigned int)scan_result.bssid[3], (unsigned int)scan_result.bssid[4],
479                (unsigned int)scan_result.bssid[5]);
480         PRINTF("     RSSI          : %ddBm\r\n", -(int)scan_result.rssi);
481         PRINTF("     Channel       : %d\r\n", (int)scan_result.channel);
482 
483         char security[40];
484         security[0] = '\0';
485 
486         if (scan_result.wpa2_entp)
487         {
488             strcat(security, "WPA2_ENTP ");
489         }
490         if (scan_result.wep)
491         {
492             strcat(security, "WEP ");
493         }
494         if (scan_result.wpa)
495         {
496             strcat(security, "WPA ");
497         }
498         if (scan_result.wpa2)
499         {
500             strcat(security, "WPA2 ");
501         }
502         if (scan_result.wpa3_sae)
503         {
504             strcat(security, "WPA3_SAE ");
505         }
506 
507         if (i != 0)
508         {
509             /* Add ',' separator before next entry */
510             ssids_json[ssids_json_idx++] = ',';
511         }
512 
513         ret = snprintf(
514             ssids_json + ssids_json_idx, ssids_json_len - ssids_json_idx - 1,
515             "{\"ssid\":\"%s\",\"bssid\":\"%02X:%02X:%02X:%02X:%02X:%02X\",\"signal\":\"%ddBm\",\"channel\":%d,"
516             "\"security\":\"%s\"}",
517             scan_result.ssid, (unsigned int)scan_result.bssid[0], (unsigned int)scan_result.bssid[1],
518             (unsigned int)scan_result.bssid[2], (unsigned int)scan_result.bssid[3], (unsigned int)scan_result.bssid[4],
519             (unsigned int)scan_result.bssid[5], -(int)scan_result.rssi, (int)scan_result.channel, security);
520         if (ret > 0)
521         {
522             ssids_json_idx += ret;
523         }
524         else
525         {
526             PRINTF("[!] JSON creation failed\r\n");
527             vPortFree(ssids_json);
528             ssids_json = NULL;
529             xEventGroupSetBits(s_wplSyncEvent, EVENT_BIT(EVENT_SCAN_DONE));
530             return WM_FAIL;
531         }
532     }
533 
534     /* End of JSON "]}" */
535     strcpy(ssids_json + ssids_json_idx, "]}");
536 
537     xEventGroupSetBits(s_wplSyncEvent, EVENT_BIT(EVENT_SCAN_DONE));
538     return WM_SUCCESS;
539 }
540 
WPL_Scan(void)541 char *WPL_Scan(void)
542 {
543     wpl_ret_t status = WPLRET_SUCCESS;
544     int ret;
545     EventBits_t syncBit;
546 
547     if (s_wplState != WPL_STARTED)
548     {
549         status = WPLRET_NOT_READY;
550     }
551 
552     if (status == WPLRET_SUCCESS)
553     {
554         ret = wlan_scan(WLP_process_results);
555         if (ret != WM_SUCCESS)
556         {
557             status = WPLRET_FAIL;
558         }
559     }
560 
561     if (status == WPLRET_SUCCESS)
562     {
563         syncBit = xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_SCAN_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
564         if (syncBit & EVENT_BIT(EVENT_SCAN_DONE))
565         {
566             status = WPLRET_SUCCESS;
567         }
568         else
569         {
570             status = WPLRET_TIMEOUT;
571         }
572     }
573 
574     if (status == WPLRET_SUCCESS)
575     {
576         return ssids_json;
577     }
578 
579     return NULL;
580 }
581 
WPL_AddNetworkWithSecurity(char * ssid,char * password,char * label,wpl_security_t security)582 wpl_ret_t WPL_AddNetworkWithSecurity(char *ssid, char *password, char *label, wpl_security_t security)
583 {
584     wpl_ret_t status = WPLRET_SUCCESS;
585     int ret;
586     struct wlan_network sta_network;
587     memset(&sta_network, 0, sizeof(struct wlan_network));
588 
589     if (s_wplState != WPL_STARTED)
590     {
591         status = WPLRET_NOT_READY;
592     }
593 
594     if (status == WPLRET_SUCCESS)
595     {
596         if ((strlen(label) == 0) || (strlen(label) > (WLAN_NETWORK_NAME_MAX_LENGTH - 1)))
597         {
598             status = WPLRET_BAD_PARAM;
599         }
600     }
601 
602     if (status == WPLRET_SUCCESS)
603     {
604         if ((strlen(ssid) == 0) || (strlen(ssid) > IEEEtypes_SSID_SIZE))
605         {
606             status = WPLRET_BAD_PARAM;
607         }
608     }
609 
610     if (status == WPLRET_SUCCESS)
611     {
612         size_t password_len = strlen(password);
613 
614         if (password_len == 0)
615         {
616             sta_network.security.type = WLAN_SECURITY_NONE;
617         }
618         else if ((password_len >= WPL_WIFI_PASSWORD_MIN_LEN) && (password_len <= WPL_WIFI_PASSWORD_LENGTH))
619         {
620             switch (security)
621             {
622                 case WPL_SECURITY_WILDCARD:
623                     sta_network.security.type = WLAN_SECURITY_WILDCARD;
624                     sta_network.security.mfpc = true;
625                     sta_network.security.mfpr = true;
626                     sta_network.security.password_len = password_len;
627                     strncpy(sta_network.security.password, password, password_len);
628                     sta_network.security.psk_len = password_len;
629                     strncpy(sta_network.security.psk, password, password_len);
630                     break;
631                 case WPL_SECURITY_WPA3_SAE:
632                     sta_network.security.type = WLAN_SECURITY_WPA3_SAE;
633                     sta_network.security.mfpc = true;
634                     sta_network.security.mfpr = true;
635                     sta_network.security.password_len = strlen(password);
636                     strncpy(sta_network.security.password, password, strlen(password));
637                     break;
638                 default:
639                     PRINTF("[!] Unimplemented security type (%d)\r\n", security);
640                     status = WPLRET_BAD_PARAM;
641                     break;
642             }
643         }
644         else
645         {
646             status = WPLRET_BAD_PARAM;
647         }
648     }
649 
650     strcpy(sta_network.name, label);
651     strcpy(sta_network.ssid, ssid);
652     sta_network.ip.ipv4.addr_type = ADDR_TYPE_DHCP;
653     sta_network.ssid_specific     = 1;
654 
655     if (status == WPLRET_SUCCESS)
656     {
657         ret = wlan_add_network(&sta_network);
658         if (ret != WM_SUCCESS)
659         {
660             status = WPLRET_FAIL;
661         }
662     }
663 
664     return status;
665 }
666 
WPL_AddNetwork(char * ssid,char * password,char * label)667 wpl_ret_t WPL_AddNetwork(char *ssid, char *password, char *label)
668 {
669     return WPL_AddNetworkWithSecurity(ssid, password, label, WPL_SECURITY_WILDCARD);
670 }
671 
WPL_RemoveNetwork(char * label)672 wpl_ret_t WPL_RemoveNetwork(char *label)
673 {
674     wpl_ret_t status = WPLRET_SUCCESS;
675     int ret;
676 
677     if (s_wplState != WPL_STARTED)
678     {
679         status = WPLRET_NOT_READY;
680     }
681 
682     if (status == WPLRET_SUCCESS)
683     {
684         if ((strlen(label) == 0) || (strlen(label) > (WLAN_NETWORK_NAME_MAX_LENGTH - 1)))
685         {
686             status = WPLRET_BAD_PARAM;
687         }
688     }
689 
690     if (status == WPLRET_SUCCESS)
691     {
692         ret = wlan_remove_network(label);
693         if (ret != WM_SUCCESS)
694         {
695             status = WPLRET_FAIL;
696         }
697     }
698 
699     return status;
700 }
701 
WPL_Join(char * label)702 wpl_ret_t WPL_Join(char *label)
703 {
704     wpl_ret_t status = WPLRET_SUCCESS;
705     int ret;
706     EventBits_t syncBit;
707 
708     if ((s_wplState != WPL_STARTED) || (s_wplStaConnected != false))
709     {
710         status = WPLRET_NOT_READY;
711     }
712 
713     if (status == WPLRET_SUCCESS)
714     {
715         if ((strlen(label) == 0) || (strlen(label) > (WLAN_NETWORK_NAME_MAX_LENGTH - 1)))
716         {
717             status = WPLRET_BAD_PARAM;
718         }
719     }
720 
721     if (status == WPLRET_SUCCESS)
722     {
723         xEventGroupClearBits(s_wplSyncEvent, WPL_SYNC_CONNECT_GROUP);
724 
725         ret = wlan_connect(label);
726         if (ret != WM_SUCCESS)
727         {
728             status = WPLRET_FAIL;
729         }
730     }
731 
732     if (status == WPLRET_SUCCESS)
733     {
734         syncBit = xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_CONNECT_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
735         if (syncBit & EVENT_BIT(WLAN_REASON_SUCCESS))
736         {
737             status = WPLRET_SUCCESS;
738         }
739         else if (syncBit & EVENT_BIT(WLAN_REASON_CONNECT_FAILED))
740         {
741             status = WPLRET_FAIL;
742         }
743         else if (syncBit & EVENT_BIT(WLAN_REASON_NETWORK_NOT_FOUND))
744         {
745             status = WPLRET_NOT_FOUND;
746         }
747         else if (syncBit & EVENT_BIT(WLAN_REASON_NETWORK_AUTH_FAILED))
748         {
749             status = WPLRET_AUTH_FAILED;
750         }
751         else if (syncBit & EVENT_BIT(WLAN_REASON_ADDRESS_FAILED))
752         {
753             status = WPLRET_ADDR_FAILED;
754         }
755         else
756         {
757             status = WPLRET_TIMEOUT;
758         }
759 
760         if (status != WPLRET_SUCCESS)
761         {
762             /* Abort the next connection attempt */
763             WPL_Leave();
764         }
765     }
766 
767     if (status == WPLRET_SUCCESS)
768     {
769         s_wplStaConnected = true;
770     }
771 
772     return status;
773 }
774 
WPL_Leave(void)775 wpl_ret_t WPL_Leave(void)
776 {
777     wpl_ret_t status = WPLRET_SUCCESS;
778     int ret;
779     EventBits_t syncBit;
780 
781     if (s_wplState != WPL_STARTED)
782     {
783         status = WPLRET_NOT_READY;
784     }
785 
786     enum wlan_connection_state connection_state = WLAN_DISCONNECTED;
787     wlan_get_connection_state(&connection_state);
788     if (connection_state == WLAN_DISCONNECTED)
789     {
790         s_wplStaConnected = false;
791         return WPLRET_SUCCESS;
792     }
793 
794     if (status == WPLRET_SUCCESS)
795     {
796         xEventGroupClearBits(s_wplSyncEvent, WPL_SYNC_DISCONNECT_GROUP);
797 
798         ret = wlan_disconnect();
799         if (ret != WM_SUCCESS)
800         {
801             status = WPLRET_FAIL;
802         }
803     }
804 
805     if (status == WPLRET_SUCCESS)
806     {
807         syncBit = xEventGroupWaitBits(s_wplSyncEvent, WPL_SYNC_DISCONNECT_GROUP, pdTRUE, pdFALSE, WPL_SYNC_TIMEOUT_MS);
808         if (syncBit & EVENT_BIT(WLAN_REASON_USER_DISCONNECT))
809         {
810             status = WPLRET_SUCCESS;
811         }
812         else
813         {
814             status = WPLRET_TIMEOUT;
815         }
816     }
817 
818     s_wplStaConnected = false;
819 
820     return status;
821 }
822 
WPL_GetIP(char * ip,int client)823 wpl_ret_t WPL_GetIP(char *ip, int client)
824 {
825     wpl_ret_t status = WPLRET_SUCCESS;
826     int ret;
827     struct wlan_ip_config addr;
828 
829     if (ip == NULL)
830     {
831         status = WPLRET_FAIL;
832     }
833 
834     if (status == WPLRET_SUCCESS)
835     {
836         if (client)
837         {
838             ret = wlan_get_address(&addr);
839         }
840         else
841         {
842             ret = wlan_get_uap_address(&addr);
843         }
844 
845         if (ret == WM_SUCCESS)
846         {
847             net_inet_ntoa(addr.ipv4.address, ip);
848         }
849         else
850         {
851             status = WPLRET_FAIL;
852         }
853     }
854 
855     return status;
856 }
857