From 6f12736c86b1d14733ed4856d1d7f974e7629fca Mon Sep 17 00:00:00 2001 From: tangyuxin <462747508@qq.com> Date: Tue, 5 Jun 2018 16:44:48 +0800 Subject: [PATCH] =?UTF-8?q?[components][drivers]wlan=E9=A9=B1=E5=8A=A8?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/wlan/wlan_cmd.c | 102 ++++++------- components/drivers/wlan/wlan_cmd.h | 31 +++- components/drivers/wlan/wlan_dev.c | 229 ++++++++++++++++++---------- components/drivers/wlan/wlan_dev.h | 113 +++++++++----- components/drivers/wlan/wlan_mgnt.c | 142 +++++++++++++++++ components/drivers/wlan/wlan_mgnt.h | 34 +++++ 6 files changed, 484 insertions(+), 167 deletions(-) create mode 100644 components/drivers/wlan/wlan_mgnt.c create mode 100644 components/drivers/wlan/wlan_mgnt.h diff --git a/components/drivers/wlan/wlan_cmd.c b/components/drivers/wlan/wlan_cmd.c index 5c01732321..33dfac5b75 100644 --- a/components/drivers/wlan/wlan_cmd.c +++ b/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 diff --git a/components/drivers/wlan/wlan_cmd.h b/components/drivers/wlan/wlan_cmd.h index 5e8b13ce7c..a981601f5e 100644 --- a/components/drivers/wlan/wlan_cmd.h +++ b/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); diff --git a/components/drivers/wlan/wlan_dev.c b/components/drivers/wlan/wlan_dev.c index 7c310791fa..3c26531508 100644 --- a/components/drivers/wlan/wlan_dev.c +++ b/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 #include -#include - #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; } diff --git a/components/drivers/wlan/wlan_dev.h b/components/drivers/wlan/wlan_dev.h index cbd5e2e5b5..df7244fd6f 100644 --- a/components/drivers/wlan/wlan_dev.h +++ b/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 diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c new file mode 100644 index 0000000000..2a728747f2 --- /dev/null +++ b/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 +#include + +#include + +#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; +} diff --git a/components/drivers/wlan/wlan_mgnt.h b/components/drivers/wlan/wlan_mgnt.h new file mode 100644 index 0000000000..b00414c6e2 --- /dev/null +++ b/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 -- GitLab