未验证 提交 1e27372e 编写于 作者: C Chester guo 提交者: GitHub

Modify wlan framework (#5076)

* update auto connect use sys work.
* add fast connect.
* update wlan cmd, support scan result report user-level callback.
Co-authored-by: Nzetingxu <zetingxu@bestechnic.com>
Co-authored-by: Nliu2guang <liuguang@rt-thread.com>
Co-authored-by: Nguodi <guodi@rt-thread.com>
Co-authored-by: xpxyr's avatargeniusgogo <xpxyr@sina.com>
上级 c8c24ae7
......@@ -9,10 +9,22 @@
*/
#include <rtthread.h>
#include <rthw.h>
#include <wlan_mgnt.h>
#include <wlan_cfg.h>
#include <wlan_prot.h>
#define DBG_TAG "WLAN.cmd"
#ifdef RT_WLAN_MGNT_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* RT_WLAN_MGNT_DEBUG */
#include <rtdbg.h>
static struct rt_wlan_scan_result scan_result;
static struct rt_wlan_info *scan_filter = RT_NULL;
#if defined(RT_WLAN_MANAGE_ENABLE) && defined(RT_WLAN_MSH_CMD_ENABLE)
struct wifi_cmd_des
......@@ -142,46 +154,192 @@ static int wifi_status(int argc, char *argv[])
return 0;
}
static int wifi_scan(int argc, char *argv[])
static rt_bool_t wifi_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
{
struct rt_wlan_scan_result *scan_result = RT_NULL;
struct rt_wlan_info *info = RT_NULL;
struct rt_wlan_info filter;
rt_bool_t is_equ = 1;
rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
if (argc > 3)
return -1;
if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
{
is_equ &= info2->security == info1->security;
}
if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
{
is_equ &= info1->ssid.len == info2->ssid.len;
is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
}
if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
(rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
{
is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
}
if (is_equ && info1->datarate && info2->datarate)
{
is_equ &= info1->datarate == info2->datarate;
}
if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
{
is_equ &= info1->channel == info2->channel;
}
if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
{
is_equ &= info1->rssi == info2->rssi;
}
return is_equ;
}
if (argc == 3)
static rt_err_t wifi_scan_result_cache(struct rt_wlan_info *info)
{
struct rt_wlan_info *ptable;
rt_err_t err = RT_EOK;
int i, insert = -1;
rt_base_t level;
if ((info == RT_NULL) || (info->ssid.len == 0)) return -RT_EINVAL;
LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
/* scanning result filtering */
level = rt_hw_interrupt_disable();
if (scan_filter)
{
INVALID_INFO(&filter);
SSID_SET(&filter, argv[2]);
info = &filter;
struct rt_wlan_info _tmp_info = *scan_filter;
rt_hw_interrupt_enable(level);
if (wifi_info_isequ(&_tmp_info, info) != RT_TRUE)
{
return RT_EOK;
}
}
else
{
rt_hw_interrupt_enable(level);
}
/* clean scan result */
rt_wlan_scan_result_clean();
/* scan ap info */
scan_result = rt_wlan_scan_with_info(info);
if (scan_result)
/* de-duplicatio */
for (i = 0; i < scan_result.num; i++)
{
if ((info->ssid.len == scan_result.info[i].ssid.len) &&
(rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
{
return RT_EOK;
}
#ifdef RT_WLAN_SCAN_SORT
if (insert >= 0)
{
continue;
}
/* Signal intensity comparison */
if ((info->rssi < 0) && (scan_result.info[i].rssi < 0))
{
if (info->rssi > scan_result.info[i].rssi)
{
insert = i;
continue;
}
else if (info->rssi < scan_result.info[i].rssi)
{
continue;
}
}
/* Channel comparison */
if (info->channel < scan_result.info[i].channel)
{
insert = i;
continue;
}
else if (info->channel > scan_result.info[i].channel)
{
continue;
}
/* data rate comparison */
if ((info->datarate > scan_result.info[i].datarate))
{
insert = i;
continue;
}
else if (info->datarate < scan_result.info[i].datarate)
{
continue;
}
#endif
}
/* Insert the end */
if (insert == -1)
insert = scan_result.num;
if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM)
return RT_EOK;
/* malloc memory */
ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1));
if (ptable == RT_NULL)
{
LOG_E("wlan info malloc failed!");
return -RT_ENOMEM;
}
scan_result.num ++;
/* copy info */
for (i = 0; i < scan_result.num; i++)
{
int index, num;
if (i < insert)
{
ptable[i] = scan_result.info[i];
}
else if (i > insert)
{
ptable[i] = scan_result.info[i - 1];
}
else if (i == insert)
{
ptable[i] = *info;
}
}
rt_free(scan_result.info);
scan_result.info = ptable;
return err;
}
static void wifi_scan_result_clean(void)
{
/* If there is data */
if (scan_result.num)
{
scan_result.num = 0;
rt_free(scan_result.info);
scan_result.info = RT_NULL;
}
}
static void print_ap_info(struct rt_wlan_info *info,int index)
{
char *security;
num = scan_result->num;
if(index == 0)
{
rt_kprintf(" SSID MAC security rssi chn Mbps\n");
rt_kprintf("------------------------------- ----------------- -------------- ---- --- ----\n");
for (index = 0; index < num; index ++)
}
{
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);
}
rt_wlan_scan_result_clean();
}
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;
}
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;
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -16,6 +16,7 @@
#include <wlan_prot.h>
#include <wlan_workqueue.h>
// #define RT_WLAN_MGNT_DEBUG
#define DBG_TAG "WLAN.mgnt"
#ifdef RT_WLAN_MGNT_DEBUG
#define DBG_LVL DBG_LOG
......@@ -38,9 +39,6 @@
#define STA_DEVICE() (_sta_mgnt.device)
#define AP_DEVICE() (_ap_mgnt.device)
#define SRESULT_LOCK() (rt_mutex_take(&scan_result_mutex, RT_WAITING_FOREVER))
#define SRESULT_UNLOCK() (rt_mutex_release(&scan_result_mutex))
#define STAINFO_LOCK() (rt_mutex_take(&sta_info_mutex, RT_WAITING_FOREVER))
#define STAINFO_UNLOCK() (rt_mutex_release(&sta_info_mutex))
......@@ -53,6 +51,7 @@
#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
#define TIME_STOP() (rt_timer_stop(&reconnect_time))
#define TIME_START() (rt_timer_start(&reconnect_time))
static rt_uint32_t id = 0;
#else
#define TIME_STOP()
#define TIME_START()
......@@ -108,8 +107,6 @@ static struct rt_mutex mgnt_mutex;
static struct rt_wlan_mgnt_des _sta_mgnt;
static struct rt_wlan_mgnt_des _ap_mgnt;
static struct rt_wlan_scan_result scan_result;
static struct rt_mutex scan_result_mutex;
static struct rt_wlan_sta_des sta_info;
static struct rt_mutex sta_info_mutex;
......@@ -118,7 +115,6 @@ static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX];
static struct rt_wlan_complete_des *complete_tab[5];
static struct rt_mutex complete_mutex;
static struct rt_wlan_info *scan_filter;
#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static struct rt_timer reconnect_time;
......@@ -155,40 +151,6 @@ rt_inline rt_bool_t _is_do_connect(void)
#ifdef RT_WLAN_WORK_THREAD_ENABLE
static rt_bool_t rt_wlan_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
{
rt_bool_t is_equ = 1;
rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
{
is_equ &= info2->security == info1->security;
}
if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
{
is_equ &= info1->ssid.len == info2->ssid.len;
is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
}
if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
(rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
{
is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
}
if (is_equ && info1->datarate && info2->datarate)
{
is_equ &= info1->datarate == info2->datarate;
}
if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
{
is_equ &= info1->channel == info2->channel;
}
if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
{
is_equ &= info1->rssi == info2->rssi;
}
return is_equ;
}
static void rt_wlan_mgnt_work(void *parameter)
{
struct rt_wlan_msg *msg = parameter;
......@@ -276,130 +238,6 @@ static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int le
}
#endif
static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout)
{
struct rt_wlan_info *ptable;
rt_err_t err = RT_EOK;
int i, insert = -1;
rt_base_t level;
if (_sta_is_null() || (info == RT_NULL) || (info->ssid.len == 0)) return RT_EOK;
RT_WLAN_LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
err = rt_mutex_take(&scan_result_mutex, rt_tick_from_millisecond(timeout));
if (err != RT_EOK)
return err;
/* scanning result filtering */
level = rt_hw_interrupt_disable();
if (scan_filter)
{
struct rt_wlan_info _tmp_info = *scan_filter;
rt_hw_interrupt_enable(level);
if (rt_wlan_info_isequ(&_tmp_info, info) != RT_TRUE)
{
rt_mutex_release(&scan_result_mutex);
return RT_EOK;
}
}
else
{
rt_hw_interrupt_enable(level);
}
/* de-duplicatio */
for (i = 0; i < scan_result.num; i++)
{
if ((info->ssid.len == scan_result.info[i].ssid.len) &&
(rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
{
rt_mutex_release(&scan_result_mutex);
return RT_EOK;
}
#ifdef RT_WLAN_SCAN_SORT
if (insert >= 0)
{
continue;
}
/* Signal intensity comparison */
if ((info->rssi < 0) && (scan_result.info[i].rssi < 0))
{
if (info->rssi > scan_result.info[i].rssi)
{
insert = i;
continue;
}
else if (info->rssi < scan_result.info[i].rssi)
{
continue;
}
}
/* Channel comparison */
if (info->channel < scan_result.info[i].channel)
{
insert = i;
continue;
}
else if (info->channel > scan_result.info[i].channel)
{
continue;
}
/* data rate comparison */
if ((info->datarate > scan_result.info[i].datarate))
{
insert = i;
continue;
}
else if (info->datarate < scan_result.info[i].datarate)
{
continue;
}
#endif
}
/* Insert the end */
if (insert == -1)
insert = scan_result.num;
if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM)
return RT_EOK;
/* malloc memory */
ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1));
if (ptable == RT_NULL)
{
rt_mutex_release(&scan_result_mutex);
RT_WLAN_LOG_E("wlan info malloc failed!");
return -RT_ENOMEM;
}
scan_result.num ++;
/* copy info */
for (i = 0; i < scan_result.num; i++)
{
if (i < insert)
{
ptable[i] = scan_result.info[i];
}
else if (i > insert)
{
ptable[i] = scan_result.info[i - 1];
}
else if (i == insert)
{
ptable[i] = *info;
}
}
rt_free(scan_result.info);
scan_result.info = ptable;
rt_mutex_release(&scan_result_mutex);
return err;
}
static rt_err_t rt_wlan_sta_info_add(struct rt_wlan_info *info, int timeout)
{
struct rt_wlan_sta_list *sta_list;
......@@ -500,7 +338,6 @@ static rt_err_t rt_wlan_sta_info_del_all(int timeout)
#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
{
static rt_uint32_t id = 0;
struct rt_wlan_cfg_info cfg_info;
char *password = RT_NULL;
rt_base_t level;
......@@ -544,26 +381,21 @@ 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_workqueue_dowork(workqueue, &work) != RT_EOK)
if(rt_work_submit(&work,RT_TICK_PER_SECOND) != RT_EOK)
{
level = rt_hw_interrupt_disable();
rt_memset(&work, 0, sizeof(struct rt_work));
rt_hw_interrupt_enable(level);
}
}
}
}
#endif
......@@ -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;
ssid_len = rt_strlen(ssid);
result = &scan_result;
info_best = RT_NULL;
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;
SRESULT_LOCK();
for (i = 0; i < result->num; i++)
{
/* SSID is equal. */
if ((result->info[i].ssid.len == ssid_len) &&
(rt_memcmp((char *)&result->info[i].ssid.val[0], ssid, ssid_len) == 0))
{
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)
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)
{
info_best = &result->info[i];
continue;
}
/*Get the rssi the max ap*/
if(info->rssi > tgt_info->rssi)
{
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)
{
LOG_E("Scan register user callback error:%d!\n",err);
return err;
}
err = rt_wlan_scan_with_info(&info);
if(err != RT_EOK)
{
rt_wlan_scan_sync();
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,6 +1035,10 @@ 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_fast_connect(_sta_mgnt.device, info, password, password_len);
if(err != RT_EOK)
{
err = rt_wlan_dev_connect(_sta_mgnt.device, info, password, password_len);
if (err != RT_EOK)
{
......@@ -1203,6 +1050,7 @@ rt_err_t rt_wlan_connect_adv(struct rt_wlan_info *info, const char *password)
MGNT_UNLOCK();
return err;
}
}
MGNT_UNLOCK();
return err;
......@@ -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))
{
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));
RT_WLAN_LOG_E("scan wait timeout!");
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),
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册