Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 262 additions & 34 deletions components/drivers/wlan/wlan_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
Expand Down
Loading