diff --git a/components/drivers/wlan/wlan_cmd.c b/components/drivers/wlan/wlan_cmd.c index 52c25f6755a3a4d44d3853aca82bb4264a31b1a9..9089b3b124e902a552a8dd0a07a7d265375c13f0 100644 --- a/components/drivers/wlan/wlan_cmd.c +++ b/components/drivers/wlan/wlan_cmd.c @@ -9,10 +9,22 @@ */ #include +#include #include #include #include +#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 + +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; } diff --git a/components/drivers/wlan/wlan_dev.c b/components/drivers/wlan/wlan_dev.c index 49c39f1fd19a98bf1694d7cfa71a872437e16835..8e3af17e574c1926a7b41dfbebcb368a5dd75c0d 100644 --- a/components/drivers/wlan/wlan_dev.c +++ b/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; diff --git a/components/drivers/wlan/wlan_dev.h b/components/drivers/wlan/wlan_dev.h index 9fce22b7c99e1ac98b4f5436ee95e9a57f18ba04..d89dc60ef31489847c776d67948ef71754666cc6 100644 --- a/components/drivers/wlan/wlan_dev.h +++ b/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); diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c index fd164690284c6b93daa2ea840a93c06fe471b47b..768d3420696f5cb96adc415715bad5a058fdf5da 100644 --- a/components/drivers/wlan/wlan_mgnt.c +++ b/components/drivers/wlan/wlan_mgnt.c @@ -16,6 +16,7 @@ #include #include +// #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), diff --git a/components/drivers/wlan/wlan_mgnt.h b/components/drivers/wlan/wlan_mgnt.h index 38d5c31da2d747f4896ad9ad139d6b4b9abf23ca..f3855b0976711afe60e3e8957f6e09557e89a2ec 100644 --- a/components/drivers/wlan/wlan_mgnt.h +++ b/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