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 # endif
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT # ifdef ESP_ERR_DPP_AUTH_TIMEOUT
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not received in time */ 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 # endif
// components/esp_common/include/esp_err.h // components/esp_common/include/esp_err.h
# ifdef ESP_ERR_MESH_BASE # ifdef ESP_ERR_MESH_BASE

View File

@ -17,11 +17,14 @@ extern "C" {
#endif #endif
#define ESP_DPP_AUTH_TIMEOUT_SECS 1 #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_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_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_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_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. */ /** @brief Types of Bootstrap Methods for DPP. */
typedef enum dpp_bootstrap_type { typedef enum dpp_bootstrap_type {
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
@ -83,6 +86,7 @@ esp_err_t esp_supp_dpp_deinit(void);
* *
* @return * @return
* - ESP_OK: Success * - ESP_OK: Success
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
* - ESP_FAIL: Failure * - ESP_FAIL: Failure
*/ */
esp_err_t esp_err_t

View File

@ -15,6 +15,7 @@
#include "esp_event.h" #include "esp_event.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "esp_wps_i.h" #include "esp_wps_i.h"
#include "rsn_supp/wpa.h" #include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h" #include "rsn_supp/pmksa_cache.h"
@ -575,6 +576,7 @@ static void esp_dpp_task(void *pvParameters)
break; break;
} }
channel = p->chan_list[counter++ % p->num_chan]; 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, ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb); BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
if (ret != ESP_OK) { 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) static char *esp_dpp_parse_chan_list(const char *chan_list)
{ {
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_channels = os_zalloc(14 * 6 + 1); size_t max_uri_len = ESP_DPP_MAX_CHAN_COUNT * 8 + strlen(" chan=") + 1;
const char *pos = chan_list;
const char *pos2; char *uri_channels = os_zalloc(max_uri_len);
char *pos3 = uri_channels; if (!uri_channels) {
wpa_printf(MSG_WARNING, "DPP: URI allocation failed");
return NULL;
}
char *uri_ptr = uri_channels;
params->num_chan = 0; params->num_chan = 0;
os_memcpy(pos3, " chan=", strlen(" chan=")); /* Append " chan=" at the beginning of the URI */
pos3 += strlen(" chan="); strcpy(uri_ptr, " chan=");
uri_ptr += strlen(" chan=");
while (pos && *pos) { while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
int channel; int channel = 0;
int len = strlen(chan_list);
pos2 = pos; /* Parse the channel number */
while (*pos2 >= '0' && *pos2 <= '9') { while (*chan_list >= '0' && *chan_list <= '9') {
pos2++; channel = channel * 10 + (*chan_list - '0');
chan_list++;
} }
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
channel = atoi(pos); /* Validate the channel number */
if (channel < 1 || channel > 14) { 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); os_free(uri_channels);
return NULL; 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)) { if (!params->num_chan) {
break; 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; 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; struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list); 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); char *command = os_zalloc(1200);
int ret; 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); wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
if (command) { if (command) {
os_free(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 get_operating_class(u8 chan, int sec_channel)
{ {
u8 op_class; u8 op_class = 0;
if (chan < 1 || chan > 14) if (chan >= 1 && chan < 14) {
return 0;
if (sec_channel == 1) if (sec_channel == 1)
op_class = 83; op_class = 83;
else if (sec_channel == -1) else if (sec_channel == -1)
op_class = 84; op_class = 84;
else else
op_class = 81; 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; return op_class;
} }