Skip to content

Commit e24005c

Browse files
committed
fix(esp_wifi): Add support for 5ghz channel list for easy connect
1 parent 13d4235 commit e24005c

File tree

4 files changed

+129
-40
lines changed

4 files changed

+129
-40
lines changed

components/esp_common/src/esp_err_to_name.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ static const esp_err_msg_t esp_err_msg_table[] = {
469469
# endif
470470
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT
471471
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not received in time */
472+
# endif
473+
# ifdef ESP_ERR_DPP_INVALID_LIST
474+
ERR_TBL_IT(ESP_ERR_DPP_INVALID_LIST), /* 12443 0x309b Channel list given in
475+
esp_supp_dpp_bootstrap_gen() is not
476+
valid or too big */
472477
# endif
473478
// components/esp_common/include/esp_err.h
474479
# ifdef ESP_ERR_MESH_BASE

components/wpa_supplicant/esp_supplicant/include/esp_dpp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ extern "C" {
1717
#endif
1818

1919
#define ESP_DPP_AUTH_TIMEOUT_SECS 1
20+
#define ESP_DPP_MAX_CHAN_COUNT 5
2021

2122
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
2223
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
2324
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
2425
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */
26+
#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 */
27+
2528
/** @brief Types of Bootstrap Methods for DPP. */
2629
typedef enum dpp_bootstrap_type {
2730
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
@@ -83,6 +86,7 @@ esp_err_t esp_supp_dpp_deinit(void);
8386
*
8487
* @return
8588
* - ESP_OK: Success
89+
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
8690
* - ESP_FAIL: Failure
8791
*/
8892
esp_err_t

components/wpa_supplicant/esp_supplicant/src/esp_dpp.c

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "esp_event.h"
1616
#include "esp_wifi.h"
1717
#include "common/ieee802_11_defs.h"
18+
#include "common/ieee802_11_common.h"
1819
#include "esp_wps_i.h"
1920
#include "rsn_supp/wpa.h"
2021
#include "rsn_supp/pmksa_cache.h"
@@ -575,6 +576,7 @@ static void esp_dpp_task(void *pvParameters)
575576
break;
576577
}
577578
channel = p->chan_list[counter++ % p->num_chan];
579+
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel);
578580
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
579581
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
580582
if (ret != ESP_OK) {
@@ -687,47 +689,81 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
687689
static char *esp_dpp_parse_chan_list(const char *chan_list)
688690
{
689691
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
690-
char *uri_channels = os_zalloc(14 * 6 + 1);
691-
const char *pos = chan_list;
692-
const char *pos2;
693-
char *pos3 = uri_channels;
692+
size_t max_uri_len = ESP_DPP_MAX_CHAN_COUNT * 8 + strlen(" chan=") + 1;
693+
694+
char *uri_channels = os_zalloc(max_uri_len);
695+
if (!uri_channels) {
696+
wpa_printf(MSG_WARNING, "DPP: URI allocation failed");
697+
return NULL;
698+
}
699+
700+
char *uri_ptr = uri_channels;
694701
params->num_chan = 0;
695702

696-
os_memcpy(pos3, " chan=", strlen(" chan="));
697-
pos3 += strlen(" chan=");
703+
/* Append " chan=" at the beginning of the URI */
704+
strcpy(uri_ptr, " chan=");
705+
uri_ptr += strlen(" chan=");
698706

699-
while (pos && *pos) {
700-
int channel;
701-
int len = strlen(chan_list);
707+
while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
708+
int channel = 0;
702709

703-
pos2 = pos;
704-
while (*pos2 >= '0' && *pos2 <= '9') {
705-
pos2++;
710+
/* Parse the channel number */
711+
while (*chan_list >= '0' && *chan_list <= '9') {
712+
channel = channel * 10 + (*chan_list - '0');
713+
chan_list++;
706714
}
707-
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
708-
channel = atoi(pos);
709-
if (channel < 1 || channel > 14) {
710-
os_free(uri_channels);
711-
return NULL;
715+
716+
/* Validate the channel number */
717+
if (CHANNEL_TO_BIT_NUMBER(channel) == 0) {
718+
wpa_printf(MSG_WARNING, "DPP: Skipping invalid channel %d", channel);
719+
/* Skip to the next valid entry */
720+
while (*chan_list == ',' || *chan_list == ' ') {
721+
chan_list++;
712722
}
713-
params->chan_list[params->num_chan++] = channel;
714-
os_memcpy(pos3, "81/", strlen("81/"));
715-
pos3 += strlen("81/");
716-
os_memcpy(pos3, pos, (pos2 - pos));
717-
pos3 += (pos2 - pos);
718-
*pos3++ = ',';
719-
720-
pos = pos2 + 1;
723+
continue; // Skip the bad channel and move to the next one
721724
}
722-
while (*pos == ',' || *pos == ' ' || *pos == '\0') {
723-
pos++;
725+
726+
/* Get the operating class for the channel */
727+
u8 oper_class = get_operating_class(channel, 0);
728+
if (oper_class == 0) {
729+
wpa_printf(MSG_WARNING, "DPP: Skipping channel %d due to missing operating class", channel);
730+
/* Skip to the next valid entry */
731+
while (*chan_list == ',' || *chan_list == ' ') {
732+
chan_list++;
733+
}
734+
continue; /* Skip to the next channel if no operating class found */
724735
}
725736

726-
if (((int)(pos - chan_list) >= len)) {
727-
break;
737+
/* Add the valid channel to the list */
738+
params->chan_list[params->num_chan++] = channel;
739+
740+
/* Check if there's space left in uri_channels buffer */
741+
size_t remaining_space = max_uri_len - (uri_ptr - uri_channels);
742+
if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator
743+
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer");
744+
os_free(uri_channels);
745+
return NULL;
728746
}
747+
748+
/* Append the operating class and channel to the URI */
749+
uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel);
750+
751+
/* Skip any delimiters (comma or space) */
752+
while (*chan_list == ',' || *chan_list == ' ') {
753+
chan_list++;
754+
}
755+
}
756+
757+
if (!params->num_chan) {
758+
wpa_printf(MSG_ERROR, "DPP: No valid channel in the list");
759+
os_free(uri_channels);
760+
return NULL;
761+
}
762+
763+
/* Replace the last comma with a space if there was content added */
764+
if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') {
765+
*(uri_ptr - 1) = ' ';
729766
}
730-
*(pos3 - 1) = ' ';
731767

732768
return uri_channels;
733769
}
@@ -742,10 +778,16 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
742778
}
743779
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
744780
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list);
781+
782+
if (params->num_chan > ESP_DPP_MAX_CHAN_COUNT) {
783+
os_free(uri_chan_list);
784+
return ESP_ERR_DPP_INVALID_LIST;
785+
}
786+
745787
char *command = os_zalloc(1200);
746788
int ret;
747789

748-
if (!uri_chan_list || !command || params->num_chan >= 14 || params->num_chan == 0) {
790+
if (!uri_chan_list || !command || params->num_chan > ESP_DPP_MAX_CHAN_COUNT || params->num_chan == 0) {
749791
wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
750792
if (command) {
751793
os_free(command);

components/wpa_supplicant/src/common/ieee802_11_common.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,16 +357,54 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
357357

358358
u8 get_operating_class(u8 chan, int sec_channel)
359359
{
360-
u8 op_class;
360+
u8 op_class = 0;
361+
362+
if (chan >= 1 && chan < 14) {
363+
if (sec_channel == 1)
364+
op_class = 83;
365+
else if (sec_channel == -1)
366+
op_class = 84;
367+
else
368+
op_class = 81;
369+
}
361370

362-
if (chan < 1 || chan > 14)
363-
return 0;
364-
if (sec_channel == 1)
365-
op_class = 83;
366-
else if (sec_channel == -1)
367-
op_class = 84;
368-
else
369-
op_class = 81;
371+
if (chan == 14)
372+
op_class = 82;
373+
374+
#if SOC_WIFI_SUPPORT_5G
375+
if (chan >= 36 && chan <= 48) {
376+
if (sec_channel == 1)
377+
op_class = 116;
378+
else if (sec_channel == -1)
379+
op_class = 117;
380+
else
381+
op_class = 115;
382+
}
383+
if (chan >= 52 && chan <= 64) {
384+
if (sec_channel == 1)
385+
op_class = 119;
386+
else if (sec_channel == -1)
387+
op_class = 120;
388+
else
389+
op_class = 118;
390+
}
391+
if (chan >= 149 && chan <= 177) {
392+
if (sec_channel == 1)
393+
op_class = 126;
394+
else if (sec_channel == -1)
395+
op_class = 127;
396+
else
397+
op_class = 125;
398+
}
399+
if (chan >= 100 && chan <= 144) {
400+
if (sec_channel == 1)
401+
op_class = 122;
402+
else if (sec_channel == -1)
403+
op_class = 123;
404+
else
405+
op_class = 121;
406+
}
407+
#endif
370408

371409
return op_class;
372410
}

0 commit comments

Comments
 (0)