Merge branch 'bugfix/dpp_5ghz_chan_support' into 'master'

fix(esp_wifi): Add support for 5ghz channel list for easy connect

Closes WIFI-6420

See merge request espressif/esp-idf!32146
This commit is contained in:
Kapil Gupta 2024-09-20 14:46:05 +08:00
commit 903c11ff1a
4 changed files with 130 additions and 41 deletions

View File

@ -469,6 +469,11 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not received in time */
# endif
# ifdef ESP_ERR_DPP_INVALID_LIST
ERR_TBL_IT(ESP_ERR_DPP_INVALID_LIST), /* 12443 0x309b Channel list given in
esp_supp_dpp_bootstrap_gen() is not
valid or too big */
# endif
// components/esp_common/include/esp_err.h
# ifdef ESP_ERR_MESH_BASE

View File

@ -17,11 +17,14 @@ extern "C" {
#endif
#define ESP_DPP_AUTH_TIMEOUT_SECS 1
#define ESP_DPP_MAX_CHAN_COUNT 5
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */
#define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */
/** @brief Types of Bootstrap Methods for DPP. */
typedef enum dpp_bootstrap_type {
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
@ -83,6 +86,7 @@ esp_err_t esp_supp_dpp_deinit(void);
*
* @return
* - ESP_OK: Success
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
* - ESP_FAIL: Failure
*/
esp_err_t

View File

@ -15,6 +15,7 @@
#include "esp_event.h"
#include "esp_wifi.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "esp_wps_i.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h"
@ -575,6 +576,7 @@ static void esp_dpp_task(void *pvParameters)
break;
}
channel = p->chan_list[counter++ % p->num_chan];
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel);
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
if (ret != ESP_OK) {
@ -687,47 +689,81 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
static char *esp_dpp_parse_chan_list(const char *chan_list)
{
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_channels = os_zalloc(14 * 6 + 1);
const char *pos = chan_list;
const char *pos2;
char *pos3 = uri_channels;
size_t max_uri_len = ESP_DPP_MAX_CHAN_COUNT * 8 + strlen(" chan=") + 1;
char *uri_channels = os_zalloc(max_uri_len);
if (!uri_channels) {
wpa_printf(MSG_WARNING, "DPP: URI allocation failed");
return NULL;
}
char *uri_ptr = uri_channels;
params->num_chan = 0;
os_memcpy(pos3, " chan=", strlen(" chan="));
pos3 += strlen(" chan=");
/* Append " chan=" at the beginning of the URI */
strcpy(uri_ptr, " chan=");
uri_ptr += strlen(" chan=");
while (pos && *pos) {
int channel;
int len = strlen(chan_list);
while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
int channel = 0;
pos2 = pos;
while (*pos2 >= '0' && *pos2 <= '9') {
pos2++;
/* Parse the channel number */
while (*chan_list >= '0' && *chan_list <= '9') {
channel = channel * 10 + (*chan_list - '0');
chan_list++;
}
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
channel = atoi(pos);
if (channel < 1 || channel > 14) {
/* Validate the channel number */
if (CHANNEL_TO_BIT_NUMBER(channel) == 0) {
wpa_printf(MSG_WARNING, "DPP: Skipping invalid channel %d", channel);
/* Skip to the next valid entry */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
}
continue; // Skip the bad channel and move to the next one
}
/* Get the operating class for the channel */
u8 oper_class = get_operating_class(channel, 0);
if (oper_class == 0) {
wpa_printf(MSG_WARNING, "DPP: Skipping channel %d due to missing operating class", channel);
/* Skip to the next valid entry */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
}
continue; /* Skip to the next channel if no operating class found */
}
/* Add the valid channel to the list */
params->chan_list[params->num_chan++] = channel;
/* Check if there's space left in uri_channels buffer */
size_t remaining_space = max_uri_len - (uri_ptr - uri_channels);
if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer");
os_free(uri_channels);
return NULL;
}
params->chan_list[params->num_chan++] = channel;
os_memcpy(pos3, "81/", strlen("81/"));
pos3 += strlen("81/");
os_memcpy(pos3, pos, (pos2 - pos));
pos3 += (pos2 - pos);
*pos3++ = ',';
pos = pos2 + 1;
/* Append the operating class and channel to the URI */
uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel);
/* Skip any delimiters (comma or space) */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
}
while (*pos == ',' || *pos == ' ' || *pos == '\0') {
pos++;
}
if (((int)(pos - chan_list) >= len)) {
break;
if (!params->num_chan) {
wpa_printf(MSG_ERROR, "DPP: No valid channel in the list");
os_free(uri_channels);
return NULL;
}
/* Replace the last comma with a space if there was content added */
if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') {
*(uri_ptr - 1) = ' ';
}
*(pos3 - 1) = ' ';
return uri_channels;
}
@ -742,10 +778,16 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
}
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list);
if (params->num_chan > ESP_DPP_MAX_CHAN_COUNT) {
os_free(uri_chan_list);
return ESP_ERR_DPP_INVALID_LIST;
}
char *command = os_zalloc(1200);
int ret;
if (!uri_chan_list || !command || params->num_chan >= 14 || params->num_chan == 0) {
if (!uri_chan_list || !command || params->num_chan > ESP_DPP_MAX_CHAN_COUNT || params->num_chan == 0) {
wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
if (command) {
os_free(command);

View File

@ -357,16 +357,54 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
u8 get_operating_class(u8 chan, int sec_channel)
{
u8 op_class;
u8 op_class = 0;
if (chan < 1 || chan > 14)
return 0;
if (chan >= 1 && chan < 14) {
if (sec_channel == 1)
op_class = 83;
else if (sec_channel == -1)
op_class = 84;
else
op_class = 81;
}
if (chan == 14)
op_class = 82;
#if SOC_WIFI_SUPPORT_5G
if (chan >= 36 && chan <= 48) {
if (sec_channel == 1)
op_class = 116;
else if (sec_channel == -1)
op_class = 117;
else
op_class = 115;
}
if (chan >= 52 && chan <= 64) {
if (sec_channel == 1)
op_class = 119;
else if (sec_channel == -1)
op_class = 120;
else
op_class = 118;
}
if (chan >= 149 && chan <= 177) {
if (sec_channel == 1)
op_class = 126;
else if (sec_channel == -1)
op_class = 127;
else
op_class = 125;
}
if (chan >= 100 && chan <= 144) {
if (sec_channel == 1)
op_class = 122;
else if (sec_channel == -1)
op_class = 123;
else
op_class = 121;
}
#endif
return op_class;
}