Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_set_country_code_before_wifi_start_issue_v4.…
Browse files Browse the repository at this point in the history
…3' into 'release/v4.3'

Bugfix/fix set country code before wifi start issue v4.3(Backport v4.3)

See merge request espressif/esp-idf!20106
  • Loading branch information
jack0c committed Sep 23, 2022
2 parents 8034c03 + f1b8861 commit aefd3db
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 43 deletions.
39 changes: 28 additions & 11 deletions components/esp_wifi/include/esp_wifi.h
Expand Up @@ -463,6 +463,21 @@ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number);
esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records);


/**
* @brief Clear AP list found in last scan
*
* @attention When the obtained ap list fails,bss info must be cleared,otherwise it may cause memory leakage.
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_MODE: WiFi mode is wrong
* - ESP_ERR_INVALID_ARG: invalid argument
*/
esp_err_t esp_wifi_clear_ap_list(void);


/**
* @brief Get information of AP which the ESP32 station is associated with
*
Expand Down Expand Up @@ -608,18 +623,19 @@ esp_err_t esp_wifi_get_channel(uint8_t *primary, wifi_second_chan_t *second);
* @attention 1. It is discouraged to call this API since this doesn't validate the per-country rules,
* it's up to the user to fill in all fields according to local regulations.
* Please use esp_wifi_set_country_code instead.
* @attention 2. The default country is CHINA {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}
* @attention 3. When the country policy is WIFI_COUNTRY_POLICY_AUTO, the country info of the AP to which
* the station is connected is used. E.g. if the configured country info is {.cc="USA", .schan=1, .nchan=11}
* @attention 2. The default country is CHINA {.cc="CN", .schan=1, .nchan=13, .policy=WIFI_COUNTRY_POLICY_AUTO}.
* @attention 3. The third octect of country code string is one of the following: ' ', 'O', 'I', 'X', otherwise it is considered as ' '.
* @attention 4. When the country policy is WIFI_COUNTRY_POLICY_AUTO, the country info of the AP to which
* the station is connected is used. E.g. if the configured country info is {.cc="US", .schan=1, .nchan=11}
* and the country info of the AP to which the station is connected is {.cc="JP", .schan=1, .nchan=14}
* then the country info that will be used is {.cc="JP", .schan=1, .nchan=14}. If the station disconnected
* from the AP the country info is set back to the country info of the station automatically,
* {.cc="US", .schan=1, .nchan=11} in the example.
* @attention 4. When the country policy is WIFI_COUNTRY_POLICY_MANUAL, then the configured country info is used always.
* @attention 5. When the country info is changed because of configuration or because the station connects to a different
* @attention 5. When the country policy is WIFI_COUNTRY_POLICY_MANUAL, then the configured country info is used always.
* @attention 6. When the country info is changed because of configuration or because the station connects to a different
* external AP, the country IE in probe response/beacon of the soft-AP is also changed.
* @attention 6. The country configuration is stored into flash.
* @attention 7. When this API is called, the PHY init data will switch to the PHY init data type corresponding to the
* @attention 7. The country configuration is stored into flash.
* @attention 8. When this API is called, the PHY init data will switch to the PHY init data type corresponding to the
* country info.
*
* @param country the configured country info
Expand Down Expand Up @@ -917,7 +933,7 @@ esp_err_t esp_wifi_set_vendor_ie_cb(esp_vendor_ie_cb_t cb, void *ctx);
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_ARG: invalid argument, e.g. parameter is out of range
*/
esp_err_t esp_wifi_set_max_tx_power(int8_t power);
Expand All @@ -930,7 +946,7 @@ esp_err_t esp_wifi_set_max_tx_power(int8_t power);
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_ARG: invalid argument
*/
esp_err_t esp_wifi_get_max_tx_power(int8_t *power);
Expand Down Expand Up @@ -1026,7 +1042,7 @@ esp_err_t esp_wifi_set_csi_rx_cb(wifi_csi_cb_t cb, void *ctx);
* return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start or promiscuous mode is not enabled
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start or promiscuous mode is not enabled
* - ESP_ERR_INVALID_ARG: invalid argument
*/
esp_err_t esp_wifi_set_csi_config(const wifi_csi_config_t *config);
Expand All @@ -1039,7 +1055,7 @@ esp_err_t esp_wifi_set_csi_config(const wifi_csi_config_t *config);
* return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start or promiscuous mode is not enabled
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start or promiscuous mode is not enabled
* - ESP_ERR_INVALID_ARG: invalid argument
*/
esp_err_t esp_wifi_set_csi(bool en);
Expand Down Expand Up @@ -1252,6 +1268,7 @@ esp_err_t esp_wifi_set_connectionless_wake_interval(uint16_t interval);
*
* @attention 7. When country code "01" (world safe mode) is set, SoftAP mode won't contain country IE.
* @attention 8. The default country is "CN" and ieee80211d_enabled is TRUE.
* @attention 9. The third octect of country code string is one of the following: ' ', 'O', 'I', 'X', otherwise it is considered as ' '.
*
* @param country the configured country ISO code
* @param ieee80211d_enabled 802.11d is enabled or not
Expand Down
106 changes: 106 additions & 0 deletions components/esp_wifi/test/test_wifi_init.c
Expand Up @@ -220,3 +220,109 @@ TEST_CASE("Calling esp_wifi_stop() without start", "[wifi_init]")
sema = NULL;
test_utils_task_delete(th);
}

static void wifi_country_code_task(void* arg)
{
SemaphoreHandle_t *sema = (SemaphoreHandle_t *) arg;
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

ESP_LOGI(TAG, EMPH_STR("nvs_flash_erase"));
nvs_flash_erase();
ESP_LOGI(TAG, EMPH_STR("nvs_flash_init"));
esp_err_t r = nvs_flash_init();
if (r == ESP_ERR_NVS_NO_FREE_PAGES || r == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGI(TAG, EMPH_STR("no free pages or NFS version mismatch, erase.."));
TEST_ESP_OK(nvs_flash_erase());
r = nvs_flash_init();
}
TEST_ESP_OK(r);
//init tcpip stack
test_case_uses_tcpip();
ESP_LOGI(TAG, EMPH_STR("event_init"));
TEST_ESP_OK(event_init());
ESP_LOGI(TAG, EMPH_STR("esp_wifi_init"));
TEST_ESP_OK(esp_wifi_init(&cfg));

wifi_country_t country;
wifi_country_t country_01 = {.cc="01", .schan=1, .nchan=11, .policy=WIFI_COUNTRY_POLICY_MANUAL};
wifi_country_t country_CN = {.cc="CN", .schan=1, .nchan=13, .policy=WIFI_COUNTRY_POLICY_MANUAL};
ESP_LOGI(TAG, EMPH_STR("esp_wifi_get_country"));
TEST_ESP_OK(esp_wifi_get_country(&country));
TEST_ASSERT(country.cc[0] == country_CN.cc[0] && country.cc[1] == country_CN.cc[1]);

ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_country"));
TEST_ESP_OK(esp_wifi_set_country(&country_01));

ESP_LOGI(TAG, EMPH_STR("esp_wifi_get_country"));
TEST_ESP_OK(esp_wifi_get_country(&country));
TEST_ASSERT(country.cc[0] == country_01.cc[0] && country.cc[1] == country_01.cc[1]);


ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit"));
TEST_ESP_OK(esp_wifi_deinit());
ESP_LOGI(TAG, EMPH_STR("event_deinit"));
TEST_ESP_OK(event_deinit());
ESP_LOGI(TAG, EMPH_STR("nvs_flash_deinit..."));
nvs_flash_deinit();

ESP_LOGI(TAG, EMPH_STR("nvs_flash_erase"));
nvs_flash_erase();
ESP_LOGI(TAG, EMPH_STR("nvs_flash_init"));
r = nvs_flash_init();
if (r == ESP_ERR_NVS_NO_FREE_PAGES || r == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGI(TAG, EMPH_STR("no free pages or NFS version mismatch, erase.."));
TEST_ESP_OK(nvs_flash_erase());
r = nvs_flash_init();
}
TEST_ESP_OK(r);
//init tcpip stack
test_case_uses_tcpip();
ESP_LOGI(TAG, EMPH_STR("event_init"));
TEST_ESP_OK(event_init());
ESP_LOGI(TAG, EMPH_STR("esp_wifi_init"));
TEST_ESP_OK(esp_wifi_init(&cfg));

char country_code_string[3];
char country_code_string_01[3] = "01";
char country_code_string_CN[3] = "CN";
ESP_LOGI(TAG, EMPH_STR("esp_wifi_get_country_code"));
TEST_ESP_OK(esp_wifi_get_country_code(&country_code_string[0]));
TEST_ASSERT(country_code_string[0] == country_code_string_CN[0] && country_code_string[1] == country_code_string_CN[1]);

ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_country_code"));
TEST_ESP_OK(esp_wifi_set_country_code(&country_code_string_01[0], false));

ESP_LOGI(TAG, EMPH_STR("esp_wifi_get_country_code"));
TEST_ESP_OK(esp_wifi_get_country_code(&country_code_string[0]));
TEST_ASSERT(country_code_string[0] == country_code_string_01[0] && country_code_string[1] == country_code_string_01[1]);


ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit"));
TEST_ESP_OK(esp_wifi_deinit());
ESP_LOGI(TAG, EMPH_STR("event_deinit"));
TEST_ESP_OK(event_deinit());
ESP_LOGI(TAG, EMPH_STR("nvs_flash_deinit..."));
nvs_flash_deinit();

ESP_LOGI(TAG, "test passed...");
xSemaphoreGive(*sema);
vTaskSuspend(NULL);
}

TEST_CASE("wifi set country code", "[wifi_init]")
{
TaskHandle_t th = NULL;
SemaphoreHandle_t sema = xSemaphoreCreateBinary();
TEST_ASSERT_NOT_NULL(sema);
printf("Creating tasks\n");
#ifndef CONFIG_FREERTOS_UNICORE
xTaskCreatePinnedToCore(wifi_country_code_task, "wifi_country_code_task", 2048*2, &sema, 3, &th, 0);
#else
xTaskCreate(wifi_country_code_task, "wifi_country_code_task", 2048*2, &sema, 3, &th);
#endif
TEST_ASSERT_NOT_NULL(th);
xSemaphoreTake(sema, portMAX_DELAY);
vSemaphoreDelete(sema);
sema = NULL;
test_utils_task_delete(th);
}
60 changes: 46 additions & 14 deletions docs/en/api-guides/wifi.rst
Expand Up @@ -1211,7 +1211,7 @@ When to Use LR

The general conditions for using LR are:

- Both the AP and station are devices.
- Both the AP and station are Espressif devices.
- Long distance Wi-Fi connection and data transmission is required.
- Data throughput requirements are very small, such as remote device control, etc.

Expand All @@ -1233,7 +1233,7 @@ Call :cpp:func:`esp_wifi_set_country()` to set the country info. The table below
- an ASCII ‘O’ character if the regulations under which the station/AP is operating are for an outdoor environment only.
- an ASCII ‘I’ character if the regulations under which the station/AP is operating are for an indoor environment only.
- an ASCII ‘X’ character if the station/AP is operating under a noncountry entity. The first two octets of the noncountry entity is two ASCII ‘XX’ characters.
- the binary representation of the Operating Class table number currently in use. Refer to Annex E, IEEE Std 802.11-2012.
- the binary representation of the Operating Class table number currently in use. Refer to Annex E, IEEE Std 802.11-2020.

* - schan
- Start channel, it’s the minimum channel number of the regulations under which the station/AP can operate.
Expand All @@ -1242,7 +1242,33 @@ Call :cpp:func:`esp_wifi_set_country()` to set the country info. The table below
* - policy
- Country policy, this field control which country info will be used if the configured country info is conflict with the connected AP’s. More description about policy is provided in following section.

The default country info is {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}, if the Wi-Fi Mode is station/AP coexist mode, they share the same configured country info. Sometimes, the country info of AP, to which the station is connected, is different from the country info of configured. For example, the configured station has country info {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO}, but the connected AP has country info {.cc="CN", .schan=1, .nchan=13}, then country info of connected AP's is used.
The default country info is::

wifi_country_t config = {
.cc = "CN",
.schan = 1,
.nchan = 13,
.policy = WIFI_COUNTRY_POLICY_AUTO,
};

If the Wi-Fi Mode is station/AP coexist mode, they share the same configured country info. Sometimes, the country info of AP, to which the station is connected, is different from the country info of configured. For example, the configured station has country info::

wifi_country_t config = {
.cc = "JP",
.schan = 1,
.nchan = 14,
.policy = WIFI_COUNTRY_POLICY_AUTO,
};

but the connected AP has country info::

wifi_country_t config = {
.cc = "CN",
.schan = 1,
.nchan = 13,
};

then country info of connected AP's is used.

Following table depicts which country info is used in different Wi-Fi Mode and different country policy, also describe the impact to active scan.

Expand All @@ -1255,34 +1281,40 @@ Following table depicts which country info is used in different Wi-Fi Mode and d
- Description
* - Station
- WIFI_COUNTRY_POLICY_AUTO
- If the connected AP has country IE in its beacon, the country info equals to the country info in beacon, otherwise, use default country info.
- If the connected AP has country IE in its beacon, the country info equals to the country info in beacon. Otherwise, use the default country info.

For scan:

- If schan+nchan-1 >11 :

Use active scan from schan to 11 and use passive scan from 12 to schan+nchan-1.

- If schan+nchan-1 <= 11 :

Use active scan from schan to schan+nchan-1.
Use active scan from 1 to 11 and use passive scan from 12 to 14.

Always keep in mind that if an AP with hidden SSID and station is set to a passive scan channel, the passive scan will not find it. In other words, if the application hopes to find the AP with hidden SSID in every channel, the policy of country info should be configured to WIFI_COUNTRY_POLICY_MANUAL.

* - Station
- WIFI_COUNTRY_POLICY_MANUAL
- Always use the configured country info. For scan, scans channel “schan” to “schan+nchan-1” with active scan.
- Always use the configured country info.

For scan:

Use active scan from schan to schan+nchan-1.

* - AP
- WIFI_COUNTRY_POLICY_AUTO
- Always use the configured country info.

* - AP
- WIFI_COUNTRY_POLICY_MANUAL
- Always use the configured country info.

* - Station/AP-coexistence
- WIFI_COUNTRY_POLICY_AUTO
- If the station doesn’t connects to any external AP, the AP use the configured country info. If the station connects to an external AP, the AP has the same country info as the station.
- Station: Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO.
AP: If the station does not connect to any external AP, the AP uses the configured country info. If the station connects to an external AP, the AP has the same country info as the station.

* - Station/AP-coexistence
- WIFI_COUNTRY_POLICY_MANUAL
- Station: Same as station mode with policy WIFI_COUNTRY_POLICY_MANUAL.
AP: Same as AP mode with policy WIFI_COUNTRY_POLICY_MANUAL.

Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO.

Home Channel
*************************
Expand Down

0 comments on commit aefd3db

Please sign in to comment.