xref: /nrf52832-nimble/rt-thread/components/drivers/wlan/wlan_mgnt.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-08-06     tyx          the first version
9  */
10 
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <wlan_dev.h>
14 #include <wlan_cfg.h>
15 #include <wlan_mgnt.h>
16 #include <wlan_prot.h>
17 #include <wlan_workqueue.h>
18 
19 #define DBG_ENABLE
20 #ifdef RT_WLAN_MGNT_DEBUG
21 #define DBG_LEVEL DBG_LOG
22 #else
23 #define DBG_LEVEL DBG_INFO
24 #endif
25 #define DBG_SECTION_NAME  "WLAN.mgnt"
26 #define DBG_COLOR
27 #include <rtdbg.h>
28 
29 #ifndef RT_WLAN_DEVICE
30 #define RT_WLAN_DEVICE(__device) ((struct rt_wlan_device *)__device)
31 #endif
32 
33 #define RT_WLAN_LOG_D(_fmt, ...) LOG_D("L:%d "_fmt"", __LINE__, ##__VA_ARGS__)
34 #define RT_WLAN_LOG_I(...) LOG_I(__VA_ARGS__)
35 #define RT_WLAN_LOG_W(_fmt, ...) LOG_W("F:%s L:%d "_fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__)
36 #define RT_WLAN_LOG_E(_fmt, ...) LOG_E("F:%s L:%d "_fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__)
37 
38 #define STA_DEVICE()  (_sta_mgnt.device)
39 #define AP_DEVICE()  (_ap_mgnt.device)
40 
41 #define SRESULT_LOCK()    (rt_mutex_take(&scan_result_mutex, RT_WAITING_FOREVER))
42 #define SRESULT_UNLOCK()  (rt_mutex_release(&scan_result_mutex))
43 
44 #define STAINFO_LOCK()    (rt_mutex_take(&sta_info_mutex, RT_WAITING_FOREVER))
45 #define STAINFO_UNLOCK()  (rt_mutex_release(&sta_info_mutex))
46 
47 #define MGNT_LOCK()       (rt_mutex_take(&mgnt_mutex, RT_WAITING_FOREVER))
48 #define MGNT_UNLOCK()     (rt_mutex_release(&mgnt_mutex))
49 
50 #define COMPLETE_LOCK()       (rt_mutex_take(&complete_mutex, RT_WAITING_FOREVER))
51 #define COMPLETE_UNLOCK()     (rt_mutex_release(&complete_mutex))
52 
53 #define TIME_STOP()    (rt_timer_stop(&reconnect_time))
54 #define TIME_START()   (rt_timer_start(&reconnect_time))
55 
56 #define DISCONNECT_RESPONSE_TICK    (2000)
57 
58 #if RT_WLAN_EBOX_NUM < 1
59 #error "event box num Too little"
60 #endif
61 
62 struct rt_wlan_mgnt_des
63 {
64     struct rt_wlan_device *device;
65     struct rt_wlan_info info;
66     struct rt_wlan_key key;
67     rt_uint8_t state;
68     rt_uint8_t flags;
69 };
70 
71 struct rt_wlan_event_desc
72 {
73     rt_wlan_event_handler handler;
74     void *parameter;
75 };
76 
77 struct rt_wlan_sta_list
78 {
79     struct rt_wlan_sta_list *next;
80     struct rt_wlan_info info;
81 };
82 
83 struct rt_wlan_sta_des
84 {
85     int num;
86     struct rt_wlan_sta_list *node;
87 };
88 
89 struct rt_wlan_msg
90 {
91     rt_int32_t event;
92     rt_int32_t len;
93     void *buff;
94 };
95 
96 struct rt_wlan_complete_des
97 {
98     struct rt_event complete;
99     rt_uint32_t event_flag;
100     int index;
101 };
102 
103 static struct rt_mutex mgnt_mutex;
104 
105 static struct rt_wlan_mgnt_des _sta_mgnt;
106 static struct rt_wlan_mgnt_des _ap_mgnt;
107 
108 static struct rt_wlan_scan_result scan_result;
109 static struct rt_mutex scan_result_mutex;
110 
111 static struct rt_wlan_sta_des sta_info;
112 static struct rt_mutex sta_info_mutex;
113 
114 static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX];
115 
116 static struct rt_wlan_complete_des *complete_tab[5];
117 static struct rt_mutex complete_mutex;
118 
119 static struct rt_timer reconnect_time;
120 
_sta_is_null(void)121 rt_inline int _sta_is_null(void)
122 {
123     if (_sta_mgnt.device == RT_NULL)
124     {
125         return 1;
126     }
127     return 0;
128 }
129 
_ap_is_null(void)130 rt_inline int _ap_is_null(void)
131 {
132     if (_ap_mgnt.device == RT_NULL)
133     {
134         return 1;
135     }
136     return 0;
137 }
138 
_is_do_connect(void)139 rt_inline rt_bool_t _is_do_connect(void)
140 {
141     if ((rt_wlan_get_autoreconnect_mode() == RT_FALSE) ||
142             (rt_wlan_is_connected() == RT_TRUE) ||
143             (_sta_mgnt.state & RT_WLAN_STATE_CONNECTING))
144     {
145         return RT_FALSE;
146     }
147     return RT_TRUE;
148 }
149 
150 static void rt_wlan_mgnt_work(void *parameter);
151 
rt_wlan_send_msg(rt_wlan_dev_event_t event,void * buff,int len)152 static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
153 {
154     struct rt_wlan_msg *msg;
155 
156     RT_WLAN_LOG_D("F:%s is run event:%d", __FUNCTION__, event);
157 
158     /* Event packing */
159     msg = rt_malloc(sizeof(struct rt_wlan_msg) + len);
160     if (msg == RT_NULL)
161     {
162         RT_WLAN_LOG_E("wlan mgnt send msg err! No memory");
163         return -RT_ENOMEM;
164     }
165     rt_memset(msg, 0, sizeof(struct rt_wlan_msg) + len);
166     msg->event = event;
167     if (len != 0)
168     {
169         msg->buff = ((char *)msg) + sizeof(struct rt_wlan_msg);
170         msg->len = len;
171     }
172 
173     /* send event to wlan thread */
174     if (rt_wlan_workqueue_dowork(rt_wlan_mgnt_work, msg) != RT_EOK)
175     {
176         rt_free(msg);
177         RT_WLAN_LOG_E("wlan mgnt do work fail");
178         return -RT_ERROR;
179     }
180     return RT_EOK;
181 }
182 
rt_wlan_scan_result_cache(struct rt_wlan_info * info,int timeout)183 static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout)
184 {
185     struct rt_wlan_info *ptable;
186     rt_err_t err = RT_EOK;
187     int i, insert = -1;
188 
189     if (_sta_is_null() || (info == RT_NULL)) return RT_EOK;
190 
191     RT_WLAN_LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
192                   info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
193 
194     err = rt_mutex_take(&scan_result_mutex, rt_tick_from_millisecond(timeout));
195     if (err != RT_EOK)
196         return err;
197 
198     /* de-duplicatio */
199     for (i = 0; i < scan_result.num; i++)
200     {
201         if ((info->ssid.len == scan_result.info[i].ssid.len) &&
202                 (rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
203         {
204             rt_mutex_release(&scan_result_mutex);
205             return RT_EOK;
206         }
207 #ifdef RT_WLAN_SCAN_SORT
208         if (insert >= 0)
209         {
210             continue;
211         }
212         /* Signal intensity comparison */
213         if ((info->rssi < 0) && (scan_result.info[i].rssi < 0))
214         {
215             if (info->rssi > scan_result.info[i].rssi)
216             {
217                 insert = i;
218                 continue;
219             }
220             else if (info->rssi < scan_result.info[i].rssi)
221             {
222                 continue;
223             }
224         }
225 
226         /* Channel comparison */
227         if (info->channel < scan_result.info[i].channel)
228         {
229             insert = i;
230             continue;
231         }
232         else if (info->channel > scan_result.info[i].channel)
233         {
234             continue;
235         }
236 
237         /* data rate comparison */
238         if ((info->datarate > scan_result.info[i].datarate))
239         {
240             insert = i;
241             continue;
242         }
243         else if (info->datarate < scan_result.info[i].datarate)
244         {
245             continue;
246         }
247 #endif
248     }
249 
250     /* Insert the end */
251     if (insert == -1)
252         insert = scan_result.num;
253 
254     if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM)
255         return RT_EOK;
256 
257     /* malloc memory */
258     ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1));
259     if (ptable == RT_NULL)
260     {
261         rt_mutex_release(&scan_result_mutex);
262         RT_WLAN_LOG_E("wlan info malloc failed!");
263         return -RT_ENOMEM;
264     }
265     scan_result.num ++;
266 
267     /* copy info */
268     for (i = 0; i < scan_result.num; i++)
269     {
270         if (i < insert)
271         {
272             ptable[i] = scan_result.info[i];
273         }
274         else if (i > insert)
275         {
276             ptable[i] = scan_result.info[i - 1];
277         }
278         else if (i == insert)
279         {
280             ptable[i] = *info;
281         }
282     }
283     rt_free(scan_result.info);
284     scan_result.info = ptable;
285     rt_mutex_release(&scan_result_mutex);
286     return err;
287 }
288 
rt_wlan_sta_info_add(struct rt_wlan_info * info,int timeout)289 static rt_err_t rt_wlan_sta_info_add(struct rt_wlan_info *info, int timeout)
290 {
291     struct rt_wlan_sta_list *sta_list;
292     rt_err_t err = RT_EOK;
293 
294     if (_ap_is_null() || (info == RT_NULL)) return RT_EOK;
295 
296     err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout));
297     if (err == RT_EOK)
298     {
299         /* malloc memory */
300         sta_list = rt_malloc(sizeof(struct rt_wlan_sta_list));
301         if (sta_list == RT_NULL)
302         {
303             rt_mutex_release(&sta_info_mutex);
304             RT_WLAN_LOG_E("sta list malloc failed!");
305             return -RT_ENOMEM;
306         }
307         sta_list->next = RT_NULL;
308         sta_list->info = *info;
309 
310         /* Append sta info */
311         sta_list->next = sta_info.node;
312         sta_info.node = sta_list;
313         /* num++ */
314         sta_info.num ++;
315         rt_mutex_release(&sta_info_mutex);
316         RT_WLAN_LOG_I("sta associated mac:%02x:%02x:%02x:%02x:%02x:%02x",
317                       info->bssid[0], info->bssid[1], info->bssid[2],
318                       info->bssid[3], info->bssid[4], info->bssid[5]);
319     }
320     return err;
321 }
322 
rt_wlan_sta_info_del(struct rt_wlan_info * info,int timeout)323 static rt_err_t rt_wlan_sta_info_del(struct rt_wlan_info *info, int timeout)
324 {
325     struct rt_wlan_sta_list *sta_list, *sta_prve;
326     rt_err_t err = RT_EOK;
327 
328     if (_ap_is_null() || (info == RT_NULL)) return RT_EOK;
329 
330     err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout));
331     if (err == RT_EOK)
332     {
333         /* traversing the list */
334         for (sta_list = sta_info.node, sta_prve = RT_NULL; sta_list != RT_NULL;
335                 sta_prve = sta_list, sta_list = sta_list->next)
336         {
337             /* find mac addr */
338             if (rt_memcmp(&sta_list->info.bssid[0], &info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0)
339             {
340                 if (sta_prve == RT_NULL)
341                 {
342                     sta_info.node = sta_list->next;
343                 }
344                 else
345                 {
346                     sta_prve->next = sta_list->next;
347                 }
348                 sta_info.num --;
349                 rt_free(sta_list);
350                 break;
351             }
352         }
353         rt_mutex_release(&sta_info_mutex);
354         RT_WLAN_LOG_I("sta exit mac:%02x:%02x:%02x:%02x:%02x:%02x",
355                       info->bssid[0], info->bssid[1], info->bssid[2],
356                       info->bssid[3], info->bssid[4], info->bssid[5]);
357     }
358     return err;
359 }
360 
rt_wlan_sta_info_del_all(int timeout)361 static rt_err_t rt_wlan_sta_info_del_all(int timeout)
362 {
363     struct rt_wlan_sta_list *sta_list, *sta_next;
364     rt_err_t err = RT_EOK;
365 
366     err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout));
367     if (err == RT_EOK)
368     {
369         /* traversing the list */
370         for (sta_list = sta_info.node; sta_list != RT_NULL; sta_list = sta_next)
371         {
372             sta_next = sta_list->next;
373             sta_info.num --;
374             rt_free(sta_list);
375         }
376         rt_mutex_release(&sta_info_mutex);
377     }
378     if (sta_info.num != 0)
379     {
380         RT_WLAN_LOG_W("\n\n!!!Program runing exception!!!\n\n");
381     }
382     sta_info.num = 0;
383     sta_info.node = RT_NULL;
384     return err;
385 }
386 
rt_wlan_auto_connect_run(struct rt_work * work,void * parameter)387 static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
388 {
389     static rt_uint32_t id = 0;
390     struct rt_wlan_cfg_info cfg_info;
391     char *password = RT_NULL;
392     rt_base_t level;
393 
394     RT_WLAN_LOG_D("F:%s is run", __FUNCTION__);
395 
396     if (rt_mutex_take(&mgnt_mutex, 0) != RT_EOK)
397         goto exit;
398 
399     /* auto connect status is disable or wifi is connect or connecting, exit */
400     if (_is_do_connect() == RT_FALSE)
401     {
402         id = 0;
403         RT_WLAN_LOG_D("not connection");
404         goto exit;
405     }
406 
407     /* Read the next configuration */
408     rt_memset(&cfg_info, 0, sizeof(struct rt_wlan_cfg_info));
409     if (rt_wlan_cfg_read_index(&cfg_info, id ++) == 0)
410     {
411         RT_WLAN_LOG_D("read cfg fail");
412         id = 0;
413         goto exit;
414     }
415 
416     if (id >= rt_wlan_cfg_get_num()) id = 0;
417 
418     if ((cfg_info.key.len > 0) && (cfg_info.key.len < RT_WLAN_PASSWORD_MAX_LENGTH))
419     {
420         cfg_info.key.val[cfg_info.key.len] = '\0';
421         password = (char *)(&cfg_info.key.val[0]);
422     }
423     rt_wlan_connect_adv(&cfg_info.info, password);
424 exit:
425     rt_mutex_release(&mgnt_mutex);
426     level = rt_hw_interrupt_disable();
427     rt_memset(work, 0, sizeof(struct rt_work));
428     rt_hw_interrupt_enable(level);
429 }
430 
rt_wlan_cyclic_check(void * parameter)431 static void rt_wlan_cyclic_check(void *parameter)
432 {
433     struct rt_workqueue *workqueue;
434     static struct rt_work work;
435     rt_base_t level;
436 
437     if ((_is_do_connect() == RT_TRUE) && (work.work_func == RT_NULL))
438     {
439         workqueue = rt_wlan_get_workqueue();
440         if (workqueue != RT_NULL)
441         {
442             level = rt_hw_interrupt_disable();
443             rt_work_init(&work, rt_wlan_auto_connect_run, RT_NULL);
444             rt_hw_interrupt_enable(level);
445             if (rt_workqueue_dowork(workqueue, &work) != RT_EOK)
446             {
447                 level = rt_hw_interrupt_disable();
448                 rt_memset(&work, 0, sizeof(struct rt_work));
449                 rt_hw_interrupt_enable(level);
450             }
451         }
452     }
453 }
454 
rt_wlan_mgnt_work(void * parameter)455 static void rt_wlan_mgnt_work(void *parameter)
456 {
457     struct rt_wlan_msg *msg = parameter;
458 
459     switch (msg->event)
460     {
461     case RT_WLAN_DEV_EVT_CONNECT:
462     {
463         struct rt_wlan_cfg_info cfg_info;
464 
465         /* save config */
466         if (rt_wlan_is_connected() == RT_TRUE)
467         {
468             rt_enter_critical();
469             cfg_info.info = _sta_mgnt.info;
470             cfg_info.key = _sta_mgnt.key;
471             rt_exit_critical();
472             RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
473             rt_wlan_cfg_save(&cfg_info);
474         }
475         break;
476     }
477     default :
478         break;
479     }
480 
481     rt_free(msg);
482 }
483 
rt_wlan_event_dispatch(struct rt_wlan_device * device,rt_wlan_dev_event_t event,struct rt_wlan_buff * buff,void * parameter)484 static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter)
485 {
486     rt_base_t level;
487     void *user_parameter;
488     rt_wlan_event_handler handler = RT_NULL;
489     rt_err_t err = RT_NULL;
490     rt_wlan_event_t user_event = RT_WLAN_EVT_MAX;
491     int i;
492     struct rt_wlan_buff user_buff = { 0 };
493 
494     if (buff)
495     {
496         user_buff = *buff;
497     }
498     /* Event Handle */
499     switch (event)
500     {
501     case RT_WLAN_DEV_EVT_CONNECT:
502     {
503         RT_WLAN_LOG_D("event: CONNECT");
504         _sta_mgnt.state |= RT_WLAN_STATE_CONNECT;
505         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
506         user_event = RT_WLAN_EVT_STA_CONNECTED;
507         TIME_STOP();
508         rt_wlan_send_msg(event, RT_NULL, 0);
509         user_buff.data = &_sta_mgnt.info;
510         user_buff.len = sizeof(struct rt_wlan_info);
511         RT_WLAN_LOG_I("wifi connect success ssid:%s", &_sta_mgnt.info.ssid.val[0]);
512         break;
513     }
514     case RT_WLAN_DEV_EVT_CONNECT_FAIL:
515     {
516         RT_WLAN_LOG_D("event: CONNECT_FAIL");
517         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECT;
518         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
519         _sta_mgnt.state &= ~RT_WLAN_STATE_READY;
520         user_event = RT_WLAN_EVT_STA_CONNECTED_FAIL;
521         user_buff.data = &_sta_mgnt.info;
522         user_buff.len = sizeof(struct rt_wlan_info);
523         TIME_START();
524         break;
525     }
526     case RT_WLAN_DEV_EVT_DISCONNECT:
527     {
528         RT_WLAN_LOG_D("event: DISCONNECT");
529         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECT;
530         _sta_mgnt.state &= ~RT_WLAN_STATE_READY;
531         user_event = RT_WLAN_EVT_STA_DISCONNECTED;
532         user_buff.data = &_sta_mgnt.info;
533         user_buff.len = sizeof(struct rt_wlan_info);
534         TIME_START();
535         break;
536     }
537     case RT_WLAN_DEV_EVT_AP_START:
538     {
539         RT_WLAN_LOG_D("event: AP_START");
540         _ap_mgnt.state |= RT_WLAN_STATE_ACTIVE;
541         user_event = RT_WLAN_EVT_AP_START;
542         user_buff.data = &_ap_mgnt.info;
543         user_buff.len = sizeof(struct rt_wlan_info);
544         break;
545     }
546     case RT_WLAN_DEV_EVT_AP_STOP:
547     {
548         RT_WLAN_LOG_D("event: AP_STOP");
549         _ap_mgnt.state &= ~RT_WLAN_STATE_ACTIVE;
550         user_event = RT_WLAN_EVT_AP_STOP;
551         err = rt_wlan_sta_info_del_all(RT_WAITING_FOREVER);
552         if (err != RT_NULL)
553         {
554             RT_WLAN_LOG_W("AP_STOP event handle fail");
555         }
556         user_buff.data = &_ap_mgnt.info;
557         user_buff.len = sizeof(struct rt_wlan_info);
558         break;
559     }
560     case RT_WLAN_DEV_EVT_AP_ASSOCIATED:
561     {
562         RT_WLAN_LOG_D("event: ASSOCIATED");
563         user_event = RT_WLAN_EVT_AP_ASSOCIATED;
564         if (user_buff.len != sizeof(struct rt_wlan_info))
565             break;
566         err = rt_wlan_sta_info_add(user_buff.data, RT_WAITING_FOREVER);
567         if (err != RT_EOK)
568         {
569             RT_WLAN_LOG_W("AP_ASSOCIATED event handle fail");
570         }
571         break;
572     }
573     case RT_WLAN_DEV_EVT_AP_DISASSOCIATED:
574     {
575         RT_WLAN_LOG_D("event: DISASSOCIATED");
576         user_event = RT_WLAN_EVT_AP_DISASSOCIATED;
577         if (user_buff.len != sizeof(struct rt_wlan_info))
578             break;
579         err = rt_wlan_sta_info_del(user_buff.data, RT_WAITING_FOREVER);
580         if (err != RT_EOK)
581         {
582             RT_WLAN_LOG_W("AP_DISASSOCIATED event handle fail");
583         }
584         break;
585     }
586     case RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED:
587     {
588         RT_WLAN_LOG_D("event: AP_ASSOCIATE_FAILED");
589         break;
590     }
591     case RT_WLAN_DEV_EVT_SCAN_REPORT:
592     {
593         RT_WLAN_LOG_D("event: SCAN_REPORT");
594         user_event = RT_WLAN_EVT_SCAN_REPORT;
595         if (user_buff.len != sizeof(struct rt_wlan_info))
596             break;
597         rt_wlan_scan_result_cache(user_buff.data, 0);
598         break;
599     }
600     case RT_WLAN_DEV_EVT_SCAN_DONE:
601     {
602         RT_WLAN_LOG_D("event: SCAN_DONE");
603         user_buff.data = &scan_result;
604         user_buff.len = sizeof(scan_result);
605         user_event = RT_WLAN_EVT_SCAN_DONE;
606         break;
607     }
608     default :
609     {
610         RT_WLAN_LOG_D("event: UNKNOWN");
611         return;
612     }
613     }
614 
615     /* send event */
616     COMPLETE_LOCK();
617     for (i = 0; i < sizeof(complete_tab) / sizeof(complete_tab[0]); i++)
618     {
619         if ((complete_tab[i] != RT_NULL))
620         {
621             complete_tab[i]->event_flag |= 0x1 << event;
622             rt_event_send(&complete_tab[i]->complete, 0x1 << event);
623             RT_WLAN_LOG_D("&complete_tab[i]->complete:0x%08x", &complete_tab[i]->complete);
624         }
625     }
626     COMPLETE_UNLOCK();
627     /* Get user callback */
628     if (user_event < RT_WLAN_EVT_MAX)
629     {
630         level = rt_hw_interrupt_disable();
631         handler = event_tab[user_event].handler;
632         user_parameter = event_tab[user_event].parameter;
633         rt_hw_interrupt_enable(level);
634     }
635 
636     /* run user callback fun */
637     if (handler)
638     {
639         handler(user_event, &user_buff, user_parameter);
640     }
641 }
642 
rt_wlan_complete_create(const char * name)643 static struct rt_wlan_complete_des *rt_wlan_complete_create(const char *name)
644 {
645     struct rt_wlan_complete_des *complete;
646     int i;
647 
648     complete = rt_malloc(sizeof(struct rt_wlan_complete_des));
649     if (complete == RT_NULL)
650     {
651         RT_WLAN_LOG_E("complete event create failed");
652         MGNT_UNLOCK();
653         return complete;
654     }
655     rt_event_init(&complete->complete, name, RT_IPC_FLAG_FIFO);
656     complete->event_flag = 0;
657     //protect
658     COMPLETE_LOCK();
659     for (i = 0; i < sizeof(complete_tab) / sizeof(complete_tab[0]); i++)
660     {
661         if (complete_tab[i] == RT_NULL)
662         {
663             complete->index = i;
664             complete_tab[i] = complete;
665             break;
666         }
667     }
668     COMPLETE_UNLOCK();
669 
670     if (i >= sizeof(complete_tab) / sizeof(complete_tab[0]))
671     {
672         rt_event_detach(&complete->complete);
673         rt_free(complete);
674         complete = RT_NULL;
675     }
676 
677     return complete;
678 }
679 
rt_wlan_complete_wait(struct rt_wlan_complete_des * complete,rt_uint32_t event,rt_uint32_t timeout,rt_uint32_t * recved)680 static rt_err_t rt_wlan_complete_wait(struct rt_wlan_complete_des *complete, rt_uint32_t event,
681                                       rt_uint32_t timeout, rt_uint32_t *recved)
682 {
683     if (complete == RT_NULL)
684     {
685         return -RT_ERROR;
686     }
687 
688     /* Check whether there is a waiting event */
689     if (complete->event_flag & event)
690     {
691         *recved = complete->event_flag;
692         return RT_EOK;
693     }
694     else
695     {
696         return rt_event_recv(&complete->complete, event, RT_EVENT_FLAG_OR,
697                              rt_tick_from_millisecond(timeout), recved);
698     }
699 }
700 
rt_wlan_complete_delete(struct rt_wlan_complete_des * complete)701 static void rt_wlan_complete_delete(struct rt_wlan_complete_des *complete)
702 {
703     if (complete == RT_NULL)
704     {
705         return;
706     }
707     COMPLETE_LOCK();
708     complete_tab[complete->index] = RT_NULL;
709     COMPLETE_UNLOCK();
710     rt_event_detach(&complete->complete);
711     rt_free(complete);
712 }
713 
rt_wlan_set_mode(const char * dev_name,rt_wlan_mode_t mode)714 rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode)
715 {
716     rt_device_t device = RT_NULL;
717     rt_err_t err;
718     rt_int8_t up_event_flag = 0;
719     rt_wlan_dev_event_handler handler = RT_NULL;
720 
721     if ((dev_name == RT_NULL) || (mode >= RT_WLAN_MODE_MAX))
722     {
723         RT_WLAN_LOG_E("Parameter Wrongful name:%s mode:%d", dev_name, mode);
724         return -RT_EINVAL;
725     }
726 
727     RT_WLAN_LOG_D("%s is run dev_name:%s mode:%s%s%s", __FUNCTION__, dev_name,
728                   mode == RT_WLAN_NONE ? "NONE" : "",
729                   mode == RT_WLAN_STATION ? "STA" : "",
730                   mode == RT_WLAN_AP ? "AP" : ""
731                  );
732 
733     /* find device */
734     device = rt_device_find(dev_name);
735     if (device == RT_NULL)
736     {
737         RT_WLAN_LOG_E("not find device, set mode failed! name:%s", dev_name);
738         return -RT_EIO;
739     }
740 
741     MGNT_LOCK();
742     if (RT_WLAN_DEVICE(device)->mode == mode)
743     {
744         RT_WLAN_LOG_D("L:%d this device mode is set");
745         MGNT_UNLOCK();
746         return RT_EOK;
747     }
748 
749     if ((mode == RT_WLAN_STATION) &&
750             (RT_WLAN_DEVICE(device)->flags & RT_WLAN_FLAG_AP_ONLY))
751     {
752         RT_WLAN_LOG_I("this device ap mode only");
753         MGNT_UNLOCK();
754         return -RT_ERROR;
755     }
756     else if ((mode == RT_WLAN_AP) &&
757              (RT_WLAN_DEVICE(device)->flags & RT_WLAN_FLAG_STA_ONLY))
758     {
759         RT_WLAN_LOG_I("this device sta mode only");
760         MGNT_UNLOCK();
761         return -RT_ERROR;
762     }
763 
764     /*
765      * device == sta  and change to ap,  should deinit
766      * device == ap   and change to sta, should deinit
767     */
768     if (((mode == RT_WLAN_STATION) && (RT_WLAN_DEVICE(device) == AP_DEVICE())) ||
769             ((mode == RT_WLAN_AP) && (RT_WLAN_DEVICE(device) == STA_DEVICE())))
770     {
771         err = rt_wlan_set_mode(dev_name, RT_WLAN_NONE);
772         if (err != RT_EOK)
773         {
774             RT_WLAN_LOG_E("change mode failed!");
775             MGNT_UNLOCK();
776             return err;
777         }
778     }
779 
780     /* init device */
781     err = rt_wlan_dev_init(RT_WLAN_DEVICE(device), mode);
782     if (err != RT_EOK)
783     {
784         RT_WLAN_LOG_E("F:%s L:%d wlan init failed", __FUNCTION__, __LINE__);
785         MGNT_UNLOCK();
786         return err;
787     }
788 
789     /* the mode is none */
790     if (mode == RT_WLAN_NONE)
791     {
792         if (_sta_mgnt.device == RT_WLAN_DEVICE(device))
793         {
794             _sta_mgnt.device = RT_NULL;
795             _sta_mgnt.state = 0;
796             up_event_flag = 1;
797             handler = RT_NULL;
798         }
799         else if (_ap_mgnt.device == RT_WLAN_DEVICE(device))
800         {
801             _ap_mgnt.state = 0;
802             _ap_mgnt.device = RT_NULL;
803             up_event_flag = 1;
804             handler = RT_NULL;
805         }
806     }
807     /* save sta device */
808     else if (mode == RT_WLAN_STATION)
809     {
810         up_event_flag = 1;
811         handler = rt_wlan_event_dispatch;
812         _sta_mgnt.device = RT_WLAN_DEVICE(device);
813     }
814     /* save ap device */
815     else if (mode == RT_WLAN_AP)
816     {
817         up_event_flag = 1;
818         handler = rt_wlan_event_dispatch;
819         _ap_mgnt.device = RT_WLAN_DEVICE(device);
820     }
821 
822     /* update dev event handle */
823     if (up_event_flag == 1)
824     {
825         rt_wlan_dev_event_t event;
826         for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++)
827         {
828             if (handler)
829             {
830                 rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), event, handler, RT_NULL);
831             }
832             else
833             {
834                 rt_wlan_dev_unregister_event_handler(RT_WLAN_DEVICE(device), event, handler);
835             }
836         }
837     }
838     MGNT_UNLOCK();
839 
840     /* Mount protocol */
841 #ifdef RT_WLAN_DEFAULT_PROT
842     rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT);
843 #endif
844     return err;
845 }
846 
rt_wlan_get_mode(const char * dev_name)847 rt_wlan_mode_t rt_wlan_get_mode(const char *dev_name)
848 {
849     rt_device_t device = RT_NULL;
850     rt_wlan_mode_t mode;
851 
852     if (dev_name == RT_NULL)
853     {
854         RT_WLAN_LOG_E("name is null");
855         return RT_WLAN_NONE;
856     }
857 
858     /* find device */
859     device = rt_device_find(dev_name);
860     if (device == RT_NULL)
861     {
862         RT_WLAN_LOG_E("device not find! name:%s", dev_name);
863         return RT_WLAN_NONE;
864     }
865 
866     /* get mode */
867     mode = RT_WLAN_DEVICE(device)->mode;
868     RT_WLAN_LOG_D("%s is run dev_name:%s mode:%s%s%s", __FUNCTION__, dev_name,
869                   mode == RT_WLAN_NONE ? "NONE" : "",
870                   mode == RT_WLAN_STATION ? "STA" : "",
871                   mode == RT_WLAN_AP ? "AP" : "");
872 
873     return mode;
874 }
875 
rt_wlan_find_best_by_cache(const char * ssid,struct rt_wlan_info * info)876 rt_bool_t rt_wlan_find_best_by_cache(const char *ssid, struct rt_wlan_info *info)
877 {
878     int i, ssid_len;
879     struct rt_wlan_info *info_best;
880     struct rt_wlan_scan_result *result;
881 
882     ssid_len = rt_strlen(ssid);
883     result = &scan_result;
884     info_best = RT_NULL;
885 
886     SRESULT_LOCK();
887     for (i = 0; i < result->num; i++)
888     {
889         /* SSID is equal. */
890         if ((result->info[i].ssid.len == ssid_len) &&
891                 (rt_memcmp((char *)&result->info[i].ssid.val[0], ssid, ssid_len) == 0))
892         {
893             if (info_best == RT_NULL)
894             {
895                 info_best = &result->info[i];
896                 continue;
897             }
898             /* Signal strength effective */
899             if ((result->info[i].rssi < 0) && (info_best->rssi < 0))
900             {
901                 /* Find the strongest signal. */
902                 if (result->info[i].rssi > info_best->rssi)
903                 {
904                     info_best = &result->info[i];
905                     continue;
906                 }
907                 else if (result->info[i].rssi < info_best->rssi)
908                 {
909                     continue;
910                 }
911             }
912 
913             /* Finding the fastest signal */
914             if (result->info[i].datarate > info_best->datarate)
915             {
916                 info_best = &result->info[i];
917                 continue;
918             }
919         }
920     }
921     SRESULT_UNLOCK();
922 
923     if (info_best == RT_NULL)
924         return RT_FALSE;
925 
926     *info = *info_best;
927     return RT_TRUE;
928 }
929 
rt_wlan_connect(const char * ssid,const char * password)930 rt_err_t rt_wlan_connect(const char *ssid, const char *password)
931 {
932     rt_err_t err = RT_EOK;
933     int ssid_len = 0;
934     struct rt_wlan_info info;
935     struct rt_wlan_complete_des *complete;
936     rt_uint32_t set = 0, recved = 0;
937 
938     /* sta dev Can't be NULL */
939     if (_sta_is_null())
940     {
941         return -RT_EIO;
942     }
943     RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, ssid, password);
944     if (ssid == RT_NULL)
945     {
946         RT_WLAN_LOG_E("ssid is null!");
947         return -RT_EINVAL;
948     }
949     ssid_len = rt_strlen(ssid);
950     if (ssid_len > RT_WLAN_SSID_MAX_LENGTH)
951     {
952         RT_WLAN_LOG_E("ssid is to long! ssid:%s len:%d", ssid, ssid_len);
953         return -RT_EINVAL;
954     }
955 
956     if ((rt_wlan_is_connected() == RT_TRUE) &&
957             (rt_strcmp((char *)&_sta_mgnt.info.ssid.val[0], ssid) == 0))
958     {
959         RT_WLAN_LOG_I("wifi is connect ssid:%s", ssid);
960         return RT_EOK;
961     }
962     /* get info from cache */
963     INVALID_INFO(&info);
964     MGNT_LOCK();
965     if (rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
966     {
967         rt_wlan_scan_sync();
968         rt_wlan_find_best_by_cache(ssid, &info);
969         rt_wlan_scan_result_clean();
970     }
971 
972     if (info.ssid.len <= 0)
973     {
974         RT_WLAN_LOG_W("not find ap! ssid:%s", ssid);
975         MGNT_UNLOCK();
976         return -RT_ERROR;
977     }
978 
979     RT_WLAN_LOG_D("find best info ssid:%s mac: %02x %02x %02x %02x %02x %02x",
980                   info.ssid.val, info.bssid[0], info.bssid[1], info.bssid[2], info.bssid[3], info.bssid[4], info.bssid[5]);
981 
982     /* create event wait complete */
983     complete = rt_wlan_complete_create("join");
984     if (complete == RT_NULL)
985     {
986         MGNT_UNLOCK();
987         return -RT_ENOMEM;
988     }
989     /* run connect adv */
990     err = rt_wlan_connect_adv(&info, password);
991     if (err != RT_EOK)
992     {
993         rt_wlan_complete_delete(complete);
994         MGNT_UNLOCK();
995         return err;
996     }
997 
998     /* Initializing events that need to wait */
999     set |= 0x1 << RT_WLAN_DEV_EVT_CONNECT;
1000     set |= 0x1 << RT_WLAN_DEV_EVT_CONNECT_FAIL;
1001     /* Check whether there is a waiting event */
1002     rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved);
1003     rt_wlan_complete_delete(complete);
1004     /* check event */
1005     set = 0x1 << RT_WLAN_DEV_EVT_CONNECT;
1006     if (!(recved & set))
1007     {
1008         RT_WLAN_LOG_I("wifi connect failed!");
1009         MGNT_UNLOCK();
1010         return -RT_ERROR;
1011     }
1012     MGNT_UNLOCK();
1013     return err;
1014 }
1015 
rt_wlan_connect_adv(struct rt_wlan_info * info,const char * password)1016 rt_err_t rt_wlan_connect_adv(struct rt_wlan_info *info, const char *password)
1017 {
1018     int password_len = 0;
1019     rt_err_t err = RT_EOK;
1020 
1021     if (_sta_is_null())
1022     {
1023         return -RT_EIO;
1024     }
1025     if (info == RT_NULL)
1026     {
1027         RT_WLAN_LOG_E("info is null!");
1028         return -RT_EINVAL;
1029     }
1030     RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, info->ssid.val, password);
1031     /* Parameter checking */
1032     if (password != RT_NULL)
1033     {
1034         password_len = rt_strlen(password);
1035         if (password_len > RT_WLAN_PASSWORD_MAX_LENGTH)
1036         {
1037             RT_WLAN_LOG_E("password is to long! password:%s len:%d", password, password_len);
1038             return -RT_EINVAL;
1039         }
1040     }
1041     if (info->ssid.len == 0 || info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)
1042     {
1043         RT_WLAN_LOG_E("ssid is zero or to long! ssid:%s len:%d", info->ssid.val, info->ssid.len);
1044         return -RT_EINVAL;
1045     }
1046     /* is connect ? */
1047     MGNT_LOCK();
1048     if (rt_wlan_is_connected())
1049     {
1050         if ((_sta_mgnt.info.ssid.len == info->ssid.len) &&
1051                 (_sta_mgnt.key.len == password_len) &&
1052                 (rt_memcmp(&_sta_mgnt.info.ssid.val[0], &info->ssid.val[0], info->ssid.len) == 0) &&
1053                 (rt_memcmp(&_sta_mgnt.info.bssid[0], &info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0) &&
1054                 (rt_memcmp(&_sta_mgnt.key.val[0], password, password_len) == 0))
1055         {
1056             RT_WLAN_LOG_I("wifi Already Connected");
1057             MGNT_UNLOCK();
1058             return RT_EOK;
1059         }
1060 
1061         err = rt_wlan_disconnect();
1062         if (err != RT_EOK)
1063         {
1064             MGNT_UNLOCK();
1065             return err;
1066         }
1067     }
1068 
1069     /* save info */
1070     rt_enter_critical();
1071     _sta_mgnt.info = *info;
1072     rt_memcpy(&_sta_mgnt.key.val, password, password_len);
1073     _sta_mgnt.key.len = password_len;
1074     _sta_mgnt.key.val[password_len] = '\0';
1075     rt_exit_critical();
1076     /* run wifi connect */
1077     _sta_mgnt.state |= RT_WLAN_STATE_CONNECTING;
1078     err = rt_wlan_dev_connect(_sta_mgnt.device, info, password, password_len);
1079     if (err != RT_EOK)
1080     {
1081         rt_enter_critical();
1082         rt_memset(&_sta_mgnt.info, 0, sizeof(struct rt_wlan_ssid));
1083         rt_memset(&_sta_mgnt.key, 0, sizeof(struct rt_wlan_key));
1084         rt_exit_critical();
1085         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
1086         MGNT_UNLOCK();
1087         return err;
1088     }
1089 
1090     MGNT_UNLOCK();
1091     return err;
1092 }
1093 
rt_wlan_disconnect(void)1094 rt_err_t rt_wlan_disconnect(void)
1095 {
1096     rt_err_t err;
1097     struct rt_wlan_complete_des *complete;
1098     rt_uint32_t recved = 0, set = 0;
1099 
1100     /* ap dev Can't be empty */
1101     if (_sta_is_null())
1102     {
1103         return -RT_EIO;
1104     }
1105     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1106 
1107     /* run disconnect */
1108     MGNT_LOCK();
1109     /* create event wait complete */
1110     complete = rt_wlan_complete_create("disc");
1111     if (complete == RT_NULL)
1112     {
1113         MGNT_UNLOCK();
1114         return -RT_ENOMEM;
1115     }
1116     err = rt_wlan_dev_disconnect(_sta_mgnt.device);
1117     if (err != RT_EOK)
1118     {
1119         RT_WLAN_LOG_E("wifi disconnect fail");
1120         rt_wlan_complete_delete(complete);
1121         MGNT_UNLOCK();
1122         return err;
1123     }
1124     /* Initializing events that need to wait */
1125     set |= 0x1 << RT_WLAN_DEV_EVT_DISCONNECT;
1126     /* Check whether there is a waiting event */
1127     rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved);
1128     rt_wlan_complete_delete(complete);
1129     /* check event */
1130     set = 0x1 << RT_WLAN_DEV_EVT_DISCONNECT;
1131     if (!(recved & set))
1132     {
1133         RT_WLAN_LOG_E("disconnect failed!");
1134         MGNT_UNLOCK();
1135         return -RT_ERROR;
1136     }
1137     RT_WLAN_LOG_I("disconnect success!");
1138     MGNT_UNLOCK();
1139     return err;
1140 }
1141 
rt_wlan_is_connected(void)1142 rt_bool_t rt_wlan_is_connected(void)
1143 {
1144     rt_bool_t _connect;
1145 
1146     if (_sta_is_null())
1147     {
1148         return RT_FALSE;
1149     }
1150     _connect = _sta_mgnt.state & RT_WLAN_STATE_CONNECT ? RT_TRUE : RT_FALSE;
1151     RT_WLAN_LOG_D("%s is run : %s", __FUNCTION__, _connect ? "connect" : "disconnect");
1152     return _connect;
1153 }
1154 
rt_wlan_is_ready(void)1155 rt_bool_t rt_wlan_is_ready(void)
1156 {
1157     rt_bool_t _ready;
1158 
1159     if (_sta_is_null())
1160     {
1161         return RT_FALSE;
1162     }
1163     _ready = _sta_mgnt.state & RT_WLAN_STATE_READY ? RT_TRUE : RT_FALSE;
1164     RT_WLAN_LOG_D("%s is run : %s", __FUNCTION__, _ready ? "ready" : "not ready");
1165     return _ready;
1166 }
1167 
rt_wlan_set_mac(rt_uint8_t mac[6])1168 rt_err_t rt_wlan_set_mac(rt_uint8_t mac[6])
1169 {
1170     rt_err_t err = RT_EOK;
1171 
1172     if (_sta_is_null())
1173     {
1174         return -RT_EIO;
1175     }
1176     RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x",
1177                   __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1178 
1179     MGNT_LOCK();
1180     err = rt_wlan_dev_set_mac(STA_DEVICE(), mac);
1181     if (err != RT_EOK)
1182     {
1183         RT_WLAN_LOG_E("set sta mac addr fail");
1184         MGNT_UNLOCK();
1185         return err;
1186     }
1187     MGNT_UNLOCK();
1188     return err;
1189 }
1190 
rt_wlan_get_mac(rt_uint8_t mac[6])1191 rt_err_t rt_wlan_get_mac(rt_uint8_t mac[6])
1192 {
1193     rt_err_t err = RT_EOK;
1194 
1195     if (_sta_is_null())
1196     {
1197         return -RT_EIO;
1198     }
1199     MGNT_LOCK();
1200     err = rt_wlan_dev_get_mac(STA_DEVICE(), mac);
1201     if (err != RT_EOK)
1202     {
1203         RT_WLAN_LOG_E("get sta mac addr fail");
1204         MGNT_UNLOCK();
1205         return err;
1206     }
1207     RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x",
1208                   __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1209     MGNT_UNLOCK();
1210     return err;
1211 }
1212 
rt_wlan_get_info(struct rt_wlan_info * info)1213 rt_err_t rt_wlan_get_info(struct rt_wlan_info *info)
1214 {
1215     if (_sta_is_null())
1216     {
1217         return -RT_EIO;
1218     }
1219     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1220 
1221     rt_enter_critical();
1222     *info = _sta_mgnt.info;
1223     rt_exit_critical();
1224     return RT_EOK;
1225 }
1226 
rt_wlan_get_rssi(void)1227 int rt_wlan_get_rssi(void)
1228 {
1229     int rssi = 0;
1230 
1231     if (_sta_is_null())
1232     {
1233         return -RT_EIO;
1234     }
1235 
1236     MGNT_LOCK();
1237     rssi = rt_wlan_dev_get_rssi(STA_DEVICE());
1238     RT_WLAN_LOG_D("%s is run rssi:%d", __FUNCTION__, rssi);
1239     MGNT_UNLOCK();
1240     return rssi;
1241 }
1242 
rt_wlan_start_ap(const char * ssid,const char * password)1243 rt_err_t rt_wlan_start_ap(const char *ssid, const char *password)
1244 {
1245     rt_err_t err = RT_EOK;
1246     int ssid_len = 0;
1247     struct rt_wlan_info info;
1248     struct rt_wlan_complete_des *complete;
1249     rt_uint32_t set = 0, recved = 0;
1250 
1251     if (_ap_is_null())
1252     {
1253         return -RT_EIO;
1254     }
1255     if (ssid == RT_NULL) return -RT_EINVAL;
1256 
1257     rt_memset(&info, 0, sizeof(struct rt_wlan_info));
1258     RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, ssid, password);
1259     if (password)
1260     {
1261         info.security = SECURITY_WPA2_AES_PSK;
1262     }
1263     ssid_len = rt_strlen(ssid);
1264     if (ssid_len > RT_WLAN_SSID_MAX_LENGTH)
1265     {
1266         RT_WLAN_LOG_E("ssid is to long! len:%d", ssid_len);
1267     }
1268 
1269     /* copy info */
1270     rt_memcpy(&info.ssid.val, ssid, ssid_len);
1271     info.ssid.len = ssid_len;
1272     info.channel = 6;
1273 
1274     /* Initializing events that need to wait */
1275     MGNT_LOCK();
1276     /* create event wait complete */
1277     complete = rt_wlan_complete_create("start_ap");
1278     if (complete == RT_NULL)
1279     {
1280         MGNT_UNLOCK();
1281         return -RT_ENOMEM;
1282     }
1283 
1284     /* start ap */
1285     err = rt_wlan_start_ap_adv(&info, password);
1286     if (err != RT_EOK)
1287     {
1288         rt_wlan_complete_delete(complete);
1289         RT_WLAN_LOG_I("start ap failed!");
1290         MGNT_UNLOCK();
1291         return err;
1292     }
1293 
1294     /* Initializing events that need to wait */
1295     set |= 0x1 << RT_WLAN_DEV_EVT_AP_START;
1296     set |= 0x1 << RT_WLAN_DEV_EVT_AP_STOP;
1297     /* Check whether there is a waiting event */
1298     rt_wlan_complete_wait(complete, set, RT_WLAN_START_AP_WAIT_MS, &recved);
1299     rt_wlan_complete_delete(complete);
1300     /* check event */
1301     set = 0x1 << RT_WLAN_DEV_EVT_AP_START;
1302     if (!(recved & set))
1303     {
1304         RT_WLAN_LOG_I("start ap failed!");
1305         MGNT_UNLOCK();
1306         return -RT_ERROR;
1307     }
1308     RT_WLAN_LOG_I("start ap successs!");
1309     MGNT_UNLOCK();
1310     return err;
1311 }
1312 
rt_wlan_start_ap_adv(struct rt_wlan_info * info,const char * password)1313 rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password)
1314 {
1315     rt_err_t err = RT_EOK;
1316     int password_len = 0;
1317 
1318     if (_ap_is_null())
1319     {
1320         return -RT_EIO;
1321     }
1322     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1323     if (password != RT_NULL)
1324     {
1325         password_len = rt_strlen(password);
1326     }
1327     if (password_len > RT_WLAN_PASSWORD_MAX_LENGTH)
1328     {
1329         RT_WLAN_LOG_E("key is to long! len:%d", password_len);
1330         return -RT_EINVAL;
1331     }
1332     /* is start up ? */
1333     MGNT_LOCK();
1334     if (rt_wlan_ap_is_active())
1335     {
1336         if ((_ap_mgnt.info.ssid.len == info->ssid.len) &&
1337                 (_ap_mgnt.info.security == info->security) &&
1338                 (_ap_mgnt.info.channel == info->channel) &&
1339                 (_ap_mgnt.info.hidden == info->hidden) &&
1340                 (_ap_mgnt.key.len == password_len) &&
1341                 (rt_memcmp(&_ap_mgnt.info.ssid.val[0], &info->ssid.val[0], info->ssid.len) == 0) &&
1342                 (rt_memcmp(&_ap_mgnt.key.val[0], password, password_len)))
1343         {
1344             RT_WLAN_LOG_D("wifi Already Start");
1345             MGNT_UNLOCK();
1346             return RT_EOK;
1347         }
1348     }
1349 
1350     err = rt_wlan_dev_ap_start(AP_DEVICE(), info, password, password_len);
1351     if (err != RT_EOK)
1352     {
1353         MGNT_UNLOCK();
1354         return err;
1355     }
1356     rt_memcpy(&_ap_mgnt.info, info, sizeof(struct rt_wlan_info));
1357     rt_memcpy(&_ap_mgnt.key.val, password, password_len);
1358     _ap_mgnt.key.len = password_len;
1359 
1360     MGNT_UNLOCK();
1361     return err;
1362 }
1363 
rt_wlan_ap_is_active(void)1364 rt_bool_t rt_wlan_ap_is_active(void)
1365 {
1366     rt_bool_t _active = RT_FALSE;
1367 
1368     if (_ap_is_null())
1369     {
1370         return RT_FALSE;
1371     }
1372 
1373     _active = _ap_mgnt.state & RT_WLAN_STATE_ACTIVE ? RT_TRUE : RT_FALSE;
1374     RT_WLAN_LOG_D("%s is run active:%s", __FUNCTION__, _active ? "Active" : "Inactive");
1375     return _active;
1376 }
1377 
rt_wlan_ap_stop(void)1378 rt_err_t rt_wlan_ap_stop(void)
1379 {
1380     rt_err_t err = RT_EOK;
1381     struct rt_wlan_complete_des *complete;
1382     rt_uint32_t set = 0, recved = 0;
1383 
1384     if (_ap_is_null())
1385     {
1386         return -RT_EIO;
1387     }
1388     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1389 
1390     MGNT_LOCK();
1391     /* create event wait complete */
1392     complete = rt_wlan_complete_create("stop_ap");
1393     if (complete == RT_NULL)
1394     {
1395         MGNT_UNLOCK();
1396         return -RT_ENOMEM;
1397     }
1398     err = rt_wlan_dev_ap_stop(AP_DEVICE());
1399     if (err != RT_EOK)
1400     {
1401         RT_WLAN_LOG_E("ap stop fail");
1402         rt_wlan_complete_delete(complete);
1403         MGNT_UNLOCK();
1404         return err;
1405     }
1406     /* Initializing events that need to wait */
1407     set |= 0x1 << RT_WLAN_DEV_EVT_AP_STOP;
1408     /* Check whether there is a waiting event */
1409     rt_wlan_complete_wait(complete, set, RT_WLAN_START_AP_WAIT_MS, &recved);
1410     rt_wlan_complete_delete(complete);
1411     /* check event */
1412     set = 0x1 << RT_WLAN_DEV_EVT_AP_STOP;
1413     if (!(recved & set))
1414     {
1415         RT_WLAN_LOG_I("ap stop failed!");
1416         MGNT_UNLOCK();
1417         return -RT_ERROR;
1418     }
1419     RT_WLAN_LOG_I("ap stop success!");
1420     MGNT_UNLOCK();
1421     return err;
1422 }
1423 
rt_wlan_ap_get_info(struct rt_wlan_info * info)1424 rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info)
1425 {
1426     if (_ap_is_null())
1427     {
1428         return -RT_EIO;
1429     }
1430     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1431 
1432     *info = _ap_mgnt.info;
1433     return RT_EOK;
1434 }
1435 
1436 /* get sta number  */
rt_wlan_ap_get_sta_num(void)1437 int rt_wlan_ap_get_sta_num(void)
1438 {
1439     int sta_num = 0;
1440 
1441     STAINFO_LOCK();
1442     sta_num = sta_info.num;
1443     STAINFO_UNLOCK();
1444     RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, sta_num);
1445     return sta_num;
1446 }
1447 
1448 /* get sta info */
rt_wlan_ap_get_sta_info(struct rt_wlan_info * info,int num)1449 int rt_wlan_ap_get_sta_info(struct rt_wlan_info *info, int num)
1450 {
1451     int sta_num = 0, i = 0;
1452     struct rt_wlan_sta_list *sta_list;
1453 
1454     STAINFO_LOCK();
1455     /* sta_num = min(sta_info.num, num) */
1456     sta_num = sta_info.num > num ? num : sta_info.num;
1457     for (sta_list = sta_info.node; sta_list != RT_NULL && i < sta_num; sta_list = sta_list->next)
1458     {
1459         info[i] = sta_list->info;
1460         i ++;
1461     }
1462     STAINFO_UNLOCK();
1463     RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, i);
1464     return i;
1465 }
1466 
1467 /* deauth sta */
rt_wlan_ap_deauth_sta(rt_uint8_t * mac)1468 rt_err_t rt_wlan_ap_deauth_sta(rt_uint8_t *mac)
1469 {
1470     rt_err_t err = RT_EOK;
1471     struct rt_wlan_sta_list *sta_list;
1472     rt_bool_t find_flag = RT_FALSE;
1473 
1474     if (_ap_is_null())
1475     {
1476         return -RT_EIO;
1477     }
1478     RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x:%d",
1479                   __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1480 
1481     if (mac == RT_NULL)
1482     {
1483         RT_WLAN_LOG_E("mac addr is null");
1484         return -RT_EINVAL;
1485     }
1486 
1487     MGNT_LOCK();
1488     if (sta_info.node == RT_NULL || sta_info.num == 0)
1489     {
1490         RT_WLAN_LOG_E("No AP");
1491         MGNT_UNLOCK();
1492         return -RT_ERROR;
1493     }
1494 
1495     STAINFO_LOCK();
1496     /* Search for MAC address from sta list */
1497     for (sta_list = sta_info.node; sta_list != RT_NULL; sta_list = sta_list->next)
1498     {
1499         if (rt_memcmp(&sta_list->info.bssid[0], &mac[0], RT_WLAN_BSSID_MAX_LENGTH) == 0)
1500         {
1501             find_flag = RT_TRUE;
1502             break;
1503         }
1504     }
1505     STAINFO_UNLOCK();
1506 
1507     /* No MAC address was found. return */
1508     if (find_flag != RT_TRUE)
1509     {
1510         RT_WLAN_LOG_E("Not find mac addr");
1511         MGNT_UNLOCK();
1512         return -RT_ERROR;
1513     }
1514 
1515     /* Kill STA */
1516     err = rt_wlan_dev_ap_deauth(AP_DEVICE(), mac);
1517     if (err != RT_NULL)
1518     {
1519         RT_WLAN_LOG_E("deauth sta failed");
1520         MGNT_UNLOCK();
1521         return err;
1522     }
1523 
1524     MGNT_UNLOCK();
1525     return err;
1526 }
1527 
rt_wlan_ap_set_country(rt_country_code_t country_code)1528 rt_err_t rt_wlan_ap_set_country(rt_country_code_t country_code)
1529 {
1530     rt_err_t err = RT_EOK;
1531 
1532     if (_ap_is_null())
1533     {
1534         return -RT_EIO;
1535     }
1536     RT_WLAN_LOG_D("%s is run country:%d", __FUNCTION__, country_code);
1537     MGNT_LOCK();
1538     err = rt_wlan_dev_set_country(AP_DEVICE(), country_code);
1539     MGNT_UNLOCK();
1540     return err;
1541 }
1542 
rt_wlan_ap_get_country(void)1543 rt_country_code_t rt_wlan_ap_get_country(void)
1544 {
1545     rt_country_code_t country_code = RT_COUNTRY_UNKNOWN;
1546 
1547     if (_ap_is_null())
1548     {
1549         return country_code;
1550     }
1551     MGNT_LOCK();
1552     country_code = rt_wlan_dev_get_country(AP_DEVICE());
1553     RT_WLAN_LOG_D("%s is run country:%d", __FUNCTION__, country_code);
1554     MGNT_UNLOCK();
1555     return country_code;
1556 }
1557 
rt_wlan_config_autoreconnect(rt_bool_t enable)1558 void rt_wlan_config_autoreconnect(rt_bool_t enable)
1559 {
1560     RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
1561 
1562     MGNT_LOCK();
1563     if (enable)
1564     {
1565         _sta_mgnt.flags |= RT_WLAN_STATE_AUTOEN;
1566     }
1567     else
1568     {
1569         _sta_mgnt.flags &= ~RT_WLAN_STATE_AUTOEN;
1570     }
1571     MGNT_UNLOCK();
1572 }
1573 
rt_wlan_get_autoreconnect_mode(void)1574 rt_bool_t rt_wlan_get_autoreconnect_mode(void)
1575 {
1576     rt_bool_t enable = 0;
1577 
1578     enable = _sta_mgnt.flags & RT_WLAN_STATE_AUTOEN ? 1 : 0;
1579     RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
1580     return enable;
1581 }
1582 
1583 /* Call the underlying scan function, which is asynchronous.
1584 The hotspots scanned are returned by callbacks */
rt_wlan_scan(void)1585 rt_err_t rt_wlan_scan(void)
1586 {
1587     rt_err_t err = RT_EOK;
1588 
1589     if (_sta_is_null())
1590     {
1591         return -RT_EIO;
1592     }
1593     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1594 
1595     MGNT_LOCK();
1596     err = rt_wlan_dev_scan(STA_DEVICE(), RT_NULL);
1597     MGNT_UNLOCK();
1598     return err;
1599 }
1600 
rt_wlan_scan_sync(void)1601 struct rt_wlan_scan_result *rt_wlan_scan_sync(void)
1602 {
1603     struct rt_wlan_scan_result *result;
1604 
1605     /* Execute synchronous scan function */
1606     MGNT_LOCK();
1607     result = rt_wlan_scan_with_info(RT_NULL);
1608     MGNT_UNLOCK();
1609     return result;
1610 }
1611 
rt_wlan_scan_with_info(struct rt_wlan_info * info)1612 struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
1613 {
1614     rt_err_t err = RT_EOK;
1615     struct rt_wlan_complete_des *complete;
1616     rt_uint32_t set = 0, recved = 0;
1617 
1618     if (_sta_is_null())
1619     {
1620         return RT_NULL;
1621     }
1622     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1623     if (info != RT_NULL && info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)
1624     {
1625         RT_WLAN_LOG_E("ssid is to long!");
1626         return RT_NULL;
1627     }
1628 
1629     /* Create an event that needs to wait. */
1630     MGNT_LOCK();
1631     complete = rt_wlan_complete_create("scan");
1632     if (complete == RT_NULL)
1633     {
1634         MGNT_UNLOCK();
1635         return &scan_result;
1636     }
1637 
1638     /* run scan */
1639     err = rt_wlan_dev_scan(STA_DEVICE(), info);
1640     if (err != RT_EOK)
1641     {
1642         rt_wlan_complete_delete(complete);
1643         RT_WLAN_LOG_E("scan sync fail");
1644         MGNT_UNLOCK();
1645         return RT_NULL;
1646     }
1647 
1648     /* Initializing events that need to wait */
1649     set |= 0x1 << RT_WLAN_DEV_EVT_SCAN_DONE;
1650     /* Check whether there is a waiting event */
1651     rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved);
1652     rt_wlan_complete_delete(complete);
1653     /* check event */
1654     set = 0x1 << RT_WLAN_DEV_EVT_SCAN_DONE;
1655     if (!(recved & set))
1656     {
1657         RT_WLAN_LOG_E("scan wait timeout!");
1658         MGNT_UNLOCK();
1659         return &scan_result;
1660     }
1661 
1662     MGNT_UNLOCK();
1663     return &scan_result;
1664 }
1665 
rt_wlan_scan_get_info_num(void)1666 int rt_wlan_scan_get_info_num(void)
1667 {
1668     int num = 0;
1669 
1670     num = scan_result.num;
1671     RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, num);
1672     return num;
1673 }
1674 
rt_wlan_scan_get_info(struct rt_wlan_info * info,int num)1675 int rt_wlan_scan_get_info(struct rt_wlan_info *info, int num)
1676 {
1677     int _num = 0;
1678 
1679     SRESULT_LOCK();
1680     if (scan_result.num && num > 0)
1681     {
1682         _num = scan_result.num > num ? num : scan_result.num;
1683         rt_memcpy(info, scan_result.info, _num * sizeof(struct rt_wlan_info));
1684     }
1685     SRESULT_UNLOCK();
1686     return _num;
1687 }
1688 
rt_wlan_scan_get_result(void)1689 struct rt_wlan_scan_result *rt_wlan_scan_get_result(void)
1690 {
1691     return &scan_result;
1692 }
1693 
rt_wlan_scan_result_clean(void)1694 void rt_wlan_scan_result_clean(void)
1695 {
1696     MGNT_LOCK();
1697     SRESULT_LOCK();
1698 
1699     /* If there is data */
1700     if (scan_result.num)
1701     {
1702         scan_result.num = 0;
1703         rt_free(scan_result.info);
1704         scan_result.info = RT_NULL;
1705     }
1706     SRESULT_UNLOCK();
1707     MGNT_UNLOCK();
1708 }
1709 
rt_wlan_scan_find_cache(struct rt_wlan_info * info,struct rt_wlan_info * out_info,int num)1710 int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_info, int num)
1711 {
1712     int i = 0, count = 0;
1713     struct rt_wlan_info *scan_info;
1714     rt_bool_t is_equ = 1;
1715     rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
1716 
1717     if ((out_info == RT_NULL) || (info == RT_NULL) || (num <= 0))
1718     {
1719         return 0;
1720     }
1721     SRESULT_LOCK();
1722     /* Traversing the cache to find a qualified hot spot information */
1723     for (i = 0; (i < scan_result.num) && (count < num); i++)
1724     {
1725         scan_info = &scan_result.info[i];
1726 
1727         if (is_equ && (info->security != SECURITY_UNKNOWN))
1728         {
1729             is_equ &= info->security == scan_info->security;
1730         }
1731         if (is_equ && ((info->ssid.len > 0) && (info->ssid.len == scan_info->ssid.len)))
1732         {
1733             is_equ &= rt_memcmp(&info->ssid.val[0], &scan_info->ssid.val[0], scan_info->ssid.len) == 0;
1734         }
1735         if (is_equ && (rt_memcmp(&info->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
1736         {
1737             is_equ &= rt_memcmp(&info->bssid[0], &scan_info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
1738         }
1739         if (is_equ && info->datarate)
1740         {
1741             is_equ &= info->datarate == scan_info->datarate;
1742         }
1743         if (is_equ && (info->channel >= 0))
1744         {
1745             is_equ &= info->channel == scan_info->channel;
1746         }
1747         if (is_equ && (info->rssi < 0))
1748         {
1749             is_equ &= info->rssi == scan_info->rssi;
1750         }
1751         /* Determine whether to find */
1752         if (is_equ)
1753         {
1754             rt_memcpy(&out_info[count], scan_info, sizeof(struct rt_wlan_info));
1755             count ++;
1756         }
1757     }
1758     SRESULT_UNLOCK();
1759 
1760     return count;
1761 }
1762 
rt_wlan_set_powersave(int level)1763 rt_err_t rt_wlan_set_powersave(int level)
1764 {
1765     rt_err_t err = RT_EOK;
1766 
1767     if (_sta_is_null())
1768     {
1769         return -RT_EIO;
1770     }
1771     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1772     MGNT_LOCK();
1773     err = rt_wlan_dev_set_powersave(STA_DEVICE(), level);
1774     MGNT_UNLOCK();
1775     return err;
1776 }
1777 
rt_wlan_get_powersave(void)1778 int rt_wlan_get_powersave(void)
1779 {
1780     int level;
1781 
1782     if (_sta_is_null())
1783     {
1784         return -1;
1785     }
1786     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
1787     MGNT_LOCK();
1788     level = rt_wlan_dev_get_powersave(STA_DEVICE());
1789     MGNT_UNLOCK();
1790     return level;
1791 }
1792 
rt_wlan_register_event_handler(rt_wlan_event_t event,rt_wlan_event_handler handler,void * parameter)1793 rt_err_t rt_wlan_register_event_handler(rt_wlan_event_t event, rt_wlan_event_handler handler, void *parameter)
1794 {
1795     rt_base_t level;
1796 
1797     if (event >= RT_WLAN_EVT_MAX)
1798     {
1799         return RT_EINVAL;
1800     }
1801     RT_WLAN_LOG_D("%s is run event:%d", __FUNCTION__, event);
1802 
1803     MGNT_UNLOCK();
1804     /* Registering Callbacks */
1805     level = rt_hw_interrupt_disable();
1806     event_tab[event].handler = handler;
1807     event_tab[event].parameter = parameter;
1808     rt_hw_interrupt_enable(level);
1809     MGNT_UNLOCK();
1810     return RT_EOK;
1811 }
1812 
rt_wlan_unregister_event_handler(rt_wlan_event_t event)1813 rt_err_t rt_wlan_unregister_event_handler(rt_wlan_event_t event)
1814 {
1815     rt_base_t level;
1816 
1817     if (event >= RT_WLAN_EVT_MAX)
1818     {
1819         return RT_EINVAL;
1820     }
1821     RT_WLAN_LOG_D("%s is run event:%d", __FUNCTION__, event);
1822     MGNT_LOCK();
1823     /* unregister*/
1824     level = rt_hw_interrupt_disable();
1825     event_tab[event].handler = RT_NULL;
1826     event_tab[event].parameter = RT_NULL;
1827     rt_hw_interrupt_enable(level);
1828     MGNT_UNLOCK();
1829     return RT_EOK;
1830 }
1831 
rt_wlan_mgnt_lock(void)1832 void rt_wlan_mgnt_lock(void)
1833 {
1834     MGNT_LOCK();
1835 }
1836 
rt_wlan_mgnt_unlock(void)1837 void rt_wlan_mgnt_unlock(void)
1838 {
1839     MGNT_UNLOCK();
1840 }
1841 
rt_wlan_prot_ready_event(struct rt_wlan_device * wlan,struct rt_wlan_buff * buff)1842 int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff)
1843 {
1844     rt_base_t level;
1845     void *user_parameter;
1846     rt_wlan_event_handler handler = RT_NULL;
1847 
1848     if ((wlan == RT_NULL) || (_sta_mgnt.device != wlan) ||
1849             (!(_sta_mgnt.state & RT_WLAN_STATE_CONNECT)))
1850     {
1851         return -1;
1852     }
1853     if (_sta_mgnt.state & RT_WLAN_STATE_READY)
1854     {
1855         return 0;
1856     }
1857     level = rt_hw_interrupt_disable();
1858     _sta_mgnt.state |= RT_WLAN_STATE_READY;
1859     handler = event_tab[RT_WLAN_EVT_READY].handler;
1860     user_parameter = event_tab[RT_WLAN_EVT_READY].parameter;
1861     rt_hw_interrupt_enable(level);
1862     if (handler)
1863     {
1864         handler(RT_WLAN_EVT_READY, buff, user_parameter);
1865     }
1866     return 0;
1867 }
1868 
rt_wlan_init(void)1869 int rt_wlan_init(void)
1870 {
1871     static rt_int8_t _init_flag = 0;
1872 
1873     /* Execute only once */
1874     if (_init_flag == 0)
1875     {
1876         rt_memset(&_sta_mgnt, 0, sizeof(struct rt_wlan_mgnt_des));
1877         rt_memset(&_ap_mgnt, 0, sizeof(struct rt_wlan_mgnt_des));
1878         rt_memset(&scan_result, 0, sizeof(struct rt_wlan_scan_result));
1879         rt_memset(&sta_info, 0, sizeof(struct rt_wlan_sta_des));
1880         rt_mutex_init(&mgnt_mutex, "mgnt", RT_IPC_FLAG_FIFO);
1881         rt_mutex_init(&scan_result_mutex, "scan", RT_IPC_FLAG_FIFO);
1882         rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_FIFO);
1883         rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_FIFO);
1884         rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL, DISCONNECT_RESPONSE_TICK, RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
1885         rt_timer_start(&reconnect_time);
1886         _init_flag = 1;
1887     }
1888     return 0;
1889 }
1890 INIT_PREV_EXPORT(rt_wlan_init);
1891