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