mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 13:52:22 +08:00
esp32&esp32c3/wifi: Support specific channel and bssid scan
This commit is contained in:
committed by
Abdelatif Guettouche
parent
13e4f9b6b2
commit
1d1dd8512f
@@ -2575,7 +2575,7 @@ esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
|
||||
regval[0] = getreg32(MAC_ADDR0_REG);
|
||||
regval[1] = getreg32(MAC_ADDR1_REG);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
for (i = 0; i < MAC_LEN; i++)
|
||||
{
|
||||
mac[i] = data[5 - i];
|
||||
}
|
||||
@@ -5409,7 +5409,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
|
||||
if (set)
|
||||
{
|
||||
wifi_cfg.sta.bssid_set = true;
|
||||
memcpy(wifi_cfg.sta.bssid, pdata, 6);
|
||||
memcpy(wifi_cfg.sta.bssid, pdata, MAC_LEN);
|
||||
|
||||
ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
|
||||
if (ret)
|
||||
@@ -5420,7 +5420,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pdata, wifi_cfg.sta.bssid, 6);
|
||||
memcpy(pdata, wifi_cfg.sta.bssid, MAC_LEN);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -62,6 +62,7 @@ extern "C"
|
||||
|
||||
#define SSID_MAX_LEN (32)
|
||||
#define PWD_MAX_LEN (64)
|
||||
#define MAC_LEN (6)
|
||||
|
||||
/* Wi-Fi event ID */
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* Maximum number of channels for Wi-Fi 2.4Ghz */
|
||||
|
||||
#define CHANNEL_MAX_NUM (14)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@@ -79,6 +83,8 @@ struct wifi_scan_result_s
|
||||
****************************************************************************/
|
||||
|
||||
static struct wifi_scan_result_s g_scan_priv;
|
||||
static uint8_t g_channel_num = 0;
|
||||
static uint8_t g_channel_list[CHANNEL_MAX_NUM];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -105,6 +111,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
wifi_scan_config_t *config = NULL;
|
||||
struct iw_scan_req *req;
|
||||
int ret = 0;
|
||||
int i;
|
||||
uint8_t target_mac[MAC_LEN];
|
||||
uint8_t target_ssid[SSID_MAX_LEN + 1] =
|
||||
{
|
||||
0
|
||||
@@ -128,6 +136,9 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
g_channel_num = 0;
|
||||
memset(g_channel_list, 0x0, CHANNEL_MAX_NUM);
|
||||
|
||||
if (iwr->u.data.pointer &&
|
||||
iwr->u.data.length >= sizeof(struct iw_scan_req))
|
||||
{
|
||||
@@ -143,6 +154,35 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
config->ssid = &target_ssid[0];
|
||||
config->ssid[req->essid_len] = '\0';
|
||||
}
|
||||
|
||||
if (iwr->u.data.flags & IW_SCAN_THIS_FREQ &&
|
||||
req->num_channels > 0)
|
||||
{
|
||||
/* Scan specific channels */
|
||||
|
||||
DEBUGASSERT(req->num_channels <= CHANNEL_MAX_NUM);
|
||||
g_channel_num = req->num_channels;
|
||||
if (req->num_channels == 1)
|
||||
{
|
||||
config->channel = req->channel_list[0].m;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < req->num_channels; i++)
|
||||
{
|
||||
g_channel_list[i] = req->channel_list[i].m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(target_mac, 0xff, MAC_LEN);
|
||||
if (memcmp(req->bssid.sa_data, target_mac, MAC_LEN) != 0)
|
||||
{
|
||||
/* Scan specific bssid */
|
||||
|
||||
memcpy(target_mac, req->bssid.sa_data, MAC_LEN);
|
||||
config->bssid = &target_mac[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -319,6 +359,7 @@ void esp_wifi_scan_event_parse(void)
|
||||
esp_wifi_scan_get_ap_num(&bss_total);
|
||||
if (bss_total == 0)
|
||||
{
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
wlinfo("INFO: None AP is scanned\n");
|
||||
return;
|
||||
}
|
||||
@@ -326,6 +367,7 @@ void esp_wifi_scan_event_parse(void)
|
||||
ap_list_buffer = kmm_calloc(bss_total, sizeof(wifi_ap_record_t));
|
||||
if (ap_list_buffer == NULL)
|
||||
{
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
wlerr("ERROR: Failed to calloc buffer to print scan results");
|
||||
return;
|
||||
}
|
||||
@@ -337,127 +379,153 @@ void esp_wifi_scan_event_parse(void)
|
||||
unsigned int result_size;
|
||||
size_t essid_len;
|
||||
size_t essid_len_aligned;
|
||||
bool is_target_channel = true;
|
||||
int i;
|
||||
|
||||
for (bss_count = 0; bss_count < bss_total; bss_count++)
|
||||
{
|
||||
result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
|
||||
|
||||
/* Copy BSSID */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
|
||||
if (g_channel_num > 1)
|
||||
{
|
||||
goto scan_result_full;
|
||||
is_target_channel = false;
|
||||
for (i = 0; i < g_channel_num; i++)
|
||||
{
|
||||
if (g_channel_list[i] == ap_list_buffer[bss_count].primary)
|
||||
{
|
||||
is_target_channel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_target_channel = true;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
|
||||
iwe->cmd = SIOCGIWAP;
|
||||
memcpy(&iwe->u.ap_addr.sa_data, ap_list_buffer[bss_count].bssid,
|
||||
sizeof(ap_list_buffer[bss_count].bssid));
|
||||
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
|
||||
result_size -= ESP_IW_EVENT_SIZE(ap_addr);
|
||||
|
||||
/* Copy ESSID */
|
||||
|
||||
essid_len = MIN(strlen((const char *)
|
||||
ap_list_buffer[bss_count].ssid), SSID_MAX_LEN);
|
||||
essid_len_aligned = (essid_len + 3) & -4;
|
||||
if (result_size < ESP_IW_EVENT_SIZE(essid) + essid_len_aligned)
|
||||
if (is_target_channel == true)
|
||||
{
|
||||
goto scan_result_full;
|
||||
result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
|
||||
|
||||
/* Copy BSSID */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
|
||||
iwe->cmd = SIOCGIWAP;
|
||||
memcpy(&iwe->u.ap_addr.sa_data,
|
||||
ap_list_buffer[bss_count].bssid,
|
||||
sizeof(ap_list_buffer[bss_count].bssid));
|
||||
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
|
||||
result_size -= ESP_IW_EVENT_SIZE(ap_addr);
|
||||
|
||||
/* Copy ESSID */
|
||||
|
||||
essid_len = MIN(strlen((const char *)
|
||||
ap_list_buffer[bss_count].ssid), SSID_MAX_LEN);
|
||||
essid_len_aligned = (essid_len + 3) & -4;
|
||||
if (result_size < ESP_IW_EVENT_SIZE(essid) + essid_len_aligned)
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
iwe->cmd = SIOCGIWESSID;
|
||||
iwe->u.essid.flags = 0;
|
||||
iwe->u.essid.length = essid_len;
|
||||
|
||||
/* Special processing for iw_point, set offset
|
||||
* in pointer field.
|
||||
*/
|
||||
|
||||
iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
|
||||
memcpy(&iwe->u.essid + 1,
|
||||
ap_list_buffer[bss_count].ssid, essid_len);
|
||||
|
||||
wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
|
||||
|
||||
priv->scan_result_size +=
|
||||
ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
result_size -= ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
|
||||
/* Copy link quality info */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(qual))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(qual);
|
||||
iwe->cmd = IWEVQUAL;
|
||||
iwe->u.qual.qual = 0x00;
|
||||
|
||||
wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
|
||||
|
||||
iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
|
||||
iwe->u.qual.noise = 0x00;
|
||||
iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
|
||||
result_size -= ESP_IW_EVENT_SIZE(qual);
|
||||
|
||||
/* Copy AP mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(mode))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(mode);
|
||||
iwe->cmd = SIOCGIWMODE;
|
||||
iwe->u.mode = IW_MODE_MASTER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
|
||||
result_size -= ESP_IW_EVENT_SIZE(mode);
|
||||
|
||||
/* Copy AP encryption mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(data))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(data);
|
||||
iwe->cmd = SIOCGIWENCODE;
|
||||
iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||
iwe->u.data.length = 0;
|
||||
iwe->u.essid.pointer = NULL;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
|
||||
result_size -= ESP_IW_EVENT_SIZE(data);
|
||||
|
||||
/* Copy AP channel */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(freq))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(freq);
|
||||
iwe->cmd = SIOCGIWFREQ;
|
||||
iwe->u.freq.e = 0;
|
||||
iwe->u.freq.m = ap_list_buffer[bss_count].primary;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
|
||||
result_size -= ESP_IW_EVENT_SIZE(freq);
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
iwe->cmd = SIOCGIWESSID;
|
||||
iwe->u.essid.flags = 0;
|
||||
iwe->u.essid.length = essid_len;
|
||||
|
||||
/* Special processing for iw_point, set offset in pointer field */
|
||||
|
||||
iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
|
||||
memcpy(&iwe->u.essid + 1,
|
||||
ap_list_buffer[bss_count].ssid, essid_len);
|
||||
|
||||
wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
|
||||
|
||||
priv->scan_result_size +=
|
||||
ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
result_size -= ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
|
||||
|
||||
/* Copy link quality info */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(qual))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(qual);
|
||||
iwe->cmd = IWEVQUAL;
|
||||
iwe->u.qual.qual = 0x00;
|
||||
|
||||
wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
|
||||
|
||||
iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
|
||||
iwe->u.qual.noise = 0x00;
|
||||
iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
|
||||
result_size -= ESP_IW_EVENT_SIZE(qual);
|
||||
|
||||
/* Copy AP mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(mode))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(mode);
|
||||
iwe->cmd = SIOCGIWMODE;
|
||||
iwe->u.mode = IW_MODE_MASTER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
|
||||
result_size -= ESP_IW_EVENT_SIZE(mode);
|
||||
|
||||
/* Copy AP encryption mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(data))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(data);
|
||||
iwe->cmd = SIOCGIWENCODE;
|
||||
iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||
iwe->u.data.length = 0;
|
||||
iwe->u.essid.pointer = NULL;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
|
||||
result_size -= ESP_IW_EVENT_SIZE(data);
|
||||
|
||||
/* Copy AP channel */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(freq))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(freq);
|
||||
iwe->cmd = SIOCGIWFREQ;
|
||||
iwe->u.freq.e = 0;
|
||||
iwe->u.freq.m = ap_list_buffer[bss_count].primary;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
|
||||
result_size -= ESP_IW_EVENT_SIZE(freq);
|
||||
}
|
||||
|
||||
parse_done = true;
|
||||
@@ -478,7 +546,7 @@ scan_result_full:
|
||||
ap_list_buffer = NULL;
|
||||
}
|
||||
|
||||
g_scan_priv.scan_status = ESP_SCAN_DONE;
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
nxsem_post(&priv->scan_signal);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define MAC_LEN (6)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
@@ -2619,12 +2619,12 @@ int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
|
||||
regval[1] = getreg32(MAC_ADDR1_REG);
|
||||
|
||||
crc = data[6];
|
||||
for (i = 0; i < 6; i++)
|
||||
for (i = 0; i < MAC_LEN; i++)
|
||||
{
|
||||
mac[i] = data[5 - i];
|
||||
}
|
||||
|
||||
if (crc != esp_crc8(mac, 6))
|
||||
if (crc != esp_crc8(mac, MAC_LEN))
|
||||
{
|
||||
wlerr("Failed to check MAC address CRC\n");
|
||||
return -1;
|
||||
@@ -5431,7 +5431,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
|
||||
if (set)
|
||||
{
|
||||
wifi_cfg.sta.bssid_set = true;
|
||||
memcpy(wifi_cfg.sta.bssid, pdata, 6);
|
||||
memcpy(wifi_cfg.sta.bssid, pdata, MAC_LEN);
|
||||
|
||||
ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
|
||||
if (ret)
|
||||
@@ -5442,7 +5442,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pdata, wifi_cfg.sta.bssid, 6);
|
||||
memcpy(pdata, wifi_cfg.sta.bssid, MAC_LEN);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -60,6 +60,8 @@ extern "C"
|
||||
# define ESP32_WLAN_DEVS 2
|
||||
#endif
|
||||
|
||||
#define MAC_LEN (6)
|
||||
|
||||
/* WiFi event ID */
|
||||
|
||||
enum wifi_adpt_evt_e
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* Maximum number of channels for Wi-Fi 2.4Ghz */
|
||||
|
||||
#define CHANNEL_MAX_NUM (14)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@@ -80,6 +84,8 @@ struct wifi_scan_result
|
||||
****************************************************************************/
|
||||
|
||||
static struct wifi_scan_result g_scan_priv;
|
||||
static uint8_t g_channel_num = 0;
|
||||
static uint8_t g_channel_list[CHANNEL_MAX_NUM];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -107,6 +113,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
uint8_t target_ssid[SSID_LEN];
|
||||
struct iw_scan_req *req;
|
||||
int ret = 0;
|
||||
int i;
|
||||
uint8_t target_mac[MAC_LEN];
|
||||
|
||||
memset(target_ssid, 0x0, sizeof(SSID_LEN));
|
||||
if (iwr == NULL)
|
||||
@@ -127,6 +135,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
g_channel_num = 0;
|
||||
memset(g_channel_list, 0x0, CHANNEL_MAX_NUM);
|
||||
memset(config, 0x0, sizeof(wifi_scan_config_t));
|
||||
if (iwr->u.data.pointer &&
|
||||
iwr->u.data.length >= sizeof(struct iw_scan_req))
|
||||
@@ -143,6 +153,35 @@ int esp_wifi_start_scan(struct iwreq *iwr)
|
||||
config->ssid = &target_ssid[0];
|
||||
config->ssid[req->essid_len] = '\0';
|
||||
}
|
||||
|
||||
if (iwr->u.data.flags & IW_SCAN_THIS_FREQ &&
|
||||
req->num_channels > 0)
|
||||
{
|
||||
/* Scan specific channels */
|
||||
|
||||
DEBUGASSERT(req->num_channels <= CHANNEL_MAX_NUM);
|
||||
g_channel_num = req->num_channels;
|
||||
if (req->num_channels == 1)
|
||||
{
|
||||
config->channel = req->channel_list[0].m;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < req->num_channels; i++)
|
||||
{
|
||||
g_channel_list[i] = req->channel_list[i].m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(target_mac, 0xff, MAC_LEN);
|
||||
if (memcmp(req->bssid.sa_data, target_mac, MAC_LEN) != 0)
|
||||
{
|
||||
/* Scan specific bssid */
|
||||
|
||||
memcpy(target_mac, req->bssid.sa_data, MAC_LEN);
|
||||
config->bssid = &target_mac[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,6 +354,7 @@ void esp_wifi_scan_event_parse(void)
|
||||
esp_wifi_scan_get_ap_num(&bss_total);
|
||||
if (bss_total == 0)
|
||||
{
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
wlinfo("INFO: None AP is scanned\n");
|
||||
return;
|
||||
}
|
||||
@@ -322,6 +362,7 @@ void esp_wifi_scan_event_parse(void)
|
||||
ap_list_buffer = kmm_malloc(bss_total * sizeof(wifi_ap_record_t));
|
||||
if (ap_list_buffer == NULL)
|
||||
{
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
wlerr("ERROR: Failed to malloc buffer to print scan results");
|
||||
return;
|
||||
}
|
||||
@@ -334,123 +375,148 @@ void esp_wifi_scan_event_parse(void)
|
||||
unsigned int result_size;
|
||||
size_t essid_len;
|
||||
size_t essid_len_aligned;
|
||||
bool is_target_channel = true;
|
||||
int i;
|
||||
for (bss_count = 0; bss_count < bss_total; bss_count++)
|
||||
{
|
||||
result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
|
||||
|
||||
/* Copy BSSID */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
|
||||
if (g_channel_num > 1)
|
||||
{
|
||||
goto scan_result_full;
|
||||
is_target_channel = false;
|
||||
for (i = 0; i < g_channel_num; i++)
|
||||
{
|
||||
if (g_channel_list[i] == ap_list_buffer[bss_count].primary)
|
||||
{
|
||||
is_target_channel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_target_channel = true;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
|
||||
iwe->cmd = SIOCGIWAP;
|
||||
memcpy(&iwe->u.ap_addr.sa_data, ap_list_buffer[bss_count].bssid,
|
||||
sizeof(ap_list_buffer[bss_count].bssid));
|
||||
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
|
||||
result_size -= ESP_IW_EVENT_SIZE(ap_addr);
|
||||
|
||||
/* Copy ESSID */
|
||||
|
||||
essid_len = MIN(strlen((const char *)
|
||||
ap_list_buffer[bss_count].ssid), 32);
|
||||
essid_len_aligned = (essid_len + 3) & -4;
|
||||
if (result_size < ESP_IW_EVENT_SIZE(essid)+essid_len_aligned)
|
||||
if (is_target_channel == true)
|
||||
{
|
||||
goto scan_result_full;
|
||||
result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
|
||||
|
||||
/* Copy BSSID */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
|
||||
iwe->cmd = SIOCGIWAP;
|
||||
memcpy(&iwe->u.ap_addr.sa_data,
|
||||
ap_list_buffer[bss_count].bssid,
|
||||
sizeof(ap_list_buffer[bss_count].bssid));
|
||||
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
|
||||
result_size -= ESP_IW_EVENT_SIZE(ap_addr);
|
||||
|
||||
/* Copy ESSID */
|
||||
|
||||
essid_len = MIN(strlen((const char *)
|
||||
ap_list_buffer[bss_count].ssid), 32);
|
||||
essid_len_aligned = (essid_len + 3) & -4;
|
||||
if (result_size < ESP_IW_EVENT_SIZE(essid)+essid_len_aligned)
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
iwe->cmd = SIOCGIWESSID;
|
||||
iwe->u.essid.flags = 0;
|
||||
iwe->u.essid.length = essid_len;
|
||||
|
||||
/* Special processing for iw_point, set offset
|
||||
* in pointer field.
|
||||
*/
|
||||
|
||||
iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
|
||||
memcpy(&iwe->u.essid + 1,
|
||||
ap_list_buffer[bss_count].ssid, essid_len);
|
||||
wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
|
||||
priv->scan_result_size +=
|
||||
ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
result_size -= ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
|
||||
/* Copy link quality info */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(qual))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(qual);
|
||||
iwe->cmd = IWEVQUAL;
|
||||
iwe->u.qual.qual = 0x00;
|
||||
wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
|
||||
iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
|
||||
iwe->u.qual.noise = 0x00;
|
||||
iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
|
||||
result_size -= ESP_IW_EVENT_SIZE(qual);
|
||||
|
||||
/* Copy AP mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(mode))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(mode);
|
||||
iwe->cmd = SIOCGIWMODE;
|
||||
iwe->u.mode = IW_MODE_MASTER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
|
||||
result_size -= ESP_IW_EVENT_SIZE(mode);
|
||||
|
||||
/* Copy AP encryption mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(data))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(data);
|
||||
iwe->cmd = SIOCGIWENCODE;
|
||||
iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||
iwe->u.data.length = 0;
|
||||
iwe->u.essid.pointer = NULL;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
|
||||
result_size -= ESP_IW_EVENT_SIZE(data);
|
||||
|
||||
/* Copy AP channel */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(freq))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(freq);
|
||||
iwe->cmd = SIOCGIWFREQ;
|
||||
iwe->u.freq.e = 0;
|
||||
iwe->u.freq.m = ap_list_buffer[bss_count].primary;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
|
||||
result_size -= ESP_IW_EVENT_SIZE(freq);
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
iwe->cmd = SIOCGIWESSID;
|
||||
iwe->u.essid.flags = 0;
|
||||
iwe->u.essid.length = essid_len;
|
||||
|
||||
/* Special processing for iw_point, set offset in pointer field */
|
||||
|
||||
iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
|
||||
memcpy(&iwe->u.essid + 1,
|
||||
ap_list_buffer[bss_count].ssid, essid_len);
|
||||
wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
|
||||
priv->scan_result_size +=
|
||||
ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
result_size -= ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
|
||||
|
||||
/* Copy link quality info */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(qual))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(qual);
|
||||
iwe->cmd = IWEVQUAL;
|
||||
iwe->u.qual.qual = 0x00;
|
||||
wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
|
||||
iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
|
||||
iwe->u.qual.noise = 0x00;
|
||||
iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
|
||||
result_size -= ESP_IW_EVENT_SIZE(qual);
|
||||
|
||||
/* Copy AP mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(mode))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(mode);
|
||||
iwe->cmd = SIOCGIWMODE;
|
||||
iwe->u.mode = IW_MODE_MASTER;
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
|
||||
result_size -= ESP_IW_EVENT_SIZE(mode);
|
||||
|
||||
/* Copy AP encryption mode */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(data))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(data);
|
||||
iwe->cmd = SIOCGIWENCODE;
|
||||
iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||
iwe->u.data.length = 0;
|
||||
iwe->u.essid.pointer = NULL;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
|
||||
result_size -= ESP_IW_EVENT_SIZE(data);
|
||||
|
||||
/* Copy AP channel */
|
||||
|
||||
if (result_size < ESP_IW_EVENT_SIZE(freq))
|
||||
{
|
||||
goto scan_result_full;
|
||||
}
|
||||
|
||||
iwe = (struct iw_event *)
|
||||
&priv->scan_result[priv->scan_result_size];
|
||||
iwe->len = ESP_IW_EVENT_SIZE(freq);
|
||||
iwe->cmd = SIOCGIWFREQ;
|
||||
iwe->u.freq.e = 0;
|
||||
iwe->u.freq.m = ap_list_buffer[bss_count].primary;
|
||||
|
||||
priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
|
||||
result_size -= ESP_IW_EVENT_SIZE(freq);
|
||||
}
|
||||
|
||||
parse_done = true;
|
||||
@@ -471,7 +537,7 @@ scan_result_full:
|
||||
ap_list_buffer = NULL;
|
||||
}
|
||||
|
||||
g_scan_priv.scan_status = ESP_SCAN_DONE;
|
||||
priv->scan_status = ESP_SCAN_DONE;
|
||||
nxsem_post(&priv->scan_signal);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user