xtensa/esp32: Support esp32 wireless ioctl cmd

This commit is contained in:
chenwen 2021-01-29 15:31:14 +08:00 committed by Alan Carvalho de Assis
parent ca05ff5ffb
commit f54aef9977
12 changed files with 2476 additions and 209 deletions

View File

@ -909,6 +909,12 @@ config ESP32_WIFI_CONNECT_TIMEOUT
help
Max waiting time of connecting to AP.
config ESP32_WIFI_SCAN_RESULT_SIZE
int "Scan result buffer"
default 4096
help
Maximum scan result buffer size.
config ESP32_WIFI_SAVE_PARAM
bool "Save WiFi Parameters"
default n

View File

@ -201,7 +201,7 @@ clean_context::
INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include)
INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include$(DELIM)esp32)
CHIP_CSRCS += esp32_wlan.c esp32_wifi_adapter.c
CHIP_CSRCS += esp32_wlan.c esp32_wifi_utils.c esp32_wifi_adapter.c
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)libs$(DELIM)esp32
EXTRA_LIBS += -lcore -lrtc -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lphy -lwpa_supplicant

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,8 @@ extern "C"
enum wifi_adpt_evt_e
{
WIFI_ADPT_EVT_STA_START = 0,
WIFI_ADPT_EVT_SCAN_DONE = 0,
WIFI_ADPT_EVT_STA_START,
WIFI_ADPT_EVT_STA_CONNECT,
WIFI_ADPT_EVT_STA_DISCONNECT,
WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE,
@ -145,7 +146,8 @@ int esp_wifi_notify_subscribe(pid_t pid, FAR struct sigevent *event);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -161,7 +163,8 @@ int esp_wifi_sta_start(void);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -178,7 +181,8 @@ int esp_wifi_sta_stop(void);
* len - Packet length
*
* Returned Value:
* 0 if success or others if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -194,7 +198,8 @@ int esp_wifi_sta_send_data(void *pbuf, uint32_t len);
* recv_cb - Receive callback function
*
* Returned Value:
* 0 if success or others if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -238,35 +243,55 @@ int esp_wifi_sta_read_mac(uint8_t *mac);
* Name: esp_wifi_set_password
*
* Description:
* Set WiFi station password
* Set/Get WiFi station password
*
* Input Parameters:
* pdata - Password buffer pointer
* len - Password length
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_set_password(const uint8_t *pdata, uint8_t len);
int esp_wifi_sta_password(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_set_ssid
* Name: esp_wifi_sta_essid
*
* Description:
* Set WiFi station SSID
* Set/Get WiFi station ESSID
*
* Input Parameters:
* pdata - SSID buffer pointer
* len - SSID length
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_set_ssid(const uint8_t *pdata, uint8_t len);
int esp_wifi_sta_essid(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_bssid
*
* Description:
* Set/Get WiFi station BSSID
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_bssid(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_connect
@ -278,7 +303,8 @@ int esp_wifi_sta_set_ssid(const uint8_t *pdata, uint8_t len);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -294,11 +320,156 @@ int esp_wifi_sta_connect(void);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_disconnect(void);
/****************************************************************************
* Name: esp_wifi_sta_mode
*
* Description:
* Set/Get WiFi Station mode code.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_mode(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_auth
*
* Description:
* Set/Get station authentication mode params.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_auth(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_freq
*
* Description:
* Get station frequency.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_freq(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_bitrate
*
* Description:
* Get station default bit rate (Mbps).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_bitrate(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_get_txpower
*
* Description:
* Get station transmit power (dBm).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_txpower(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_get_channel_range
*
* Description:
* Get station range of channel parameters.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_channel(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_country
*
* Description:
* Configure country info.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_country(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_sta_rssi
*
* Description:
* Get WiFi sensitivity (dBm).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_sta_rssi(struct iwreq *iwr, bool set);
#endif
#ifdef ESP32_WLAN_HAS_SOFTAP
@ -313,7 +484,8 @@ int esp_wifi_sta_disconnect(void);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -329,7 +501,8 @@ int esp_wifi_softap_start(void);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -346,7 +519,8 @@ int esp_wifi_softap_stop(void);
* len - Packet length
*
* Returned Value:
* 0 if success or others if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -362,7 +536,8 @@ int esp_wifi_softap_send_data(void *pbuf, uint32_t len);
* recv_cb - Receive callback function
*
* Returned Value:
* 0 if success or others if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -403,38 +578,58 @@ void esp_wifi_softap_register_txdone_cb(wifi_txdone_cb_t cb);
int esp_wifi_softap_read_mac(uint8_t *mac);
/****************************************************************************
* Name: esp_wifi_softap_set_password
* Name: esp_wifi_softap_password
*
* Description:
* Set WiFi softAP password
* Set/Get WiFi SoftAP password
*
* Input Parameters:
* pdata - Password buffer pointer
* len - Password length
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_set_password(const uint8_t *pdata, uint8_t len);
int esp_wifi_softap_password(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_set_ssid
* Name: esp_wifi_softap_essid
*
* Description:
* Set WiFi softAP SSID
* Set/Get WiFi SoftAP ESSID
*
* Input Parameters:
* pdata - SSID buffer pointer
* len - SSID length
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_set_ssid(const uint8_t *pdata, uint8_t len);
int esp_wifi_softap_essid(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_bssid
*
* Description:
* Set/Get WiFi softAP BSSID
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_bssid(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_connect
@ -446,7 +641,8 @@ int esp_wifi_softap_set_ssid(const uint8_t *pdata, uint8_t len);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
@ -462,11 +658,155 @@ int esp_wifi_softap_connect(void);
* None
*
* Returned Value:
* 0 if success or -1 if fail
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_disconnect(void);
/****************************************************************************
* Name: esp_wifi_softap_mode
*
* Description:
* Set/Get WiFi SoftAP mode code.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_mode(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_auth
*
* Description:
* Set/Get authentication mode params.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_auth(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_freq
*
* Description:
* Set/Get SoftAP frequency.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_freq(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_get_bitrate
*
* Description:
* Get SoftAP default bit rate (Mbps).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_bitrate(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_txpower
*
* Description:
* Get SoftAP transmit power (dBm).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_txpower(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_channel
*
* Description:
* Get SoftAP range of channel parameters.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_channel(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_country
*
* Description:
* Configure country info.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_country(struct iwreq *iwr, bool set);
/****************************************************************************
* Name: esp_wifi_softap_rssi
*
* Description:
* Get WiFi sensitivity (dBm).
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
* set - true: set data; false: get data
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_softap_rssi(struct iwreq *iwr, bool set);
#endif
#ifdef __cplusplus

View File

@ -0,0 +1,516 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_wifi_utils.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/net/arp.h>
#include <nuttx/wireless/wireless.h>
#include "esp32_wifi_adapter.h"
#include "esp32_wifi_utils.h"
#include "espidf_wifi.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Helper to get iw_event size */
#define ESP_IW_EVENT_SIZE(field) \
(offsetof(struct iw_event, u) + sizeof(((union iwreq_data *)0)->field))
#ifdef CONFIG_ESP32_WIFI_SCAN_RESULT_SIZE
# define WIFI_SCAN_RESULT_SIZE CONFIG_ESP32_WIFI_SCAN_RESULT_SIZE
#else
# define WIFI_SCAN_RESULT_SIZE (4096)
#endif
#define SCAN_TIME_SEC (5)
#define SSID_LEN (33)
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/****************************************************************************
* Private Types
****************************************************************************/
enum scan_status_e
{
ESP_SCAN_DISABLED = 0,
ESP_SCAN_RUN,
ESP_SCAN_DONE
};
/* WiFi scan result information */
struct wifi_scan_result
{
enum scan_status_e scan_status; /* Scan status */
sem_t scan_signal; /* Scan notification signal */
uint8_t *scan_result; /* Temp buffer that holds results */
unsigned int scan_result_size; /* Current size of temp buffer */
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct wifi_scan_result g_scan_priv;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp_wifi_start_scan
*
* Description:
* Scan all available APs.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_start_scan(struct iwreq *iwr)
{
struct wifi_scan_result *priv = &g_scan_priv;
wifi_scan_config_t *config = NULL;
uint8_t target_ssid[SSID_LEN];
struct iw_scan_req *req;
int ret = 0;
memset(target_ssid, 0x0, sizeof(SSID_LEN));
if (iwr == NULL)
{
wlerr("ERROR: Invalid ioctl cmd.\n");
return -EINVAL;
}
if (g_scan_priv.scan_status != ESP_SCAN_DISABLED)
{
return OK;
}
config = kmm_malloc(sizeof(wifi_scan_config_t));
if (config == NULL)
{
wlerr("ERROR: Cannot allocate result buffer\n");
return -ENOMEM;
}
memset(config, 0x0, sizeof(wifi_scan_config_t));
if (iwr->u.data.pointer &&
iwr->u.data.length >= sizeof(struct iw_scan_req))
{
req = (struct iw_scan_req *)iwr->u.data.pointer;
config->scan_type = (req->scan_type == IW_SCAN_TYPE_ACTIVE ?
WIFI_SCAN_TYPE_ACTIVE : WIFI_SCAN_TYPE_PASSIVE);
if (iwr->u.data.flags & IW_SCAN_THIS_ESSID &&
req->essid_len < sizeof(target_ssid))
{
/* Scan specific ESSID */
memcpy(&target_ssid[0], req->essid, req->essid_len);
config->ssid = &target_ssid[0];
config->ssid[req->essid_len] = '\0';
}
}
else
{
/* Default scan parameters */
wlinfo("INFO: Use default scan parameters\n");
config->scan_type = WIFI_SCAN_TYPE_ACTIVE; /* Active scan */
}
esp_wifi_start();
esp_wifi_scan_stop();
ret = esp_wifi_scan_start(config, false);
if (ret != OK)
{
wlerr("ERROR: Scan error, ret: %d\n", ret);
}
else
{
/* Allocate buffer to store scan result */
if (priv->scan_result == NULL)
{
priv->scan_result = kmm_malloc(WIFI_SCAN_RESULT_SIZE);
if (priv->scan_result == NULL)
{
wlerr("ERROR: Cannot allocate result buffer\n");
ret = -ENOMEM;
}
else
{
memset(priv->scan_result, 0x0, WIFI_SCAN_RESULT_SIZE);
}
}
}
if (config)
{
kmm_free(config);
config = NULL;
wlinfo("INFO: start scan\n");
}
g_scan_priv.scan_status = ESP_SCAN_RUN;
return ret;
}
/****************************************************************************
* Name: esp_wifi_get_scan_results
*
* Description:
* Get scan result
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_get_scan_results(struct iwreq *iwr)
{
int ret = OK;
struct timespec abstime;
static bool scan_block = false;
struct wifi_scan_result *priv = &g_scan_priv;
if (g_scan_priv.scan_status == ESP_SCAN_RUN)
{
if (scan_block == false)
{
scan_block = true;
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += SCAN_TIME_SEC;
nxsem_timedwait(&priv->scan_signal, &abstime);
scan_block = false;
}
else
{
ret = -EINVAL;
goto exit_failed;
}
}
if ((iwr == NULL) || (g_scan_priv.scan_status != ESP_SCAN_DONE))
{
ret = -EINVAL;
goto exit_failed;
}
if (!priv->scan_result)
{
/* Result have already been requested */
ret = OK;
iwr->u.data.length = 0;
goto exit_failed;
}
if (iwr->u.data.pointer == NULL ||
iwr->u.data.length < priv->scan_result_size)
{
/* Stat request, return scan_result_size */
ret = -E2BIG;
iwr->u.data.pointer = NULL;
iwr->u.data.length = priv->scan_result_size;
goto exit_failed;
}
if (priv->scan_result_size <= 0)
{
ret = OK;
iwr->u.data.length = 0;
goto exit_free_buffer;
}
/* Copy result to user buffer */
if (iwr->u.data.length > priv->scan_result_size)
{
iwr->u.data.length = priv->scan_result_size;
}
memcpy(iwr->u.data.pointer, priv->scan_result, iwr->u.data.length);
exit_free_buffer:
/* Free scan result buffer */
kmm_free(priv->scan_result);
priv->scan_result = NULL;
priv->scan_result_size = 0;
g_scan_priv.scan_status = ESP_SCAN_DISABLED;
exit_failed:
if (ret < 0)
{
iwr->u.data.length = 0;
}
return ret;
}
/****************************************************************************
* Name: esp_wifi_scan_event_parse
*
* Description:
* Parse scan information
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void esp_wifi_scan_event_parse(void)
{
struct wifi_scan_result *priv = &g_scan_priv;
wifi_ap_record_t *ap_list_buffer = NULL;
uint16_t bss_total = 0;
uint8_t bss_count = 0;
bool parse_done = false;
esp_wifi_scan_get_ap_num(&bss_total);
if (bss_total == 0)
{
wlinfo("INFO: None AP is scanned\n");
return;
}
ap_list_buffer = kmm_malloc(bss_total * sizeof(wifi_ap_record_t));
if (ap_list_buffer == NULL)
{
wlerr("ERROR: Failed to malloc buffer to print scan results");
return;
}
memset(ap_list_buffer, 0x0, sizeof(ap_list_buffer));
if (esp_wifi_scan_get_ap_records(&bss_total,
(wifi_ap_record_t *)ap_list_buffer) == OK)
{
struct iw_event *iwe;
unsigned int result_size;
size_t essid_len;
size_t essid_len_aligned;
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))
{
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);
}
parse_done = true;
}
scan_result_full:
/* Continue instead of break to log dropped AP results */
if (parse_done == false)
{
wlerr("ERROR: No more space in scan_result buffer\n");
}
if (ap_list_buffer)
{
kmm_free(ap_list_buffer);
ap_list_buffer = NULL;
}
g_scan_priv.scan_status = ESP_SCAN_DONE;
nxsem_post(&priv->scan_signal);
}
/****************************************************************************
* Name: esp_wifi_scan_init
*
* Description:
* Initialize ESP32 WiFi scan parameter.
*
* Input Parameters:
* None
*
* Returned Value:
* OK is returned on success. Otherwise, a negated errno value is returned.
*
****************************************************************************/
int esp_wifi_scan_init(void)
{
int ret;
struct wifi_scan_result *scan_priv = &g_scan_priv;
/* Initialize the scan structure */
memset(scan_priv, 0, sizeof(*scan_priv));
/* Init scan signal */
if ((ret = nxsem_init(&scan_priv->scan_signal, 0, 0)) != OK)
{
wlerr("ERROR: Initialization scan signal failed: %d\n", ret);
return ret;
}
if ((ret = nxsem_set_protocol(&scan_priv->scan_signal,
SEM_PRIO_NONE)) != OK)
{
wlerr("ERROR: Set semaphore protocol attribute failed: %d\n", ret);
}
return ret;
}

View File

@ -0,0 +1,120 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_wifi_utils.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_UTILS_H
#define __ARCH_XTENSA_SRC_ESP32_ESP32_UTILS_H
#include <nuttx/config.h>
#include <nuttx/net/netdev.h>
#include <stdint.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_wifi_start_scan
*
* Description:
* Scan all available APs.
*
* Input Parameters:
* iwr - The argument of the ioctl cmd
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_start_scan(struct iwreq *iwr);
/****************************************************************************
* Name: esp_wifi_get_scan_results
*
* Description:
* Get scan result
*
* Input Parameters:
* req The argument of the ioctl cmd
*
* Returned Value:
* OK on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
int esp_wifi_get_scan_results(struct iwreq *iwr);
/****************************************************************************
* Name: esp_wifi_scan_event_parse
*
* Description:
* Parse scan information
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void esp_wifi_scan_event_parse(void);
/****************************************************************************
* Name: esp_wifi_scan_para
*
* Description:
* Initialize ESP32 WiFi scan parameter.
*
* Input Parameters:
* None
*
* Returned Value:
* OK is returned on success. Otherwise, a negated errno value is returned.
*
****************************************************************************/
int esp_wifi_scan_init(void);
#ifdef __cplusplus
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_UTILS_H */

View File

@ -44,6 +44,8 @@
#endif
#include "esp32_wlan.h"
#include "esp32_wifi_utils.h"
#include "esp32_wifi_adapter.h"
/****************************************************************************
* Pre-processor Definitions
@ -111,19 +113,21 @@ struct wlan_pktbuf
struct wlan_ops
{
int (*start)(void);
int (*send)(void *pdata, size_t n);
int (*ssid)(const uint8_t *pdata, uint8_t n);
int (*passwd)(const uint8_t *pdata, uint8_t n);
int (*essid)(struct iwreq *iwr, bool set);
int (*bssid)(struct iwreq *iwr, bool set);
int (*passwd)(struct iwreq *iwr, bool set);
int (*mode)(struct iwreq *iwr, bool set);
int (*auth)(struct iwreq *iwr, bool set);
int (*freq)(struct iwreq *iwr, bool set);
int (*bitrate)(struct iwreq *iwr, bool set);
int (*txpower)(struct iwreq *iwr, bool set);
int (*channel)(struct iwreq *iwr, bool set);
int (*country)(struct iwreq *iwr, bool set);
int (*rssi)(struct iwreq *iwr, bool set);
int (*connect)(void);
int (*disconnect)(void);
int (*event)(pid_t pid, FAR struct sigevent *event);
int (*stop)(void);
};
@ -179,8 +183,17 @@ static const struct wlan_ops g_sta_ops =
{
.start = esp_wifi_sta_start,
.send = esp_wifi_sta_send_data,
.ssid = esp_wifi_sta_set_ssid,
.passwd = esp_wifi_sta_set_password,
.essid = esp_wifi_sta_essid,
.bssid = esp_wifi_sta_bssid,
.passwd = esp_wifi_sta_password,
.mode = esp_wifi_sta_mode,
.auth = esp_wifi_sta_auth,
.freq = esp_wifi_sta_freq,
.bitrate = esp_wifi_sta_bitrate,
.txpower = esp_wifi_sta_txpower,
.channel = esp_wifi_sta_channel,
.country = esp_wifi_sta_country,
.rssi = esp_wifi_sta_rssi,
.connect = esp_wifi_sta_connect,
.disconnect = esp_wifi_sta_disconnect,
.event = esp_wifi_notify_subscribe,
@ -193,8 +206,17 @@ static const struct wlan_ops g_softap_ops =
{
.start = esp_wifi_softap_start,
.send = esp_wifi_softap_send_data,
.ssid = esp_wifi_softap_set_ssid,
.passwd = esp_wifi_softap_set_password,
.essid = esp_wifi_softap_essid,
.bssid = esp_wifi_softap_bssid,
.passwd = esp_wifi_softap_password,
.mode = esp_wifi_softap_mode,
.auth = esp_wifi_softap_auth,
.freq = esp_wifi_softap_freq,
.bitrate = esp_wifi_softap_bitrate,
.txpower = esp_wifi_softap_txpower,
.channel = esp_wifi_softap_channel,
.country = esp_wifi_softap_country,
.rssi = esp_wifi_softap_rssi,
.connect = esp_wifi_softap_connect,
.disconnect = esp_wifi_softap_disconnect,
.event = esp_wifi_notify_subscribe,
@ -1477,54 +1499,136 @@ static int wlan_ioctl(FAR struct net_driver_s *dev,
#endif
case SIOCSIWENCODEEXT:
{
struct iw_encode_ext *ext = iwr->u.encoding.pointer;
ret = ops->passwd(ext->key, ext->key_len);
if (ret < 0)
{
nerr("ERROR: Failed to set password\n");
}
}
break;
case SIOCSIWESSID:
{
struct iw_point *essid = &iwr->u.essid;
if (essid->length)
{
ret = ops->ssid(essid->pointer, essid->length);
if (ret < 0)
{
nerr("ERROR: Failed to set SSID\n");
break;
}
ret = ops->passwd(iwr, true);
ret = ops->connect();
if (ret < 0)
{
nerr("ERROR: Failed to connect\n");
break;
}
}
else
{
ret = ops->disconnect();
if (ret < 0)
{
nerr("ERROR: Failed to connect\n");
break;
}
}
}
break;
case SIOCSIWMODE:
ret = OK;
case SIOCGIWENCODEEXT:
ret = ops->passwd(iwr, false);
break;
case SIOCSIWAUTH:
ret = OK;
case SIOCSIWESSID:
if ((iwr->u.essid.flags == IW_ESSID_ON) ||
(iwr->u.essid.flags == IW_ESSID_DELAY_ON))
{
ret = ops->essid(iwr, true);
if (ret < 0)
{
break;
}
if (iwr->u.essid.flags == IW_ESSID_ON)
{
ret = ops->connect();
}
}
else
{
ret = ops->disconnect();
}
break;
case SIOCSIWFREQ:
ret = OK;
case SIOCGIWESSID: /* Get ESSID */
ret = ops->essid(iwr, false);
break;
case SIOCSIWAP: /* Set access point MAC addresses */
if (iwr->u.ap_addr.sa_data[0] != 0 &&
iwr->u.ap_addr.sa_data[1] != 0 &&
iwr->u.ap_addr.sa_data[2] != 0)
{
ret = ops->bssid(iwr, true);
if (ret < 0)
{
nerr("ERROR: Failed to set BSSID\n");
break;
}
ret = ops->connect();
if (ret < 0)
{
nerr("ERROR: Failed to connect\n");
break;
}
}
else
{
ret = ops->disconnect();
if (ret < 0)
{
nerr("ERROR: Failed to connect\n");
break;
}
}
break;
case SIOCGIWAP: /* Get access point MAC addresses */
ret = ops->bssid(iwr, false);
break;
case SIOCSIWSCAN:
ret = esp_wifi_start_scan(iwr);
break;
case SIOCGIWSCAN:
ret = esp_wifi_get_scan_results(iwr);
break;
case SIOCSIWCOUNTRY: /* Set country code */
ret = ops->country(iwr, true);
break;
case SIOCGIWSENS: /* Get sensitivity (dBm) */
ret = ops->rssi(iwr, false);
break;
case SIOCSIWMODE: /* Set operation mode */
ret = ops->mode(iwr, true);
break;
case SIOCGIWMODE: /* Get operation mode */
ret = ops->mode(iwr, false);
break;
case SIOCSIWAUTH: /* Set authentication mode params */
ret = ops->auth(iwr, true);
break;
case SIOCGIWAUTH: /* Get authentication mode params */
ret = ops->auth(iwr, false);
break;
case SIOCSIWFREQ: /* Set channel/frequency (MHz) */
ret = ops->freq(iwr, true);
break;
case SIOCGIWFREQ: /* Get channel/frequency (MHz) */
ret = ops->freq(iwr, false);
break;
case SIOCSIWRATE: /* Set default bit rate (Mbps) */
wlwarn("WARNING: SIOCSIWRATE not implemented\n");
ret = -ENOSYS;
break;
case SIOCGIWRATE: /* Get default bit rate (Mbps) */
ret = ops->bitrate(iwr, false);
break;
case SIOCSIWTXPOW: /* Set transmit power (dBm) */
ret = ops->txpower(iwr, true);
break;
case SIOCGIWTXPOW: /* Get transmit power (dBm) */
ret = ops->txpower(iwr, false);
break;
case SIOCGIWRANGE: /* Get range of parameters */
ret = ops->channel(iwr, false);
break;
default:
nerr("ERROR: Unrecognized IOCTL command: %d\n", cmd);
ret = -ENOTTY; /* Special return value for this case */
@ -1747,6 +1851,13 @@ int esp32_wlan_sta_initialize(void)
eth_mac[0], eth_mac[1], eth_mac[2],
eth_mac[3], eth_mac[4], eth_mac[5]);
ret = esp_wifi_scan_init();
if (ret < 0)
{
nerr("ERROR: Initialize WiFi scan parameter error: %d\n", ret);
return ret;
}
ret = esp32_net_initialize(ESP32_WLAN_STA_DEVNO, eth_mac, &g_sta_ops);
if (ret < 0)
{
@ -1807,6 +1918,13 @@ int esp32_wlan_softap_initialize(void)
eth_mac[0], eth_mac[1], eth_mac[2],
eth_mac[3], eth_mac[4], eth_mac[5]);
ret = esp_wifi_scan_init();
if (ret < 0)
{
nerr("ERROR: Initialize WiFi scan parameter error: %d\n", ret);
return ret;
}
ret = esp32_net_initialize(ESP32_WLAN_SOFTAP_DEVNO, eth_mac,
&g_softap_ops);
if (ret < 0)

View File

@ -43,7 +43,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_MAX_TASKS=16
CONFIG_MM_REGIONS=2
CONFIG_MM_REGIONS=3
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y

View File

@ -32,6 +32,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_MAX_TASKS=16
CONFIG_MM_REGIONS=3
CONFIG_NAME_MAX=48

View File

@ -31,6 +31,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_MAX_TASKS=16
CONFIG_MM_REGIONS=3
CONFIG_NAME_MAX=48

View File

@ -32,6 +32,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_MAX_TASKS=16
CONFIG_MM_REGIONS=3
CONFIG_NAME_MAX=48

View File

@ -268,6 +268,12 @@
#define IW_MAX_FREQUENCIES 32 /* Max. frequencies in struct iw_range */
/* ESSID flags */
#define IW_ESSID_OFF 0 /* Disconnect with access point */
#define IW_ESSID_ON 1 /* Connect with access point */
#define IW_ESSID_DELAY_ON 2 /* Delay the connection behavior of essid */
/* Transmit Power flags available */
#define IW_TXPOW_TYPE 0x00ff /* Type of value */