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