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