浏览代码

[components][drivers]wlan驱动框架更新

tangyuxin 7 年之前
父节点
当前提交
6f12736c86

+ 51 - 51
components/drivers/wlan/wlan_cmd.c

@@ -2,7 +2,7 @@
  * File      : wlan_cmd.c
  *             Wi-Fi common commands
  * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2016, RT-Thread Development Team
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -40,6 +40,13 @@ static char wifi_ssid[32]    = {0};
 static char wifi_key[32]     = {0};
 static int network_mode      = WIFI_STATION;
 
+#define WLAN_DEBUG   1
+#if WLAN_DEBUG
+#define WLAN_DBG(...)     rt_kprintf("[WLAN]"),rt_kprintf(__VA_ARGS__)
+#else
+#define WLAN_DBG(...)
+#endif
+
 #ifndef WIFI_SETTING_FN
 #define WIFI_SETTING_FN     "/appfs/setting.json"
 #endif
@@ -69,7 +76,7 @@ int wifi_set_mode(int mode)
     return network_mode;
 }
 
-int wifi_set_setting(const char* ssid, const char* pwd)
+int wifi_set_setting(const char *ssid, const char *pwd)
 {
     if (!ssid) return -1;
 
@@ -87,13 +94,13 @@ int wifi_set_setting(const char* ssid, const char* pwd)
 }
 
 #ifdef PKG_USING_CJSON
-int wifi_read_cfg(const char* filename)
+int wifi_read_cfg(const char *filename)
 {
     int fd;
     cJSON *json = RT_NULL;
 
-    fd = open(filename,O_RDONLY, 0);
-    if(fd < 0)
+    fd = open(filename, O_RDONLY, 0);
+    if (fd < 0)
     {
         /* no setting file */
         return -1;
@@ -106,7 +113,7 @@ int wifi_read_cfg(const char* filename)
         length = lseek(fd, 0, SEEK_END);
         if (length)
         {
-            char *json_str = (char *) rt_malloc (length);
+            char *json_str = (char *) rt_malloc(length);
             if (json_str)
             {
                 lseek(fd, 0, SEEK_SET);
@@ -149,7 +156,7 @@ int wifi_read_cfg(const char* filename)
     return 0;
 }
 
-int wifi_save_cfg(const char* filename)
+int wifi_save_cfg(const char *filename)
 {
     int fd;
     cJSON *json = RT_NULL;
@@ -162,7 +169,7 @@ int wifi_save_cfg(const char* filename)
         length = lseek(fd, 0, SEEK_END);
         if (length)
         {
-            char *json_str = (char *) rt_malloc (length);
+            char *json_str = (char *) rt_malloc(length);
             if (json_str)
             {
                 lseek(fd, 0, SEEK_SET);
@@ -244,9 +251,9 @@ int wifi_save_cfg(const char* filename)
 
 int wifi_save_setting(void)
 {
-    #ifdef PKG_USING_CJSON
+#ifdef PKG_USING_CJSON
     wifi_save_cfg(WIFI_SETTING_FN);
-    #endif
+#endif
 
     return 0;
 }
@@ -265,7 +272,7 @@ int wifi_softap_setup_netif(struct netif *netif)
         {
             char name[8];
             memset(name, 0, sizeof(name));
-            strncpy(name, netif->name, sizeof(name)>sizeof(netif->name)? sizeof(netif->name) : sizeof(name));
+            strncpy(name, netif->name, sizeof(name) > sizeof(netif->name) ? sizeof(netif->name) : sizeof(name));
             dhcpd_start(name);
         }
 #endif
@@ -279,15 +286,15 @@ int wifi_default(void)
     int result = 0;
     struct rt_wlan_device *wlan;
 
-    #ifdef PKG_USING_CJSON
+#ifdef PKG_USING_CJSON
     /* read default setting for wifi */
     wifi_read_cfg(WIFI_SETTING_FN);
-    #endif
+#endif
 
     if (network_mode == WIFI_STATION)
     {
         /* get wlan device */
-        wlan = (struct rt_wlan_device*)rt_device_find(WIFI_DEVICE_STA_NAME);
+        wlan = (struct rt_wlan_device *)rt_device_find(WIFI_DEVICE_STA_NAME);
         if (!wlan)
         {
             rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_STA_NAME);
@@ -296,7 +303,7 @@ int wifi_default(void)
 
         /* wifi station */
         rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, wifi_ssid);
-        result =rt_wlan_init(wlan, WIFI_STATION);
+        result = rt_wlan_init(wlan, WIFI_STATION);
         if (result == RT_EOK)
         {
             result = rt_wlan_connect(wlan, &info, wifi_key);
@@ -306,7 +313,7 @@ int wifi_default(void)
     {
         /* wifi AP */
         /* get wlan device */
-        wlan = (struct rt_wlan_device*)rt_device_find(WIFI_DEVICE_AP_NAME);
+        wlan = (struct rt_wlan_device *)rt_device_find(WIFI_DEVICE_AP_NAME);
         if (!wlan)
         {
             rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_AP_NAME);
@@ -317,7 +324,7 @@ int wifi_default(void)
         info.channel = 11;
 
         /* wifi soft-AP */
-        result =rt_wlan_init(wlan, WIFI_AP);
+        result = rt_wlan_init(wlan, WIFI_AP);
         if (result == RT_EOK)
         {
             result = rt_wlan_softap(wlan, &info, wifi_key);
@@ -334,14 +341,14 @@ static void wifi_usage(void)
     rt_kprintf("wifi          - Do the default wifi action\n");
     rt_kprintf("wifi wlan_dev scan\n");
     rt_kprintf("wifi wlan_dev join SSID PASSWORD\n");
-    rt_kprintf("wifi wlan_dev ap SSID [PASSWORD]\n");    
+    rt_kprintf("wifi wlan_dev ap SSID [PASSWORD]\n");
     rt_kprintf("wifi wlan_dev up\n");
     rt_kprintf("wifi wlan_dev down\n");
     rt_kprintf("wifi wlan_dev rssi\n");
     rt_kprintf("wifi wlan_dev status\n");
 }
 
-int wifi(int argc, char** argv)
+int wifi(int argc, char **argv)
 {
     struct rt_wlan_device *wlan;
 
@@ -368,15 +375,15 @@ int wifi(int argc, char** argv)
 
         network_mode = WIFI_STATION;
 
-        #ifdef PKG_USING_CJSON
+#ifdef PKG_USING_CJSON
         wifi_save_cfg(WIFI_SETTING_FN);
-        #endif
+#endif
 
         return 0;
     }
 
     /* get wlan device */
-    wlan = (struct rt_wlan_device*)rt_device_find(argv[1]);
+    wlan = (struct rt_wlan_device *)rt_device_find(argv[1]);
     if (!wlan)
     {
         rt_kprintf("no wlan:%s device\n", argv[1]);
@@ -397,6 +404,7 @@ int wifi(int argc, char** argv)
         /* TODO: use easy-join to replace */
         rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, argv[3]);
         rt_wlan_connect(wlan, &info, argv[4]);
+        rt_wlan_info_deinit(&info);
     }
     else if (strcmp(argv[2], "up") == 0)
     {
@@ -406,36 +414,28 @@ int wifi(int argc, char** argv)
     else if (strcmp(argv[2], "down") == 0)
     {
         rt_wlan_disconnect(wlan);
+        rt_wlan_info_deinit(&info);
     }
     else if (strcmp(argv[2], "scan") == 0)
     {
-        struct rt_wlan_info *infos;
+        struct rt_wlan_scan_result *scan_result = RT_NULL;
 
-        infos = (struct rt_wlan_info*)rt_malloc(sizeof(struct rt_wlan_info) * 12);
-        if (infos)
+        rt_wlan_scan(wlan, &scan_result);
+        if (scan_result)
         {
             int index, num;
 
-            memset(infos, 0x0, sizeof(struct rt_wlan_info) * 12);
-            num = rt_wlan_scan(wlan, infos, 12);
-
-            for (index = 0; index < num; index ++)
-            {
-                rt_kprintf("----Wi-Fi AP[%d] Information----\n", index);
-                rt_kprintf("SSID: %-.32s\n", infos[index].ssid);
-                rt_kprintf("rssi: %d\n", infos[index].rssi);
-                rt_kprintf(" chn: %d\n", infos[index].channel);
-                rt_kprintf("rate: %d\n", infos[index].datarate);
-                rt_kprintf("\n");
-            }
-
-            /* de-initialize info */
+            num = scan_result->ap_num;
+            rt_kprintf("----Wi-Fi APInformation----\n");
             for (index = 0; index < num; index ++)
             {
-                rt_wlan_info_deinit(&infos[index]);
+                rt_kprintf("SSID:%-.32s, ", scan_result->ap_table[index].ssid);
+                rt_kprintf("rssi:%d, ", scan_result->ap_table[index].rssi);
+                rt_kprintf("chn:%d, ", scan_result->ap_table[index].channel);
+                rt_kprintf("rate:%d\n", scan_result->ap_table[index].datarate);
             }
-            rt_free(infos);
         }
+        rt_wlan_release_scan_result(&scan_result);
     }
     else if (strcmp(argv[2], "rssi") == 0)
     {
@@ -454,7 +454,7 @@ int wifi(int argc, char** argv)
             rt_wlan_info_init(&info, WIFI_AP, SECURITY_OPEN, argv[3]);
             info.channel = 11;
 
-            result =rt_wlan_init(wlan, WIFI_AP);
+            result = rt_wlan_init(wlan, WIFI_AP);
             /* start soft ap */
             result = rt_wlan_softap(wlan, &info, NULL);
             if (result == RT_EOK)
@@ -468,19 +468,19 @@ int wifi(int argc, char** argv)
             rt_wlan_info_init(&info, WIFI_AP, SECURITY_WPA2_AES_PSK, argv[3]);
             info.channel = 11;
 
-            result =rt_wlan_init(wlan, WIFI_AP);
+            result = rt_wlan_init(wlan, WIFI_AP);
             /* start soft ap */
             result = rt_wlan_softap(wlan, &info, argv[4]);
             if (result == RT_EOK)
             {
                 network_mode = WIFI_AP;
-            }            
+            }
         }
         else
         {
             wifi_usage();
         }
-        
+
         if (result != RT_EOK)
         {
             rt_kprintf("wifi start failed! result=%d\n", result);
@@ -496,13 +496,13 @@ int wifi(int argc, char** argv)
 
             rt_kprintf("Wi-Fi AP: %-.32s\n", wlan->info->ssid);
             rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", wlan->info->bssid[0],
-                    wlan->info->bssid[1],
-                    wlan->info->bssid[2],
-                    wlan->info->bssid[3],
-                    wlan->info->bssid[4],
-                    wlan->info->bssid[5]);
+                       wlan->info->bssid[1],
+                       wlan->info->bssid[2],
+                       wlan->info->bssid[3],
+                       wlan->info->bssid[4],
+                       wlan->info->bssid[5]);
             rt_kprintf(" Channel: %d\n", wlan->info->channel);
-            rt_kprintf("DataRate: %dMbps\n", wlan->info->datarate/1000);
+            rt_kprintf("DataRate: %dMbps\n", wlan->info->datarate / 1000);
             rt_kprintf("    RSSI: %d\n", rssi);
         }
         else

+ 28 - 3
components/drivers/wlan/wlan_cmd.h

@@ -1,3 +1,28 @@
+/*
+ * File      : wlan_cmd.h
+ *             Wi-Fi common commands
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-06-05     RT-Thread    first version
+ */
+
 #ifndef WLAN_CMD_H__
 #define WLAN_CMD_H__
 
@@ -11,11 +36,11 @@ int wifi_default(void);
 /* setup netif for soft-ap */
 int wifi_softap_setup_netif(struct netif *netif);
 
-int wifi_set_setting(const char* ssid, const char* pwd);
+int wifi_set_setting(const char *ssid, const char *pwd);
 
 #ifdef PKG_USING_CJSON
-int wifi_read_cfg(const char* filename);
-int wifi_save_cfg(const char* filename);
+int wifi_read_cfg(const char *filename);
+int wifi_save_cfg(const char *filename);
 #endif
 /* save wifi setting with default storage file */
 int wifi_save_setting(void);

+ 150 - 79
components/drivers/wlan/wlan_dev.c

@@ -1,7 +1,7 @@
 /*
  *  RT-Thread Wi-Fi Device
  *
- * COPYRIGHT (C) 2014 - 2015, Shanghai Real-Thread Technology Co., Ltd
+ * COPYRIGHT (C) 2014 - 2018, Shanghai Real-Thread Technology Co., Ltd
  *
  *  This file is part of RT-Thread (http://www.rt-thread.org)
  *
@@ -29,15 +29,13 @@
 #include <rtthread.h>
 #include <rtdevice.h>
 
-#include <lwip/netifapi.h>
-
 #include "wlan_dev.h"
 #include "wlan_cmd.h"
 
 #define NIOCTL_SADDR    0x02
 
-void rt_wlan_info_init(struct rt_wlan_info* info, rt_wlan_mode_t mode, rt_wlan_security_t security, 
-    char *ssid)
+void rt_wlan_info_init(struct rt_wlan_info *info, rt_wlan_mode_t mode, rt_wlan_security_t security,
+                       char *ssid)
 {
     if (info == RT_NULL) return ;
 
@@ -46,15 +44,15 @@ void rt_wlan_info_init(struct rt_wlan_info* info, rt_wlan_mode_t mode, rt_wlan_s
     info->security = security;
     if (ssid)
     {
-        info->ssid = rt_malloc(strlen((char*)ssid) + 1);
+        info->ssid = rt_malloc(strlen((char *)ssid) + 1);
         if (info->ssid)
         {
-            strncpy((char*)info->ssid, (char*)ssid, strlen((char*)ssid) + 1);
+            strncpy((char *)info->ssid, (char *)ssid, strlen((char *)ssid) + 1);
         }
     }
 }
 
-void rt_wlan_info_deinit(struct rt_wlan_info* info)
+void rt_wlan_info_deinit(struct rt_wlan_info *info)
 {
     if (info->ssid)
     {
@@ -65,18 +63,32 @@ void rt_wlan_info_deinit(struct rt_wlan_info* info)
     memset(info, 0x0, sizeof(struct rt_wlan_info));
 }
 
-int rt_wlan_init(struct rt_wlan_device* device, rt_wlan_mode_t mode)
+int rt_wlan_init(struct rt_wlan_device *device, rt_wlan_mode_t mode)
 {
     int result;
 
     if (device == RT_NULL) return 0;
 
-    result = rt_device_control(RT_DEVICE(device), WIFI_INIT, (void*)&mode);
+    if (device->info == RT_NULL)
+    {
+        struct rt_wlan_info *info;
+        char *ssid;
+
+        info = rt_malloc(sizeof(struct rt_wlan_info));
+        if (info)
+        {
+            ssid = rt_malloc(SSID_LENGTH_MAX_SIZE);
+            info->ssid = ssid;
+        }
+        device->info = info;
+    }
+
+    result = rt_device_control(RT_DEVICE(device), WIFI_INIT, (void *)&mode);
 
     return result;
 }
 
-int rt_wlan_connect(struct rt_wlan_device* device, struct rt_wlan_info* info, char *password)
+int rt_wlan_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, char *password)
 {
     int result = 0;
 
@@ -87,28 +99,14 @@ int rt_wlan_connect(struct rt_wlan_device* device, struct rt_wlan_info* info, ch
         rt_wlan_set_info(device, info);
     }
 
-    result = rt_device_control(RT_DEVICE(device), WIFI_EASYJOIN, (void*)password);
-    if (result == RT_EOK)
-    {
-        struct netif *netif = device->parent.netif;
-
-        netifapi_netif_set_up(netif);
-        eth_device_linkchange(&(device->parent), RT_TRUE);
+    rt_strncpy((char *)device->key, (char *)password, sizeof(device->key) - 1);
 
-#ifdef RT_LWIP_DHCP
-        /* set DHCP flags */
-        // netif->flags |= NETIF_FLAG_DHCP;
-        /* start DHCP */
-        dhcp_start(netif);
-#endif
-
-        rt_strncpy((char*)device->key, (char*)password, sizeof(device->key) - 1);
-    }
+    result = rt_device_control(RT_DEVICE(device), WIFI_EASYJOIN, (void *)password);
 
     return result;
 }
 
-int rt_wlan_softap(struct rt_wlan_device* device, struct rt_wlan_info* info, char *password)
+int rt_wlan_softap(struct rt_wlan_device *device, struct rt_wlan_info *info, char *password)
 {
     int result = RT_EOK;
 
@@ -119,21 +117,14 @@ int rt_wlan_softap(struct rt_wlan_device* device, struct rt_wlan_info* info, cha
         rt_wlan_set_info(device, info);
     }
 
-    result = rt_device_control(RT_DEVICE(device), WIFI_SOFTAP, (void*)password);
-    if (result == RT_EOK)
-    {
-        rt_strncpy((char*)device->key, (char*)password, sizeof(device->key) - 1);
-
-        netifapi_netif_set_up(device->parent.netif);
-        eth_device_linkchange(&(device->parent), RT_TRUE);
+    rt_strncpy((char *)device->key, (char *)password, sizeof(device->key) - 1);
 
-        wifi_softap_setup_netif(device->parent.netif);
-    }
+    result = rt_device_control(RT_DEVICE(device), WIFI_SOFTAP, (void *)password);
 
     return result;
 }
 
-int rt_wlan_disconnect(struct rt_wlan_device* device)
+int rt_wlan_disconnect(struct rt_wlan_device *device)
 {
     int result = 0;
 
@@ -141,33 +132,30 @@ int rt_wlan_disconnect(struct rt_wlan_device* device)
 
     /* save event handler */
     result = rt_device_control(RT_DEVICE(device), WIFI_DISCONNECT, RT_NULL);
-    if (result == RT_EOK)
-    {
-        netifapi_netif_set_down(device->parent.netif);
-        eth_device_linkchange(&(device->parent), RT_FALSE);
-    }
 
     return result;
 }
 
-int rt_wlan_set_info(struct rt_wlan_device* device, struct rt_wlan_info* info)
+int rt_wlan_set_info(struct rt_wlan_device *device, struct rt_wlan_info *info)
 {
-    if (device->info == info) return RT_EOK; /* same info */
-
-    if (device->info != RT_NULL)
-    {
-        rt_wlan_info_deinit(device->info);
-        rt_free(device->info);
-    }
+    if (device == RT_NULL) return -RT_EIO;
+    if (device->info == RT_NULL) return -RT_EIO;
 
-    device->info = info;
+    device->info->mode = info->mode;
+    device->info->security = info->security;
+    memset(device->info->ssid, 0, SSID_LENGTH_MAX_SIZE);
+    memcpy(device->info->ssid, info->ssid, strlen(info->ssid));
+    memcpy(device->info->bssid, info->bssid, 6);
+    device->info->datarate = info->datarate;
+    device->info->channel = info->channel;
+    device->info->rssi = info->rssi;
 
     return RT_EOK;
 }
 
-struct rt_wlan_info *rt_wlan_get_info(struct rt_wlan_device* device)
+struct rt_wlan_info *rt_wlan_get_info(struct rt_wlan_device *device)
 {
-    struct rt_wlan_info* info = RT_NULL;
+    struct rt_wlan_info *info = RT_NULL;
 
     if (device != RT_NULL)
     {
@@ -177,70 +165,153 @@ struct rt_wlan_info *rt_wlan_get_info(struct rt_wlan_device* device)
     return info;
 }
 
-int rt_wlan_scan(struct rt_wlan_device* device, struct rt_wlan_info *infos, int item_sz)
+int rt_wlan_scan(struct rt_wlan_device *device, struct rt_wlan_scan_result **scan_result)
 {
     int result;
-    struct rt_wlan_info_request request;
 
-    if (device == RT_NULL) return 0;
+    result = rt_device_control(RT_DEVICE(device), WIFI_SCAN, scan_result);
 
-    request.req_number = item_sz;
-    request.rsp_number = 0;
-    request.infos = infos;
-
-    result = rt_device_control(RT_DEVICE(device), WIFI_SCAN, (void*)&request);
-    result = result; /* skip warning */
-
-    return request.rsp_number;
+    return result;
 }
 
-int rt_wlan_get_rssi(struct rt_wlan_device* device)
+int rt_wlan_get_rssi(struct rt_wlan_device *device)
 {
     int rssi;
     int result;
 
     if (device == RT_NULL) return 0;
-    result = rt_device_control(RT_DEVICE(device), WIFI_GET_RSSI, (void*)&rssi);
+    result = rt_device_control(RT_DEVICE(device), WIFI_GET_RSSI, (void *)&rssi);
 
     if (result == RT_EOK) return rssi;
 
     return result;
 }
 
-int rt_wlan_get_mac(struct rt_wlan_device* device, rt_uint8_t hwaddr[6])
+int rt_wlan_get_mac(struct rt_wlan_device *device, rt_uint8_t hwaddr[6])
 {
     int result;
     if (device == RT_NULL) return 0;
-    result = rt_device_control(RT_DEVICE(device), NIOCTL_GADDR, (void*)hwaddr);
+    result = rt_device_control(RT_DEVICE(device), NIOCTL_GADDR, (void *)hwaddr);
     return result;
 }
 
-int rt_wlan_set_mac(struct rt_wlan_device* device, rt_uint8_t hwaddr[6])
+int rt_wlan_set_mac(struct rt_wlan_device *device, rt_uint8_t hwaddr[6])
 {
     int result;
     if (device == RT_NULL) return 0;
-    result = rt_device_control(RT_DEVICE(device), NIOCTL_SADDR, (void*)hwaddr);
+    result = rt_device_control(RT_DEVICE(device), NIOCTL_SADDR, (void *)hwaddr);
+    return result;
+}
+
+int rt_wlan_enter_powersave(struct rt_wlan_device *device, int level)
+{
+    int result = 0;
+
+    if (device == RT_NULL) return -RT_EIO;
+
+    result = rt_device_control(RT_DEVICE(device), WIFI_ENTER_POWERSAVE, (void *)&level);
+
+    return result;
+}
+
+int rt_wlan_register_event_handler(struct rt_wlan_device *device, rt_wlan_event_t event,
+                                   rt_wlan_event_handler handler)
+{
+    if (device == RT_NULL) return -RT_EIO;
+    if (event >= WIFI_EVT_MAX) return -RT_EINVAL;
+
+    device->handler[event] = handler;
+
+    return RT_EOK;
+}
+
+int rt_wlan_unregister_event_handler(struct rt_wlan_device *device, rt_wlan_event_t event)
+{
+    if (device == RT_NULL) return -RT_EIO;
+    if (event >= WIFI_EVT_MAX) return -RT_EINVAL;
+
+    device->handler[event] = RT_NULL;
+
+    return RT_EOK;
+}
+
+int rt_wlan_indicate_event_handle(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    if (device == RT_NULL) return -RT_EIO;
+    if (event >= WIFI_EVT_MAX) return -RT_EINVAL;
+
+    if (device->handler[event] != RT_NULL)
+        device->handler[event](device, event, user_data);
+
+    return RT_EOK;
+}
+
+int rt_wlan_cfg_monitor(struct rt_wlan_device *device, rt_wlan_monitor_opition_t opition)
+{
+    int result = 0;
+
+    if (device == RT_NULL) return -RT_EIO;
+
+    result = rt_device_control(RT_DEVICE(device), WIFI_CFG_MONITOR, (void *)&opition);
+
+    return result;
+}
+
+int rt_wlan_set_monitor_callback(struct rt_wlan_device *device, rt_wlan_monitor_callback_t callback)
+{
+    int result = 0;
+
+    if (device == RT_NULL) return -RT_EIO;
+
+    result = rt_device_control(RT_DEVICE(device), WIFI_SET_MONITOR_CALLBACK, (void *)callback);
+
     return result;
 }
 
-int rt_wlan_enter_powersave(struct rt_wlan_device* device, int level)
+int rt_wlan_set_channel(struct rt_wlan_device *device, int channel)
 {
     int result = 0;
 
     if (device == RT_NULL) return -RT_EIO;
 
-    result = rt_device_control(RT_DEVICE(device), WIFI_ENTER_POWERSAVE, (void*)&level);
+    result = rt_device_control(RT_DEVICE(device), WIFI_SET_CHANNEL, (void *)&channel);
 
     return result;
 }
 
-void rt_wlan_set_event_callback(struct rt_wlan_device* device, rt_wlan_event_handler handler, 
-    void *user_data)
+int rt_wlan_get_channel(struct rt_wlan_device *device)
 {
-    if (device == RT_NULL) return ;
+    int channel = 0;
 
-    device->handler = handler;
-    device->user_data = user_data;
+    if (device == RT_NULL) return -RT_EIO;
+
+    rt_device_control(RT_DEVICE(device), WIFI_GET_CHANNEL, &channel);
+
+    return channel;
+}
+
+void rt_wlan_release_scan_result(struct rt_wlan_scan_result **scan_result)
+{
+    int i, ap_num;
+    struct rt_wlan_scan_result *_scan_result;
 
-    return ;
+    if (*scan_result != RT_NULL)
+    {
+        _scan_result = *scan_result;
+        ap_num = _scan_result->ap_num;
+        for (i = 0; i < ap_num; i++)
+        {
+            if (_scan_result->ap_table[i].ssid != RT_NULL)
+            {
+                rt_free(_scan_result->ap_table[i].ssid);
+                _scan_result->ap_table[i].ssid = RT_NULL;
+            }
+        }
+        _scan_result->ap_num = 0;
+        rt_free(_scan_result->ap_table);
+        _scan_result->ap_table = RT_NULL;
+    }
+    rt_free(*scan_result);
+    *scan_result = RT_NULL;
+    scan_result = RT_NULL;
 }

+ 79 - 34
components/drivers/wlan/wlan_dev.h

@@ -1,7 +1,7 @@
 /*
  *  RT-Thread Wi-Fi Device
  *
- * COPYRIGHT (C) 2014 - 2015, Shanghai Real-Thread Technology Co., Ltd
+ * COPYRIGHT (C) 2014 - 2018, Shanghai Real-Thread Technology Co., Ltd
  *
  *  This file is part of RT-Thread (http://www.rt-thread.org)
  *
@@ -25,6 +25,7 @@
  * Date           Author       Notes
  * 2014-09-11     Bernard      the first verion
  */
+
 #ifndef WIFI_DEVICE_H__
 #define WIFI_DEVICE_H__
 
@@ -33,6 +34,7 @@
 
 typedef enum
 {
+    WIFI_NONE,
     WIFI_STATION,
     WIFI_AP,
 } rt_wlan_mode_t;
@@ -47,6 +49,10 @@ typedef enum
     WIFI_DISCONNECT,
     WIFI_GET_RSSI,          /* get sensitivity (dBm) */
     WIFI_ENTER_POWERSAVE,
+    WIFI_CFG_MONITOR,       /* start/stop minitor */
+    WIFI_SET_CHANNEL,
+    WIFI_GET_CHANNEL,
+    WIFI_SET_MONITOR_CALLBACK,
 } rt_wlan_cmd_t;
 
 typedef enum
@@ -56,6 +62,12 @@ typedef enum
     WIFI_PWR_NORMAL
 } rt_wlan_powersave_t;
 
+typedef enum
+{
+    WIFI_MONITOR_START,
+    WIFI_MONITOR_STOP
+} rt_wlan_monitor_opition_t;
+
 #define SHARED_ENABLED  0x00008000
 #define WPA_SECURITY    0x00200000
 #define WPA2_SECURITY   0x00400000
@@ -66,7 +78,7 @@ typedef enum
 #define WSEC_SWFLAG     0x0008
 
 #define KEY_ARRAY_SIZE  32
-
+#define SSID_LENGTH_MAX_SIZE  32 + 1
 /**
  * Enumeration of Wi-Fi security modes
  */
@@ -74,23 +86,32 @@ typedef enum
 {
     SECURITY_OPEN           = 0,                                                /**< Open security                           */
     SECURITY_WEP_PSK        = WEP_ENABLED,                                      /**< WEP Security with open authentication   */
-    SECURITY_WEP_SHARED     = ( WEP_ENABLED | SHARED_ENABLED ),                 /**< WEP Security with shared authentication */
-    SECURITY_WPA_TKIP_PSK   = ( WPA_SECURITY  | TKIP_ENABLED ),                 /**< WPA Security with TKIP                  */
-    SECURITY_WPA_AES_PSK    = ( WPA_SECURITY  | AES_ENABLED ),                  /**< WPA Security with AES                   */
-    SECURITY_WPA2_AES_PSK   = ( WPA2_SECURITY | AES_ENABLED ),                  /**< WPA2 Security with AES                  */
-    SECURITY_WPA2_TKIP_PSK  = ( WPA2_SECURITY | TKIP_ENABLED ),                 /**< WPA2 Security with TKIP                 */
-    SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ),   /**< WPA2 Security with AES & TKIP           */
+    SECURITY_WEP_SHARED     = (WEP_ENABLED | SHARED_ENABLED),                   /**< WEP Security with shared authentication */
+    SECURITY_WPA_TKIP_PSK   = (WPA_SECURITY  | TKIP_ENABLED),                   /**< WPA Security with TKIP                  */
+    SECURITY_WPA_AES_PSK    = (WPA_SECURITY  | AES_ENABLED),                    /**< WPA Security with AES                   */
+    SECURITY_WPA2_AES_PSK   = (WPA2_SECURITY | AES_ENABLED),                    /**< WPA2 Security with AES                  */
+    SECURITY_WPA2_TKIP_PSK  = (WPA2_SECURITY | TKIP_ENABLED),                   /**< WPA2 Security with TKIP                 */
+    SECURITY_WPA2_MIXED_PSK = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED),     /**< WPA2 Security with AES & TKIP           */
     SECURITY_WPS_OPEN       = WPS_ENABLED,                                      /**< WPS with open security                  */
     SECURITY_WPS_SECURE     = (WPS_ENABLED | AES_ENABLED),                      /**< WPS with AES security                   */
-    SECURITY_UNKNOWN        = -1,                                               /**< May be returned by scan function if security is unknown. 
+    SECURITY_UNKNOWN        = -1,                                               /**< May be returned by scan function if security is unknown.
                                                                                      Do not pass this to the join function! */
 } rt_wlan_security_t;
 
 typedef enum
 {
+    WIFI_EVT_INIT_DONE = 0,
     WIFI_EVT_LINK_DOWN,
     WIFI_EVT_LINK_UP,
-}rt_wlan_event_t;
+    WIFI_EVT_CONNECT,
+    WIFI_EVT_DISCONNECT,
+    WIFI_EVT_AP_START,
+    WIFI_EVT_AP_STOP,
+    WIFI_EVENT_STA_ASSOC,
+    WIFI_EVENT_STA_DISASSOC,
+    WIFI_EVT_SCAN_DONE,
+    WIFI_EVT_MAX,
+} rt_wlan_event_t;
 
 /* wifi network information */
 struct rt_wlan_info
@@ -117,59 +138,83 @@ struct rt_wlan_info_request
     struct rt_wlan_info *infos;/* the array of information to save response */
 };
 
-struct rt_wlan_device;
-typedef void (*rt_wlan_event_handler)(struct rt_wlan_device* device, rt_wlan_event_t event, void* user_data);
+typedef struct rt_wlan_scan_result
+{
+    char ap_num;
+    struct rt_wlan_info *ap_table;
+} rt_wlan_scan_result_t;
 
+struct rt_wlan_device;
+typedef void (*rt_wlan_event_handler)(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data);
+typedef void (*rt_wlan_monitor_callback_t)(uint8_t *data, int len, void *user_data);
 struct rt_wlan_device
 {
     struct eth_device parent;
 
-    struct rt_wlan_info* info;
+    struct rt_wlan_info *info;
     char key[KEY_ARRAY_SIZE + 1];
 
-    rt_wlan_event_handler handler;
-    void* user_data;
+    rt_wlan_event_handler handler[WIFI_EVT_MAX];
+    void *user_data;
     int interface;
 };
 
 /*
  * Wi-Fi Information APIs
  */
-void rt_wlan_info_init(struct rt_wlan_info* info, rt_wlan_mode_t mode, rt_wlan_security_t security, 
-    char *ssid);
-void rt_wlan_info_deinit(struct rt_wlan_info* info);
+void rt_wlan_info_init(struct rt_wlan_info *info, rt_wlan_mode_t mode, rt_wlan_security_t security,
+                       char *ssid);
+void rt_wlan_info_deinit(struct rt_wlan_info *info);
 
 /*
  * Wi-Fi Manager APIs
  */
-int rt_wlan_init(struct rt_wlan_device* device, rt_wlan_mode_t mode);
+int rt_wlan_init(struct rt_wlan_device *device, rt_wlan_mode_t mode);
 
-int rt_wlan_connect(struct rt_wlan_device* device, struct rt_wlan_info* info, 
-    char *password);
-int rt_wlan_disconnect(struct rt_wlan_device* device);
+int rt_wlan_connect(struct rt_wlan_device *device, struct rt_wlan_info *info,
+                    char *password);
+int rt_wlan_disconnect(struct rt_wlan_device *device);
 
-int rt_wlan_softap(struct rt_wlan_device* device, struct rt_wlan_info* info, 
-    char *password);
+int rt_wlan_softap(struct rt_wlan_device *device, struct rt_wlan_info *info,
+                   char *password);
 
 /* set wifi information for AP */
-int rt_wlan_set_info(struct rt_wlan_device* device, struct rt_wlan_info* info);
+int rt_wlan_set_info(struct rt_wlan_device *device, struct rt_wlan_info *info);
 /* get wifi information for AP */
-struct rt_wlan_info *rt_wlan_get_info(struct rt_wlan_device* device);
+struct rt_wlan_info *rt_wlan_get_info(struct rt_wlan_device *device);
 
 /* get the AP result which were scaned in station */
-int rt_wlan_scan(struct rt_wlan_device* device, struct rt_wlan_info *infos, int item_sz);
+int rt_wlan_scan(struct rt_wlan_device *device, struct rt_wlan_scan_result **scan_result);
 
 /* get rssi */
-int rt_wlan_get_rssi(struct rt_wlan_device* device);
+int rt_wlan_get_rssi(struct rt_wlan_device *device);
 /* Get/Set MAC */
-int rt_wlan_get_mac(struct rt_wlan_device* device,rt_uint8_t hwaddr[6]);
-int rt_wlan_set_mac(struct rt_wlan_device* device,rt_uint8_t hwaddr[6]);
+int rt_wlan_get_mac(struct rt_wlan_device *device, rt_uint8_t hwaddr[6]);
+int rt_wlan_set_mac(struct rt_wlan_device *device, rt_uint8_t hwaddr[6]);
 
 /* enter power save level */
-int rt_wlan_enter_powersave(struct rt_wlan_device* device, int level);
+int rt_wlan_enter_powersave(struct rt_wlan_device *device, int level);
 
-void rt_wlan_set_event_callback(struct rt_wlan_device* device, rt_wlan_event_handler handler, 
-    void *user_data);
+/* register the event handler */
+int rt_wlan_register_event_handler(struct rt_wlan_device *device, rt_wlan_event_t event,
+                                   rt_wlan_event_handler handler);
 
-#endif
+/* un-register the event handler */
+int rt_wlan_unregister_event_handler(struct rt_wlan_device *device, rt_wlan_event_t event);
+
+/* wlan driver indicate event to upper layer through wifi_indication. */
+int rt_wlan_indicate_event_handle(struct rt_wlan_device *device, rt_wlan_event_t event,
+                                  void *user_data);
+
+/* start or stop monitor */
+int rt_wlan_cfg_monitor(struct rt_wlan_device *device, rt_wlan_monitor_opition_t opition);
+
+/* set callback function for monitor mode*/
+int rt_wlan_set_monitor_callback(struct rt_wlan_device *device, rt_wlan_monitor_callback_t callback);
 
+/* Set the monitor channel */
+int rt_wlan_set_channel(struct rt_wlan_device *device, int channel);
+
+void rt_wlan_release_scan_result(struct rt_wlan_scan_result **scan_result);
+
+#endif

+ 142 - 0
components/drivers/wlan/wlan_mgnt.c

@@ -0,0 +1,142 @@
+/*
+ *  RT-Thread Wi-Fi Device
+ *
+ * COPYRIGHT (C) 2014 - 2018, Shanghai Real-Thread Technology Co., Ltd
+ *
+ *  This file is part of RT-Thread (http://www.rt-thread.org)
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-27     EvalZero     the first verion
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <lwip/netifapi.h>
+
+#include "wlan_dev.h"
+#include "wlan_cmd.h"
+
+#define WLAN_MGNT_DEBUG   1
+
+#if WLAN_MGNT_DEBUG
+#define WLAN_MGNT_DBG(...)     rt_kprintf("[WLAN_MGNT]"),rt_kprintf(__VA_ARGS__)
+#else
+#define WLAN_MGNT_DBG(...)
+#endif
+
+#ifndef WIFI_DEVICE_STA_NAME
+#define WIFI_DEVICE_STA_NAME    "w0"
+#endif
+#ifndef WIFI_DEVICE_AP_NAME
+#define WIFI_DEVICE_AP_NAME    "ap"
+#endif
+
+static void wlan_mgnt_init_done_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan init done  event callback \n");
+}
+
+static void wlan_mgnt_link_up_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan link up event callback \n");
+}
+
+static void wlan_mgnt_link_down_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan link down event callback \n");
+}
+
+static void wlan_mgnt_sta_connect_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan sta connect event callback \n");
+    struct netif *netif = device->parent.netif;
+
+    netifapi_netif_set_up(netif);
+    netifapi_netif_set_link_up(netif);
+#ifdef RT_LWIP_DHCP
+    /* start DHCP */
+    dhcp_start(netif);
+#endif
+}
+
+static void wlan_mgnt_sta_disconnect_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan sta disconnect event callback \n");
+    netifapi_netif_set_down(device->parent.netif);
+    netifapi_netif_set_link_down(device->parent.netif);
+    rt_memset(&device->parent.netif->ip_addr, 0, sizeof(ip_addr_t));
+    rt_memset(&device->parent.netif->netmask, 0, sizeof(ip_addr_t));
+    rt_memset(&device->parent.netif->gw, 0, sizeof(ip_addr_t));
+#ifdef RT_LWIP_DHCP
+    dhcp_stop(device->parent.netif);
+#endif
+}
+
+static void wlan_mgnt_ap_start_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan ap start event callback \n");
+    netifapi_netif_set_up(device->parent.netif);
+    netifapi_netif_set_link_up(device->parent.netif);
+
+    wifi_softap_setup_netif(device->parent.netif);
+}
+
+
+static void wlan_mgnt_ap_stop_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan ap stop event callback \n");
+
+    netifapi_netif_set_down(device->parent.netif);
+    netifapi_netif_set_link_down(device->parent.netif);
+}
+
+static void wlan_mgnt_ap_associate_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan ap associate event callback \n");
+}
+
+static void wlan_mgnt_ap_disassociate_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan ap disassociate event callback \n");
+}
+
+static void wlan_mgnt_scan_done_event(struct rt_wlan_device *device, rt_wlan_event_t event, void *user_data)
+{
+    WLAN_MGNT_DBG("wlan scan done event callback \n");
+}
+
+int rt_wlan_mgnt_attach(struct rt_wlan_device *device, void *user_data)
+{
+    RT_ASSERT(device != RT_NULL);
+
+    rt_wlan_register_event_handler(device, WIFI_EVT_INIT_DONE, wlan_mgnt_init_done_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_LINK_DOWN, wlan_mgnt_link_up_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_LINK_UP, wlan_mgnt_link_down_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_CONNECT, wlan_mgnt_sta_connect_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_DISCONNECT, wlan_mgnt_sta_disconnect_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_AP_START, wlan_mgnt_ap_start_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_AP_STOP, wlan_mgnt_ap_stop_event);
+    rt_wlan_register_event_handler(device, WIFI_EVENT_STA_ASSOC, wlan_mgnt_ap_associate_event);
+    rt_wlan_register_event_handler(device, WIFI_EVENT_STA_DISASSOC, wlan_mgnt_ap_disassociate_event);
+    rt_wlan_register_event_handler(device, WIFI_EVT_SCAN_DONE, wlan_mgnt_scan_done_event);
+
+    return RT_EOK;
+}

+ 34 - 0
components/drivers/wlan/wlan_mgnt.h

@@ -0,0 +1,34 @@
+/*
+ *  RT-Thread Wi-Fi Device
+ *
+ * COPYRIGHT (C) 2014 - 2018, Shanghai Real-Thread Technology Co., Ltd
+ *
+ *  This file is part of RT-Thread (http://www.rt-thread.org)
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-27     EvalZero     the first verion
+ */
+
+#ifndef __WLAN_MGNT_H__
+#define __WLAN_MGNT_H__
+
+int rt_wlan_mgnt_attach(struct rt_wlan_device *device, void *user_data);
+
+#endif