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