瀏覽代碼

Modify wlan framework (#5076)

* update auto connect use sys work.
* add fast connect.
* update wlan cmd, support scan result report user-level callback.

Co-authored-by: zetingxu <zetingxu@bestechnic.com>
Co-authored-by: liu2guang <liuguang@rt-thread.com>
Co-authored-by: guodi <guodi@rt-thread.com>
Co-authored-by: geniusgogo <xpxyr@sina.com>
Chester guo 2 年之前
父節點
當前提交
1e27372e3e

+ 262 - 34
components/drivers/wlan/wlan_cmd.c

@@ -9,10 +9,22 @@
  */
 
 #include <rtthread.h>
+#include <rthw.h>
 #include <wlan_mgnt.h>
 #include <wlan_cfg.h>
 #include <wlan_prot.h>
 
+#define DBG_TAG "WLAN.cmd"
+#ifdef RT_WLAN_MGNT_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_MGNT_DEBUG */
+#include <rtdbg.h>
+
+static struct rt_wlan_scan_result scan_result;
+static struct rt_wlan_info *scan_filter = RT_NULL;
+
 #if defined(RT_WLAN_MANAGE_ENABLE) && defined(RT_WLAN_MSH_CMD_ENABLE)
 
 struct wifi_cmd_des
@@ -142,46 +154,192 @@ static int wifi_status(int argc, char *argv[])
     return 0;
 }
 
-static int wifi_scan(int argc, char *argv[])
+
+static rt_bool_t wifi_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
 {
-    struct rt_wlan_scan_result *scan_result = RT_NULL;
-    struct rt_wlan_info *info = RT_NULL;
-    struct rt_wlan_info filter;
+    rt_bool_t is_equ = 1;
+    rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
 
-    if (argc > 3)
-        return -1;
+    if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
+    {
+        is_equ &= info2->security == info1->security;
+    }
+    if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
+    {
+        is_equ &= info1->ssid.len == info2->ssid.len;
+        is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
+    }
+    if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
+       (rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
+    {
+        is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
+    }
+    if (is_equ && info1->datarate && info2->datarate)
+    {
+        is_equ &= info1->datarate == info2->datarate;
+    }
+    if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
+    {
+        is_equ &= info1->channel == info2->channel;
+    }
+    if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
+    {
+        is_equ &= info1->rssi == info2->rssi;
+    }
+    return is_equ;
+}
 
-    if (argc == 3)
+static rt_err_t wifi_scan_result_cache(struct rt_wlan_info *info)
+{
+    struct rt_wlan_info *ptable;
+    rt_err_t err = RT_EOK;
+    int i, insert = -1;
+    rt_base_t level;
+
+    if ((info == RT_NULL) || (info->ssid.len == 0)) return -RT_EINVAL;
+
+    LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
+                  info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
+
+    /* scanning result filtering */
+    level = rt_hw_interrupt_disable();
+    if (scan_filter)
     {
-        INVALID_INFO(&filter);
-        SSID_SET(&filter, argv[2]);
-        info = &filter;
+        struct rt_wlan_info _tmp_info = *scan_filter;
+        rt_hw_interrupt_enable(level);
+        if (wifi_info_isequ(&_tmp_info, info) != RT_TRUE)
+        {
+            return RT_EOK;
+        }
+    }
+    else
+    {
+        rt_hw_interrupt_enable(level);
     }
 
-    /* clean scan result */
-    rt_wlan_scan_result_clean();
-    /* scan ap info */
-    scan_result = rt_wlan_scan_with_info(info);
-    if (scan_result)
+    /* de-duplicatio */
+    for (i = 0; i < scan_result.num; i++)
+    {
+        if ((info->ssid.len == scan_result.info[i].ssid.len) &&
+                (rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
+        {
+            return RT_EOK;
+        }
+#ifdef RT_WLAN_SCAN_SORT
+        if (insert >= 0)
+        {
+            continue;
+        }
+        /* Signal intensity comparison */
+        if ((info->rssi < 0) && (scan_result.info[i].rssi < 0))
+        {
+            if (info->rssi > scan_result.info[i].rssi)
+            {
+                insert = i;
+                continue;
+            }
+            else if (info->rssi < scan_result.info[i].rssi)
+            {
+                continue;
+            }
+        }
+
+        /* Channel comparison */
+        if (info->channel < scan_result.info[i].channel)
+        {
+            insert = i;
+            continue;
+        }
+        else if (info->channel > scan_result.info[i].channel)
+        {
+            continue;
+        }
+
+        /* data rate comparison */
+        if ((info->datarate > scan_result.info[i].datarate))
+        {
+            insert = i;
+            continue;
+        }
+        else if (info->datarate < scan_result.info[i].datarate)
+        {
+            continue;
+        }
+#endif
+    }
+
+    /* Insert the end */
+    if (insert == -1)
+        insert = scan_result.num;
+
+    if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM)
+        return RT_EOK;
+
+    /* malloc memory */
+    ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1));
+    if (ptable == RT_NULL)
+    {
+        LOG_E("wlan info malloc failed!");
+        return -RT_ENOMEM;
+    }
+    scan_result.num ++;
+
+    /* copy info */
+    for (i = 0; i < scan_result.num; i++)
     {
-        int index, num;
+        if (i < insert)
+        {
+            ptable[i] = scan_result.info[i];
+        }
+        else if (i > insert)
+        {
+            ptable[i] = scan_result.info[i - 1];
+        }
+        else if (i == insert)
+        {
+            ptable[i] = *info;
+        }
+    }
+    rt_free(scan_result.info);
+    scan_result.info = ptable;
+    return err;
+}
+
+
+
+static void wifi_scan_result_clean(void)
+{
+
+    /* If there is data */
+    if (scan_result.num)
+    {
+        scan_result.num = 0;
+        rt_free(scan_result.info);
+        scan_result.info = RT_NULL;
+    }
+}
+
+static void print_ap_info(struct rt_wlan_info *info,int index)
+{
         char *security;
 
-        num = scan_result->num;
-        rt_kprintf("             SSID                      MAC            security    rssi chn Mbps\n");
-        rt_kprintf("------------------------------- -----------------  -------------- ---- --- ----\n");
-        for (index = 0; index < num; index ++)
+        if(index == 0)
+        {
+            rt_kprintf("             SSID                      MAC            security    rssi chn Mbps\n");
+            rt_kprintf("------------------------------- -----------------  -------------- ---- --- ----\n");
+        }
+
         {
-            rt_kprintf("%-32.32s", &scan_result->info[index].ssid.val[0]);
+            rt_kprintf("%-32.32s", &(info->ssid.val[0]));
             rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x  ",
-                       scan_result->info[index].bssid[0],
-                       scan_result->info[index].bssid[1],
-                       scan_result->info[index].bssid[2],
-                       scan_result->info[index].bssid[3],
-                       scan_result->info[index].bssid[4],
-                       scan_result->info[index].bssid[5]
+                       info->bssid[0],
+                       info->bssid[1],
+                       info->bssid[2],
+                       info->bssid[3],
+                       info->bssid[4],
+                       info->bssid[5]
                       );
-            switch (scan_result->info[index].security)
+            switch (info->security)
             {
             case SECURITY_OPEN:
                 security = "OPEN";
@@ -218,15 +376,85 @@ static int wifi_scan(int argc, char *argv[])
                 break;
             }
             rt_kprintf("%-14.14s ", security);
-            rt_kprintf("%-4d ", scan_result->info[index].rssi);
-            rt_kprintf("%3d ", scan_result->info[index].channel);
-            rt_kprintf("%4d\n", scan_result->info[index].datarate / 1000000);
+            rt_kprintf("%-4d ", info->rssi);
+            rt_kprintf("%3d ", info->channel);
+            rt_kprintf("%4d\n", info->datarate / 1000000);
+        }
+
+}
+
+static void user_ap_info_callback(int event, struct rt_wlan_buff *buff, void *parameter)
+{
+    struct rt_wlan_info *info = RT_NULL;
+    int index = 0;
+    int ret = RT_EOK;
+
+    RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT);
+    RT_ASSERT(buff != RT_NULL);
+    RT_ASSERT(parameter != RT_NULL);
+
+    info = (struct rt_wlan_info *)buff->data;
+    index = *((int *)(parameter));
+
+    ret = wifi_scan_result_cache(info);
+    if(ret == RT_EOK)
+    {
+        if(scan_filter == RT_NULL ||
+                (scan_filter != RT_NULL &&
+                 scan_filter->ssid.len == info->ssid.len &&
+                 rt_memcmp(&scan_filter->ssid.val[0], &info->ssid.val[0], scan_filter->ssid.len) == 0))
+        {
+            /*Print the info*/
+            print_ap_info(info,index);
+
+            index++;
+            *((int *)(parameter)) = index;
         }
-        rt_wlan_scan_result_clean();
     }
-    else
+
+}
+static int wifi_scan(int argc, char *argv[])
+{
+    struct rt_wlan_info *info = RT_NULL;
+    struct rt_wlan_info filter;
+    int ret = 0;
+    int i = 0;
+
+    if (argc > 3)
+        return -1;
+
+    if (argc == 3)
+    {
+        INVALID_INFO(&filter);
+        SSID_SET(&filter, argv[2]);
+        info = &filter;
+    }
+
+    ret = rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT,user_ap_info_callback,&i);
+    if(ret != RT_EOK)
+    {
+        LOG_E("Scan register user callback error:%d!\n",ret);
+        return 0;
+    }
+
+    if(info)
+    {
+        scan_filter = info;
+    }
+
+
+    /*Todo: what can i do for it return val */
+    ret = rt_wlan_scan_with_info(info);
+    if(ret != RT_EOK)
+    {
+        LOG_E("Scan with info error:%d!\n",ret);
+    }
+
+    /* clean scan result */
+    wifi_scan_result_clean();
+    if(info)
     {
-        rt_kprintf("wifi scan result is null\n");
+        scan_filter = RT_NULL;
     }
     return 0;
 }

+ 64 - 0
components/drivers/wlan/wlan_dev.c

@@ -120,6 +120,41 @@ rt_err_t rt_wlan_dev_connect(struct rt_wlan_device *device, struct rt_wlan_info
     return result;
 }
 
+rt_err_t rt_wlan_dev_fast_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len)
+{
+    rt_err_t result = RT_EOK;
+    struct rt_wlan_buff buff;
+
+    int len = 0;
+
+    if (device == RT_NULL)
+    {
+        return -RT_EIO;
+    }
+    if (info == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+
+    if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) ||
+            (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH))
+    {
+        LOG_E("L:%d password or ssid is too long", __LINE__);
+        return -RT_ERROR;
+    }
+
+    buff.len = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_FAST_CONNECT_INFO, buff.data);
+    if(buff.len < 0)
+    {
+        LOG_D("L:%d Can't get fast connect info", __LINE__);
+        return buff.len;
+    }
+
+    result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_FAST_CONNECT, &buff);
+
+    return result;
+}
+
 rt_err_t rt_wlan_dev_disconnect(struct rt_wlan_device *device)
 {
     rt_err_t result = RT_EOK;
@@ -848,6 +883,35 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
             err = wlan->ops->wlan_get_mac(wlan, mac);
         break;
     }
+    case RT_WLAN_CMD_GET_FAST_CONNECT_INFO:
+    {
+
+        LOG_D("%s %d cmd[%d]:%s  run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_FAST_INFO, "RT_WLAN_CMD_GET_FAST_INFO");
+        if (wlan->ops->wlan_get_fast_info)
+        {
+            err = wlan->ops->wlan_get_fast_info(args);
+        }
+        else
+        {
+            err = -RT_EEMPTY;
+        }
+        break;
+    }
+    case RT_WLAN_CMD_FAST_CONNECT:
+    {
+        struct rt_wlan_buff *buff = (struct rt_wlan_buff *)args;
+        LOG_D("%s %d cmd[%d]:%s  run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_FAST_CONNECT, "RT_WLAN_CMD_FAST_CONNECT");
+        if (wlan->ops->wlan_get_fast_info)
+        {
+            err = wlan->ops->wlan_fast_connect(buff->data,buff->len);
+        }
+        else
+        {
+            err = -RT_EEMPTY;
+        }
+        break;
+    }
+
     default:
         LOG_D("%s %d cmd[%d]:%s  run......", __FUNCTION__, __LINE__, -1, "UNKUOWN");
         break;

+ 6 - 1
components/drivers/wlan/wlan_dev.h

@@ -44,7 +44,9 @@ typedef enum
     RT_WLAN_CMD_SET_COUNTRY,
     RT_WLAN_CMD_GET_COUNTRY,
     RT_WLAN_CMD_SET_MAC,
-    RT_WLAN_CMD_GET_MAC
+    RT_WLAN_CMD_GET_MAC,
+    RT_WLAN_CMD_GET_FAST_CONNECT_INFO,
+    RT_WLAN_CMD_FAST_CONNECT,
 } rt_wlan_cmd_t;
 
 typedef enum
@@ -509,6 +511,8 @@ struct rt_wlan_dev_ops
     int (*wlan_recv)(struct rt_wlan_device *wlan, void *buff, int len);
     int (*wlan_send)(struct rt_wlan_device *wlan, void *buff, int len);
     int (*wlan_send_raw_frame)(struct rt_wlan_device *wlan, void *buff, int len);
+    int (*wlan_get_fast_info)(void *data);
+    rt_err_t (*wlan_fast_connect)(void *data,rt_int32_t len);
 };
 
 /*
@@ -520,6 +524,7 @@ rt_err_t rt_wlan_dev_init(struct rt_wlan_device *device, rt_wlan_mode_t mode);
  * wlan device station interface
  */
 rt_err_t rt_wlan_dev_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len);
+rt_err_t rt_wlan_dev_fast_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len);
 rt_err_t rt_wlan_dev_disconnect(struct rt_wlan_device *device);
 int rt_wlan_dev_get_rssi(struct rt_wlan_device *device);
 

+ 99 - 352
components/drivers/wlan/wlan_mgnt.c

@@ -16,6 +16,7 @@
 #include <wlan_prot.h>
 #include <wlan_workqueue.h>
 
+// #define RT_WLAN_MGNT_DEBUG
 #define DBG_TAG "WLAN.mgnt"
 #ifdef RT_WLAN_MGNT_DEBUG
 #define DBG_LVL DBG_LOG
@@ -38,9 +39,6 @@
 #define STA_DEVICE()  (_sta_mgnt.device)
 #define AP_DEVICE()  (_ap_mgnt.device)
 
-#define SRESULT_LOCK()    (rt_mutex_take(&scan_result_mutex, RT_WAITING_FOREVER))
-#define SRESULT_UNLOCK()  (rt_mutex_release(&scan_result_mutex))
-
 #define STAINFO_LOCK()    (rt_mutex_take(&sta_info_mutex, RT_WAITING_FOREVER))
 #define STAINFO_UNLOCK()  (rt_mutex_release(&sta_info_mutex))
 
@@ -53,6 +51,7 @@
 #ifdef RT_WLAN_AUTO_CONNECT_ENABLE
 #define TIME_STOP()    (rt_timer_stop(&reconnect_time))
 #define TIME_START()   (rt_timer_start(&reconnect_time))
+static rt_uint32_t id = 0;
 #else
 #define TIME_STOP()
 #define TIME_START()
@@ -108,8 +107,6 @@ static struct rt_mutex mgnt_mutex;
 static struct rt_wlan_mgnt_des _sta_mgnt;
 static struct rt_wlan_mgnt_des _ap_mgnt;
 
-static struct rt_wlan_scan_result scan_result;
-static struct rt_mutex scan_result_mutex;
 
 static struct rt_wlan_sta_des sta_info;
 static struct rt_mutex sta_info_mutex;
@@ -118,7 +115,6 @@ static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX];
 
 static struct rt_wlan_complete_des *complete_tab[5];
 static struct rt_mutex complete_mutex;
-static struct rt_wlan_info *scan_filter;
 
 #ifdef RT_WLAN_AUTO_CONNECT_ENABLE
 static struct rt_timer reconnect_time;
@@ -155,40 +151,6 @@ rt_inline rt_bool_t _is_do_connect(void)
 
 #ifdef RT_WLAN_WORK_THREAD_ENABLE
 
-static rt_bool_t rt_wlan_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
-{
-    rt_bool_t is_equ = 1;
-    rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
-
-    if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
-    {
-        is_equ &= info2->security == info1->security;
-    }
-    if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
-    {
-        is_equ &= info1->ssid.len == info2->ssid.len;
-        is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
-    }
-    if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
-       (rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
-    {
-        is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
-    }
-    if (is_equ && info1->datarate && info2->datarate)
-    {
-        is_equ &= info1->datarate == info2->datarate;
-    }
-    if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
-    {
-        is_equ &= info1->channel == info2->channel;
-    }
-    if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
-    {
-        is_equ &= info1->rssi == info2->rssi;
-    }
-    return is_equ;
-}
-
 static void rt_wlan_mgnt_work(void *parameter)
 {
     struct rt_wlan_msg *msg = parameter;
@@ -276,130 +238,6 @@ static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int le
 }
 #endif
 
-static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout)
-{
-    struct rt_wlan_info *ptable;
-    rt_err_t err = RT_EOK;
-    int i, insert = -1;
-    rt_base_t level;
-
-    if (_sta_is_null() || (info == RT_NULL) || (info->ssid.len == 0)) return RT_EOK;
-
-    RT_WLAN_LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
-                  info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
-
-    err = rt_mutex_take(&scan_result_mutex, rt_tick_from_millisecond(timeout));
-    if (err != RT_EOK)
-        return err;
-
-    /* scanning result filtering */
-    level = rt_hw_interrupt_disable();
-    if (scan_filter)
-    {
-        struct rt_wlan_info _tmp_info = *scan_filter;
-        rt_hw_interrupt_enable(level);
-        if (rt_wlan_info_isequ(&_tmp_info, info) != RT_TRUE)
-        {
-            rt_mutex_release(&scan_result_mutex);
-            return RT_EOK;
-        }
-    }
-    else
-    {
-        rt_hw_interrupt_enable(level);
-    }
-
-    /* de-duplicatio */
-    for (i = 0; i < scan_result.num; i++)
-    {
-        if ((info->ssid.len == scan_result.info[i].ssid.len) &&
-                (rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
-        {
-            rt_mutex_release(&scan_result_mutex);
-            return RT_EOK;
-        }
-#ifdef RT_WLAN_SCAN_SORT
-        if (insert >= 0)
-        {
-            continue;
-        }
-        /* Signal intensity comparison */
-        if ((info->rssi < 0) && (scan_result.info[i].rssi < 0))
-        {
-            if (info->rssi > scan_result.info[i].rssi)
-            {
-                insert = i;
-                continue;
-            }
-            else if (info->rssi < scan_result.info[i].rssi)
-            {
-                continue;
-            }
-        }
-
-        /* Channel comparison */
-        if (info->channel < scan_result.info[i].channel)
-        {
-            insert = i;
-            continue;
-        }
-        else if (info->channel > scan_result.info[i].channel)
-        {
-            continue;
-        }
-
-        /* data rate comparison */
-        if ((info->datarate > scan_result.info[i].datarate))
-        {
-            insert = i;
-            continue;
-        }
-        else if (info->datarate < scan_result.info[i].datarate)
-        {
-            continue;
-        }
-#endif
-    }
-
-    /* Insert the end */
-    if (insert == -1)
-        insert = scan_result.num;
-
-    if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM)
-        return RT_EOK;
-
-    /* malloc memory */
-    ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1));
-    if (ptable == RT_NULL)
-    {
-        rt_mutex_release(&scan_result_mutex);
-        RT_WLAN_LOG_E("wlan info malloc failed!");
-        return -RT_ENOMEM;
-    }
-    scan_result.num ++;
-
-    /* copy info */
-    for (i = 0; i < scan_result.num; i++)
-    {
-        if (i < insert)
-        {
-            ptable[i] = scan_result.info[i];
-        }
-        else if (i > insert)
-        {
-            ptable[i] = scan_result.info[i - 1];
-        }
-        else if (i == insert)
-        {
-            ptable[i] = *info;
-        }
-    }
-    rt_free(scan_result.info);
-    scan_result.info = ptable;
-    rt_mutex_release(&scan_result_mutex);
-    return err;
-}
-
 static rt_err_t rt_wlan_sta_info_add(struct rt_wlan_info *info, int timeout)
 {
     struct rt_wlan_sta_list *sta_list;
@@ -500,7 +338,6 @@ static rt_err_t rt_wlan_sta_info_del_all(int timeout)
 #ifdef RT_WLAN_AUTO_CONNECT_ENABLE
 static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
 {
-    static rt_uint32_t id = 0;
     struct rt_wlan_cfg_info cfg_info;
     char *password = RT_NULL;
     rt_base_t level;
@@ -544,24 +381,19 @@ exit:
 
 static void rt_wlan_cyclic_check(void *parameter)
 {
-    struct rt_workqueue *workqueue;
     static struct rt_work work;
     rt_base_t level;
 
     if ((_is_do_connect() == RT_TRUE) && (work.work_func == RT_NULL))
     {
-        workqueue = rt_wlan_get_workqueue();
-        if (workqueue != RT_NULL)
+        level = rt_hw_interrupt_disable();
+        rt_work_init(&work, rt_wlan_auto_connect_run, RT_NULL);
+        rt_hw_interrupt_enable(level);
+        if(rt_work_submit(&work,RT_TICK_PER_SECOND) != RT_EOK)
         {
             level = rt_hw_interrupt_disable();
-            rt_work_init(&work, rt_wlan_auto_connect_run, RT_NULL);
+            rt_memset(&work, 0, sizeof(struct rt_work));
             rt_hw_interrupt_enable(level);
-            if (rt_workqueue_dowork(workqueue, &work) != RT_EOK)
-            {
-                level = rt_hw_interrupt_disable();
-                rt_memset(&work, 0, sizeof(struct rt_work));
-                rt_hw_interrupt_enable(level);
-            }
         }
     }
 }
@@ -584,6 +416,9 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
     case RT_WLAN_DEV_EVT_CONNECT:
     {
         RT_WLAN_LOG_D("event: CONNECT");
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
+        id = 0;
+#endif
         _sta_mgnt.state |= RT_WLAN_STATE_CONNECT;
         _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
         user_event = RT_WLAN_EVT_STA_CONNECTED;
@@ -591,6 +426,23 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
         user_buff.data = &_sta_mgnt.info;
         user_buff.len = sizeof(struct rt_wlan_info);
         RT_WLAN_LOG_I("wifi connect success ssid:%s", &_sta_mgnt.info.ssid.val[0]);
+
+#ifdef RT_WLAN_CFG_ENABLE
+        {
+            struct rt_wlan_cfg_info cfg_info;
+            rt_memset(&cfg_info, 0, sizeof(cfg_info));
+            /* save config */
+            if (rt_wlan_is_connected() == RT_TRUE)
+            {
+                rt_enter_critical();
+                cfg_info.info = _sta_mgnt.info;
+                cfg_info.key = _sta_mgnt.key;
+                rt_exit_critical();
+                RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
+                rt_wlan_cfg_save(&cfg_info);
+            }
+        }
+#endif
         break;
     }
     case RT_WLAN_DEV_EVT_CONNECT_FAIL:
@@ -680,16 +532,11 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
     {
         RT_WLAN_LOG_D("event: SCAN_REPORT");
         user_event = RT_WLAN_EVT_SCAN_REPORT;
-        if (user_buff.len != sizeof(struct rt_wlan_info))
-            break;
-        rt_wlan_scan_result_cache(user_buff.data, 0);
         break;
     }
     case RT_WLAN_DEV_EVT_SCAN_DONE:
     {
         RT_WLAN_LOG_D("event: SCAN_DONE");
-        user_buff.data = &scan_result;
-        user_buff.len = sizeof(scan_result);
         user_event = RT_WLAN_EVT_SCAN_DONE;
         break;
     }
@@ -990,58 +837,40 @@ rt_wlan_mode_t rt_wlan_get_mode(const char *dev_name)
     return mode;
 }
 
-rt_bool_t rt_wlan_find_best_by_cache(const char *ssid, struct rt_wlan_info *info)
+
+static void rt_wlan_join_scan_callback(int event, struct rt_wlan_buff *buff, void *parameter)
 {
-    int i, ssid_len;
-    struct rt_wlan_info *info_best;
-    struct rt_wlan_scan_result *result;
+    struct rt_wlan_info *info = RT_NULL;
+    struct rt_wlan_info *tgt_info = RT_NULL;
+    int ret = RT_EOK;
+
+    RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT);
+    RT_ASSERT(buff != RT_NULL);
+    RT_ASSERT(parameter != RT_NULL);
+
+    info = (struct rt_wlan_info *)buff->data;
+    tgt_info = (struct rt_wlan_info *)parameter;
 
-    ssid_len = rt_strlen(ssid);
-    result = &scan_result;
-    info_best = RT_NULL;
 
-    SRESULT_LOCK();
-    for (i = 0; i < result->num; i++)
+    RT_WLAN_LOG_D("%s info len:%d tgt info len:%d", __FUNCTION__,info->ssid.len,tgt_info->ssid.len);
+    RT_WLAN_LOG_D("%s info ssid:%s tgt info ssid:%s", __FUNCTION__,&info->ssid.val[0],&tgt_info->ssid.val[0]);
+
+    if(rt_memcmp(&info->ssid.val[0], &tgt_info->ssid.val[0], info->ssid.len) == 0 &&
+            info->ssid.len == tgt_info->ssid.len)
     {
-        /* SSID is equal. */
-        if ((result->info[i].ssid.len == ssid_len) &&
-                (rt_memcmp((char *)&result->info[i].ssid.val[0], ssid, ssid_len) == 0))
+        /*Get the rssi the max ap*/
+        if(info->rssi > tgt_info->rssi)
         {
-            if (info_best == RT_NULL)
-            {
-                info_best = &result->info[i];
-                continue;
-            }
-            /* Signal strength effective */
-            if ((result->info[i].rssi < 0) && (info_best->rssi < 0))
-            {
-                /* Find the strongest signal. */
-                if (result->info[i].rssi > info_best->rssi)
-                {
-                    info_best = &result->info[i];
-                    continue;
-                }
-                else if (result->info[i].rssi < info_best->rssi)
-                {
-                    continue;
-                }
-            }
-
-            /* Finding the fastest signal */
-            if (result->info[i].datarate > info_best->datarate)
-            {
-                info_best = &result->info[i];
-                continue;
-            }
+            tgt_info->security  = info->security;
+            tgt_info->band      = info->band;
+            tgt_info->datarate  = info->datarate;
+            tgt_info->channel   = info->channel;
+            tgt_info->rssi      = info->rssi;
+            tgt_info->hidden    = info->hidden;
+            /* hwaddr */
+            rt_memcmp(tgt_info->bssid,info->bssid,RT_WLAN_BSSID_MAX_LENGTH);
         }
     }
-    SRESULT_UNLOCK();
-
-    if (info_best == RT_NULL)
-        return RT_FALSE;
-
-    *info = *info_best;
-    return RT_TRUE;
 }
 
 rt_err_t rt_wlan_connect(const char *ssid, const char *password)
@@ -1080,21 +909,35 @@ rt_err_t rt_wlan_connect(const char *ssid, const char *password)
     /* get info from cache */
     INVALID_INFO(&info);
     MGNT_LOCK();
-    while (scan_retry-- && rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
+
+    rt_memcpy(&info.ssid.val[0],ssid,rt_strlen(ssid));
+    info.ssid.len = rt_strlen(ssid);
+
+#ifdef RT_WLAN_JOIN_SCAN_BY_MGNT
+    err = rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT,rt_wlan_join_scan_callback,&info);
+    if(err != RT_EOK)
     {
-        rt_wlan_scan_sync();
+        LOG_E("Scan register user callback error:%d!\n",err);
+        return err;
+    }
+
+    err = rt_wlan_scan_with_info(&info);
+    if(err != RT_EOK)
+    {
+        LOG_E("Scan with info error:%d!\n",err);
+        return err;
     }
-    rt_wlan_scan_result_clean();
 
-    if (info.ssid.len <= 0)
+    if (info.channel <= 0)
     {
-        RT_WLAN_LOG_W("not find ap! ssid:%s", ssid);
+        RT_WLAN_LOG_W("not find ap! ssid:%s,info.ssid.len=%d", ssid,info.ssid.len);
         MGNT_UNLOCK();
         return -RT_ERROR;
     }
 
     RT_WLAN_LOG_D("find best info ssid:%s mac: %02x %02x %02x %02x %02x %02x",
                   info.ssid.val, info.bssid[0], info.bssid[1], info.bssid[2], info.bssid[3], info.bssid[4], info.bssid[5]);
+#endif
 
     /* create event wait complete */
     complete = rt_wlan_complete_create("join");
@@ -1192,16 +1035,21 @@ rt_err_t rt_wlan_connect_adv(struct rt_wlan_info *info, const char *password)
     rt_exit_critical();
     /* run wifi connect */
     _sta_mgnt.state |= RT_WLAN_STATE_CONNECTING;
-    err = rt_wlan_dev_connect(_sta_mgnt.device, info, password, password_len);
-    if (err != RT_EOK)
+
+    err = rt_wlan_dev_fast_connect(_sta_mgnt.device, info, password, password_len);
+    if(err != RT_EOK)
     {
-        rt_enter_critical();
-        rt_memset(&_sta_mgnt.info, 0, sizeof(struct rt_wlan_ssid));
-        rt_memset(&_sta_mgnt.key, 0, sizeof(struct rt_wlan_key));
-        rt_exit_critical();
-        _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
-        MGNT_UNLOCK();
-        return err;
+        err = rt_wlan_dev_connect(_sta_mgnt.device, info, password, password_len);
+        if (err != RT_EOK)
+        {
+            rt_enter_critical();
+            rt_memset(&_sta_mgnt.info, 0, sizeof(struct rt_wlan_ssid));
+            rt_memset(&_sta_mgnt.key, 0, sizeof(struct rt_wlan_key));
+            rt_exit_critical();
+            _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
+            MGNT_UNLOCK();
+            return err;
+        }
     }
 
     MGNT_UNLOCK();
@@ -1731,35 +1579,22 @@ rt_err_t rt_wlan_scan(void)
     return err;
 }
 
-struct rt_wlan_scan_result *rt_wlan_scan_sync(void)
-{
-    struct rt_wlan_scan_result *result;
-
-    /* Execute synchronous scan function */
-    MGNT_LOCK();
-    result = rt_wlan_scan_with_info(RT_NULL);
-    MGNT_UNLOCK();
-    return result;
-}
-
-struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
+rt_err_t rt_wlan_scan_with_info(struct rt_wlan_info *info)
 {
     rt_err_t err = RT_EOK;
     struct rt_wlan_complete_des *complete;
     rt_uint32_t set = 0, recved = 0;
     static struct rt_wlan_info scan_filter_info;
-    rt_base_t level;
-    struct rt_wlan_scan_result *result;
 
     if (_sta_is_null())
     {
-        return RT_NULL;
+        return -RT_EINVAL;
     }
     RT_WLAN_LOG_D("%s is run", __FUNCTION__);
     if (info != RT_NULL && info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)
     {
         RT_WLAN_LOG_E("ssid is to long!");
-        return RT_NULL;
+        return -RT_EINVAL;
     }
 
     /* Create an event that needs to wait. */
@@ -1768,16 +1603,7 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
     if (complete == RT_NULL)
     {
         MGNT_UNLOCK();
-        return &scan_result;
-    }
-
-    /* add scan info filter */
-    if (info)
-    {
-        scan_filter_info = *info;
-        level = rt_hw_interrupt_disable();
-        scan_filter = &scan_filter_info;
-        rt_hw_interrupt_enable(level);
+        return -RT_EIO;
     }
 
     /* run scan */
@@ -1785,9 +1611,9 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
     if (err != RT_EOK)
     {
         rt_wlan_complete_delete(complete);
+        MGNT_UNLOCK();
         RT_WLAN_LOG_E("scan sync fail");
-        result = RT_NULL;
-        goto scan_exit;
+        return -RT_ERROR;
     }
 
     /* Initializing events that need to wait */
@@ -1799,90 +1625,13 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
     set = 0x1 << RT_WLAN_DEV_EVT_SCAN_DONE;
     if (!(recved & set))
     {
+        MGNT_UNLOCK();
         RT_WLAN_LOG_E("scan wait timeout!");
-        result = &scan_result;
-        goto scan_exit;
-    }
-
-scan_exit:
-    MGNT_UNLOCK();
-    level = rt_hw_interrupt_disable();
-    scan_filter = RT_NULL;
-    rt_hw_interrupt_enable(level);
-    result = &scan_result;
-    return result;
-}
-
-int rt_wlan_scan_get_info_num(void)
-{
-    int num = 0;
-
-    num = scan_result.num;
-    RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, num);
-    return num;
-}
-
-int rt_wlan_scan_get_info(struct rt_wlan_info *info, int num)
-{
-    int _num = 0;
-
-    SRESULT_LOCK();
-    if (scan_result.num && num > 0)
-    {
-        _num = scan_result.num > num ? num : scan_result.num;
-        rt_memcpy(info, scan_result.info, _num * sizeof(struct rt_wlan_info));
+        return -RT_ETIMEOUT;
     }
-    SRESULT_UNLOCK();
-    return _num;
-}
-
-struct rt_wlan_scan_result *rt_wlan_scan_get_result(void)
-{
-    return &scan_result;
-}
 
-void rt_wlan_scan_result_clean(void)
-{
-    MGNT_LOCK();
-    SRESULT_LOCK();
-
-    /* If there is data */
-    if (scan_result.num)
-    {
-        scan_result.num = 0;
-        rt_free(scan_result.info);
-        scan_result.info = RT_NULL;
-    }
-    SRESULT_UNLOCK();
     MGNT_UNLOCK();
-}
-
-int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_info, int num)
-{
-    int i = 0, count = 0;
-    struct rt_wlan_info *scan_info;
-    rt_bool_t is_equ;
-
-    if ((out_info == RT_NULL) || (info == RT_NULL) || (num <= 0))
-    {
-        return 0;
-    }
-    SRESULT_LOCK();
-    /* Traversing the cache to find a qualified hot spot information */
-    for (i = 0; (i < scan_result.num) && (count < num); i++)
-    {
-        scan_info = &scan_result.info[i];
-        is_equ = rt_wlan_info_isequ(scan_info, info);
-        /* Determine whether to find */
-        if (is_equ)
-        {
-            rt_memcpy(&out_info[count], scan_info, sizeof(struct rt_wlan_info));
-            count ++;
-        }
-    }
-    SRESULT_UNLOCK();
-
-    return count;
+    return RT_EOK;
 }
 
 rt_err_t rt_wlan_set_powersave(int level)
@@ -2009,12 +1758,10 @@ int rt_wlan_init(void)
     {
         rt_memset(&_sta_mgnt, 0, sizeof(struct rt_wlan_mgnt_des));
         rt_memset(&_ap_mgnt, 0, sizeof(struct rt_wlan_mgnt_des));
-        rt_memset(&scan_result, 0, sizeof(struct rt_wlan_scan_result));
         rt_memset(&sta_info, 0, sizeof(struct rt_wlan_sta_des));
-        rt_mutex_init(&mgnt_mutex, "mgnt", RT_IPC_FLAG_PRIO);
-        rt_mutex_init(&scan_result_mutex, "scan", RT_IPC_FLAG_PRIO);
-        rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_PRIO);
-        rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_PRIO);
+        rt_mutex_init(&mgnt_mutex, "mgnt", RT_IPC_FLAG_FIFO);
+        rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_FIFO);
+        rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_FIFO);
 #ifdef RT_WLAN_AUTO_CONNECT_ENABLE
         rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL,
                       rt_tick_from_millisecond(AUTO_CONNECTION_PERIOD_MS),

+ 2 - 7
components/drivers/wlan/wlan_mgnt.h

@@ -119,13 +119,8 @@ rt_country_code_t rt_wlan_ap_get_country(void);
  */
 rt_err_t rt_wlan_scan(void);
 struct rt_wlan_scan_result *rt_wlan_scan_sync(void);
-struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info);
-int rt_wlan_scan_get_info_num(void);
-int rt_wlan_scan_get_info(struct rt_wlan_info *info, int num);
-struct rt_wlan_scan_result *rt_wlan_scan_get_result(void);
-void rt_wlan_scan_result_clean(void);
-int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_info, int num);
-rt_bool_t rt_wlan_find_best_by_cache(const char *ssid, struct rt_wlan_info *info);
+rt_err_t rt_wlan_scan_with_info(struct rt_wlan_info *info);
+
 
 /*
  * wifi auto connect interface