diff --git a/.github/workflows/sonar-scan.yml b/.github/workflows/sonar-scan.yml index 4db3f00e..7a158ef2 100644 --- a/.github/workflows/sonar-scan.yml +++ b/.github/workflows/sonar-scan.yml @@ -51,7 +51,7 @@ jobs: sudo locale-gen de_DE.UTF-8 - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v1 + uses: SonarSource/sonarcloud-github-c-cpp@v2 - name: Set IDF_PATH run: echo "IDF_PATH=$HOME/esp/esp-idf" >> $GITHUB_ENV diff --git a/src/http_server_handle_req.c b/src/http_server_handle_req.c index 9201da9b..ba88a05b 100644 --- a/src/http_server_handle_req.c +++ b/src/http_server_handle_req.c @@ -211,6 +211,7 @@ http_server_handle_req_delete( { LOG_INFO("http_server_netconn_serve: DELETE /connect.json"); dns_server_stop(); + wifi_manager_disable_wps(); if (wifi_manager_is_connected_to_ethernet()) { wifi_manager_disconnect_eth(); @@ -454,6 +455,15 @@ http_server_handle_req_post_connect_json(const http_req_body_t http_body) return http_server_resp_400(); } +static http_server_resp_t +http_server_handle_req_post_connect_wps(void) +{ + LOG_INFO("http_server_netconn_serve: POST /connect_wps"); + + wifi_manager_enable_wps(); + return http_server_resp_200_json("{}"); +} + static http_server_resp_t http_server_handle_req_post( const char* p_file_name, @@ -505,6 +515,10 @@ http_server_handle_req_post( { return http_server_handle_req_post_connect_json(http_body); } + if (0 == strcmp(p_file_name, "connect_wps")) + { + return http_server_handle_req_post_connect_wps(); + } return wifi_manager_cb_on_http_post(p_file_name, p_uri_params, http_body, p_param->flag_access_from_lan); } diff --git a/src/include/wifi_manager.h b/src/include/wifi_manager.h index 8dc59abe..f536820e 100644 --- a/src/include/wifi_manager.h +++ b/src/include/wifi_manager.h @@ -99,6 +99,18 @@ wifi_manager_stop_ap(void); void wifi_manager_start_ap(const bool flag_block_req_from_lan); +/** + * @brief Enable WPS + */ +void +wifi_manager_enable_wps(void); + +/** + * @brief Disable WPS + */ +void +wifi_manager_disable_wps(void); + /** * @brief Stop Wi-Fi Manger */ @@ -111,6 +123,12 @@ wifi_manager_stop(void); void wifi_manager_connect_async(void); +/** + * @brief requests a connection to an access point using SSID and password got by WPS. + */ +void +wifi_manager_connect_async_by_wps(void); + /** * @brief scan WiFi APs and return json */ diff --git a/src/include/wifi_manager_defs.h b/src/include/wifi_manager_defs.h index b52a1af0..b2fbcaca 100644 --- a/src/include/wifi_manager_defs.h +++ b/src/include/wifi_manager_defs.h @@ -179,8 +179,10 @@ typedef enum message_code_e EVENT_AP_STA_CONNECTED = 14, EVENT_AP_STA_DISCONNECTED = 15, EVENT_AP_STA_IP_ASSIGNED = 16, - ORDER_TASK_WATCHDOG_FEED = 17, - MESSAGE_CODE_COUNT = 18 /* important for the callback array */ + ORDER_ENABLE_WPS = 17, + ORDER_DISABLE_WPS = 18, + ORDER_TASK_WATCHDOG_FEED = 19, + MESSAGE_CODE_COUNT = 20 /* important for the callback array */ } message_code_e; typedef void (*wifi_manager_cb_ptr)(void*); @@ -207,6 +209,7 @@ typedef enum connection_request_made_by_code_e CONNECTION_REQUEST_USER = 1, CONNECTION_REQUEST_AUTO_RECONNECT = 2, CONNECTION_REQUEST_RESTORE_CONNECTION = 3, + CONNECTION_REQUEST_WPS = 4, CONNECTION_REQUEST_MAX = 0x7fffffff /*force the creation of this enum as a 32 bit int */ } connection_request_made_by_code_e; @@ -338,6 +341,8 @@ typedef struct wifiman_config_t wifiman_config_t; typedef void (*wifi_manager_callback_on_cmd_connect_eth_t)(void); typedef void (*wifi_manager_callback_on_cmd_disconnect_eth_t)(void); typedef void (*wifi_manager_callback_on_cmd_disconnect_sta_t)(void); +typedef void (*wifi_manager_callback_on_wps_started_t)(void); +typedef void (*wifi_manager_callback_on_wps_stopped_t)(void); typedef void (*wifi_manager_callback_on_ap_started_t)(void); typedef void (*wifi_manager_callback_on_ap_stopped_t)(void); typedef void (*wifi_manager_callback_on_ap_sta_connected_t)(void); @@ -355,6 +360,8 @@ typedef struct wifi_manager_callbacks_t wifi_manager_callback_on_cmd_connect_eth_t cb_on_connect_eth_cmd; wifi_manager_callback_on_cmd_disconnect_eth_t cb_on_disconnect_eth_cmd; wifi_manager_callback_on_cmd_disconnect_sta_t cb_on_disconnect_sta_cmd; + wifi_manager_callback_on_wps_started_t cb_on_wps_started; + wifi_manager_callback_on_wps_stopped_t cb_on_wps_stopped; wifi_manager_callback_on_ap_started_t cb_on_ap_started; wifi_manager_callback_on_ap_stopped_t cb_on_ap_stopped; wifi_manager_callback_on_ap_sta_connected_t cb_on_ap_sta_connected; diff --git a/src/wifi_manager.c b/src/wifi_manager.c index 494d373b..9328afc1 100644 --- a/src/wifi_manager.c +++ b/src/wifi_manager.c @@ -131,6 +131,7 @@ wifi_manager_set_config_sta(const wifiman_config_sta_t* const p_wifi_cfg_sta) /* STA - Wifi Station configuration setup */ wifi_manager_netif_configure_sta(); + LOG_INFO("%s: ### Configure WiFi mode: Station", __func__); /* by default the mode is STA because wifi_manager will not start the access point unless it has to! */ const esp_err_t err = esp_wifi_set_mode(WIFI_MODE_STA); if (ESP_OK != err) @@ -218,15 +219,27 @@ wifi_manager_update_network_connection_info( void wifi_manager_connect_async(void) { - /* in order to avoid a false positive on the front end app we need to quickly flush the ip json - * There'se a risk the front end sees an IP or a password error when in fact - * it's a remnant from a previous connection - */ wifi_manager_lock(); json_network_info_clear(); wifi_manager_unlock(); LOG_INFO("%s: wifiman_msg_send_cmd_connect_sta: CONNECTION_REQUEST_USER", __func__); - wifiman_msg_send_cmd_connect_sta(CONNECTION_REQUEST_USER); + if (!wifiman_msg_send_cmd_connect_sta(CONNECTION_REQUEST_USER)) + { + LOG_ERR("%s failed", "wifiman_msg_send_cmd_connect_sta"); + } +} + +void +wifi_manager_connect_async_by_wps(void) +{ + wifi_manager_lock(); + json_network_info_clear(); + wifi_manager_unlock(); + LOG_INFO("%s: wifiman_msg_send_cmd_connect_sta: CONNECTION_REQUEST_WPS", __func__); + if (!wifiman_msg_send_cmd_connect_sta(CONNECTION_REQUEST_WPS)) + { + LOG_ERR("%s failed", "wifiman_msg_send_cmd_connect_sta"); + } } void @@ -243,6 +256,20 @@ wifi_manager_start_ap(const bool flag_block_req_from_lan) wifiman_msg_send_cmd_start_ap(flag_block_req_from_lan); } +void +wifi_manager_enable_wps(void) +{ + LOG_INFO("%s", __func__); + wifiman_msg_send_cmd_enable_wps(); +} + +void +wifi_manager_disable_wps(void) +{ + LOG_INFO("%s", __func__); + wifiman_msg_send_cmd_disable_wps(); +} + void wifi_manager_stop(void) { diff --git a/src/wifi_manager_handle_msg.c b/src/wifi_manager_handle_msg.c index fcaced00..5f75e8d7 100644 --- a/src/wifi_manager_handle_msg.c +++ b/src/wifi_manager_handle_msg.c @@ -5,6 +5,7 @@ * @copyright Ruuvi Innovations Ltd, license BSD-3-Clause. */ +#include #include "wifi_manager_internal.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" @@ -33,6 +34,8 @@ static wifi_manager_scan_info_t g_wifi_scan_info; static uint16_t g_wifi_ap_num = MAX_AP_NUM; static wifi_ap_record_t g_wifi_ap_records[2 * MAX_AP_NUM]; +bool g_wifi_wps_enabled; + static bool wifi_scan_next(wifi_manager_scan_info_t* const p_scan_info) { @@ -126,6 +129,14 @@ wifi_handle_cmd_connect_sta(const wifiman_msg_param_t* const p_param) LOG_INFO("WIFI_MANAGER:EV_STATE: Set WIFI_MANAGER_REQUEST_RESTORE_STA_BIT"); xEventGroupSetBits(g_p_wifi_manager_event_group, WIFI_MANAGER_REQUEST_RESTORE_STA_BIT); break; + case CONNECTION_REQUEST_WPS: + LOG_INFO( + "MESSAGE: ORDER_CONNECT_STA: CONNECTION_REQUEST_WPS, event_bits=0x%04x", + (printf_uint_t)event_bits); + LOG_INFO("WIFI_MANAGER:EV_STATE: Set WIFI_MANAGER_REQUEST_STA_CONNECT_BIT"); + xEventGroupClearBits(g_p_wifi_manager_event_group, WIFI_MANAGER_REQUEST_RESTORE_STA_BIT); + xEventGroupSetBits(g_p_wifi_manager_event_group, WIFI_MANAGER_REQUEST_STA_CONNECT_BIT); + break; default: LOG_WARN( "MESSAGE: ORDER_CONNECT_STA: req_type=%d, event_bits=0x%04x", @@ -274,8 +285,11 @@ wifi_handle_ev_sta_disconnected(const wifiman_msg_param_t* const p_param) { LOG_INFO("lost connection"); update_reason_code = UPDATE_LOST_CONNECTION; - LOG_INFO("%s: activate reconnection after timeout", __func__); - wifi_manager_start_timer_reconnect_sta_after_timeout(); + if (!g_wifi_wps_enabled) + { + LOG_INFO("%s: activate reconnection after timeout", __func__); + wifi_manager_start_timer_reconnect_sta_after_timeout(); + } } const wifiman_wifi_ssid_t ssid = wifiman_config_sta_get_ssid(); wifi_manager_update_network_connection_info(update_reason_code, &ssid, NULL, NULL); @@ -304,6 +318,7 @@ wifi_handle_cmd_start_ap(const bool flag_block_req_from_lan) xEventGroupSetBits( g_p_wifi_manager_event_group, WIFI_MANAGER_AP_ACTIVE | (flag_block_req_from_lan ? WIFI_MANAGER_BLOCK_REQ_FROM_LAN_WHILE_AP_ACTIVE : 0)); + wifi_callback_on_ap_started(); } @@ -324,6 +339,43 @@ wifi_handle_cmd_stop_ap(void) wifi_callback_on_ap_stopped(); } +static void +wifi_handle_cmd_enable_wps(void) +{ + LOG_INFO("MESSAGE: ORDER_ENABLE_WPS"); + esp_err_t err = esp_wifi_wps_enable(&g_wps_config); + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_enable"); + } + err = esp_wifi_wps_start(0); + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_start"); + } + else + { + g_wifi_wps_enabled = true; + wifi_callback_on_wps_started(); + } +} + +static void +wifi_handle_cmd_disable_wps(void) +{ + LOG_INFO("MESSAGE: ORDER_DISABLE_WPS"); + const esp_err_t err = esp_wifi_wps_disable(); + g_wifi_wps_enabled = false; + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_disable"); + } + else + { + wifi_callback_on_wps_stopped(); + } +} + static void wifi_handle_ev_sta_got_ip(const wifiman_msg_param_t* const p_param) { @@ -616,6 +668,12 @@ wifi_manager_recv_and_handle_msg(void) case EVENT_AP_STA_IP_ASSIGNED: wifi_handle_ev_ap_sta_ip_assigned(); break; + case ORDER_ENABLE_WPS: + wifi_handle_cmd_enable_wps(); + break; + case ORDER_DISABLE_WPS: + wifi_handle_cmd_disable_wps(); + break; case ORDER_TASK_WATCHDOG_FEED: wifiman_msg_clear_flag_wdog_feed_active(); wifi_manager_wdt_task_reset(); diff --git a/src/wifi_manager_internal.c b/src/wifi_manager_internal.c index 66a467d8..28519232 100644 --- a/src/wifi_manager_internal.c +++ b/src/wifi_manager_internal.c @@ -5,12 +5,14 @@ * @copyright Ruuvi Innovations Ltd, license BSD-3-Clause. */ +#include #include "wifi_manager_internal.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "esp_wifi.h" #include "esp_task_wdt.h" #include "lwip/sockets.h" +#include "os_malloc.h" #include "os_mutex_recursive.h" #include "os_sema.h" #include "wifi_manager.h" @@ -24,9 +26,16 @@ #define LOG_LOCAL_LEVEL LOG_LEVEL_INFO #include "log.h" - static const char TAG[] = "wifi_manager"; +esp_wps_config_t g_wps_config = { + .wps_type = WPS_TYPE_PBC, + .factory_info = { ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "Ruuvi") + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "Ruuvi Gateway") + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_name, "Ruuvi Gateway") + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(device_name, "Ruuvi Gateway") } +}; + static wifi_manager_callbacks_t g_wifi_callbacks; static os_timer_one_shot_without_arg_t* g_p_wifi_scan_timer; @@ -134,6 +143,7 @@ wifi_manager_cb_on_http_delete( void wifi_manager_esp_wifi_configure_ap(void) { + LOG_INFO("%s: ### Configure WiFi mode: AP and Station", __func__); esp_err_t err = esp_wifi_set_mode(WIFI_MODE_APSTA); if (ESP_OK != err) { @@ -143,6 +153,28 @@ wifi_manager_esp_wifi_configure_ap(void) wifi_config_t ap_config = { .ap = wifiman_config_ap_get_config(), }; + if (0 == ap_config.ap.ssid_len) + { + LOG_INFO("Configure Wi-Fi AP: SSID: %s", ap_config.ap.ssid); + } + else + { + LOG_INFO("Configure Wi-Fi AP: SSID: %.*s", ap_config.ap.ssid_len, ap_config.ap.ssid); + } + LOG_INFO("Configure Wi-Fi AP: Auth mode: %d", ap_config.ap.authmode); + if (WIFI_AUTH_OPEN == ap_config.ap.authmode) + { + LOG_INFO("Configure Wi-Fi AP: Password: not used"); + } + else + { + LOG_INFO("Configure Wi-Fi AP: Password: %s", "********"); + LOG_DBG("Configure Wi-Fi AP: Password: %s", ap_config.ap.password); + } + LOG_INFO("Configure Wi-Fi AP: Channel: %d", ap_config.ap.channel); + LOG_INFO("Configure Wi-Fi AP: Is SSID hidden: %d", ap_config.ap.ssid_hidden); + LOG_INFO("Configure Wi-Fi AP: Max conn: %d", ap_config.ap.max_connection); + LOG_INFO("Configure Wi-Fi AP: Beacon interval: %d", ap_config.ap.beacon_interval); err = esp_wifi_set_config(WIFI_IF_AP, &ap_config); if (ESP_OK != err) { @@ -152,6 +184,7 @@ wifi_manager_esp_wifi_configure_ap(void) const wifi_settings_ap_t wifi_ap_settings = wifiman_config_ap_get_settings(); + LOG_INFO("Configure Wi-Fi AP: Bandwidth: %s", (WIFI_BW_HT20 == wifi_ap_settings.ap_bandwidth) ? "HT20" : "HT40"); err = esp_wifi_set_bandwidth(WIFI_IF_AP, wifi_ap_settings.ap_bandwidth); if (ESP_OK != err) { @@ -271,6 +304,113 @@ wifi_manager_timer_cb_reconnect(const os_timer_one_shot_cptr_without_arg_t* cons wifiman_msg_send_cmd_connect_sta(CONNECTION_REQUEST_AUTO_RECONNECT); } +static void +wifi_manager_event_handler_on_wps_er_success(wifi_event_sta_wps_er_success_t* const p_evt) +{ + typedef struct tmp_wifi_config_t + { + wifi_config_t conf; + wifiman_wifi_ssid_t ssid; + wifiman_wifi_password_t password; + } tmp_wifi_config_t; + + LOG_INFO("WIFI_EVENT_STA_WPS_ER_SUCCESS"); + + LOG_INFO("Disable WPS"); + esp_err_t err = esp_wifi_wps_disable(); + g_wifi_wps_enabled = false; + if (ESP_OK != err) + { + LOG_ERR("%s failed", "esp_wifi_wps_disable"); + } + wifi_callback_on_wps_stopped(); + + tmp_wifi_config_t* p_tmp_wifi_config = (tmp_wifi_config_t*)os_calloc(1, sizeof(*p_tmp_wifi_config)); + if (NULL == p_tmp_wifi_config) + { + LOG_ERR("Can't allocate memory"); + return; + } + p_tmp_wifi_config->ssid.ssid_buf[0] = '\0'; + p_tmp_wifi_config->password.password_buf[0] = '\0'; + + if (NULL != p_evt) + { + LOG_INFO("WIFI_EVENT_STA_WPS_ER_SUCCESS: ap_cred_cnt=%d", p_evt->ap_cred_cnt); + if (0 == p_evt->ap_cred_cnt) + { + LOG_ERR("WIFI_EVENT_STA_WPS_ER_SUCCESS: ap_cred_cnt is zero"); + os_free(p_tmp_wifi_config); + return; + } + (void)snprintf( + p_tmp_wifi_config->ssid.ssid_buf, + sizeof(p_tmp_wifi_config->ssid.ssid_buf), + "%s", + p_evt->ap_cred[0].ssid); + (void)snprintf( + p_tmp_wifi_config->password.password_buf, + sizeof(p_tmp_wifi_config->password.password_buf), + "%s", + p_evt->ap_cred[0].passphrase); + } + else + { + /* + * If only one AP credential is received from WPS, there will be no event data and + * esp_wifi_set_config() is already called by WPS modules for backward compatibility + * with legacy apps. So directly attempt connection here. + */ + err = esp_wifi_get_config(WIFI_IF_STA, &p_tmp_wifi_config->conf); + if (ESP_OK != err) + { + LOG_ERR("%s failed", "esp_wifi_get_config"); + os_free(p_tmp_wifi_config); + return; + } + (void)snprintf( + p_tmp_wifi_config->ssid.ssid_buf, + sizeof(p_tmp_wifi_config->ssid.ssid_buf), + "%s", + p_tmp_wifi_config->conf.sta.ssid); + (void)snprintf( + p_tmp_wifi_config->password.password_buf, + sizeof(p_tmp_wifi_config->password.password_buf), + "%s", + p_tmp_wifi_config->conf.sta.password); + } + + LOG_INFO("WIFI_EVENT_STA_WPS_ER_SUCCESS: SSID: %s", p_tmp_wifi_config->conf.sta.ssid); + LOG_DBG("WIFI_EVENT_STA_WPS_ER_SUCCESS: password: %s", p_tmp_wifi_config->conf.sta.password); + if ('\0' != p_tmp_wifi_config->conf.sta.ssid[0]) + { + wifiman_config_sta_set_ssid_and_password(&p_tmp_wifi_config->ssid, &p_tmp_wifi_config->password); + os_free(p_tmp_wifi_config); + + wifi_manager_connect_async_by_wps(); + } +} + +static void +wifi_manager_restart_wps(void) +{ + esp_err_t err = esp_wifi_wps_disable(); + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_disable"); + } + err = esp_wifi_wps_enable(&g_wps_config); + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_enable"); + } + err = esp_wifi_wps_start(0); + if (ESP_OK != err) + { + LOG_ERR_ESP(err, "%s failed", "esp_wifi_wps_start"); + } +} + void wifi_manager_event_handler( ATTR_UNUSED void* p_ctx, @@ -326,6 +466,17 @@ wifi_manager_event_handler( wifiman_msg_send_ev_disconnected(((const wifi_event_sta_disconnected_t*)p_event_data)->reason); break; + case WIFI_EVENT_STA_WPS_ER_SUCCESS: + wifi_manager_event_handler_on_wps_er_success(p_event_data); + break; + case WIFI_EVENT_STA_WPS_ER_FAILED: + LOG_ERR("WIFI_EVENT_STA_WPS_ER_FAILED"); + wifi_manager_restart_wps(); + break; + case WIFI_EVENT_STA_WPS_ER_TIMEOUT: + LOG_ERR("WIFI_EVENT_STA_WPS_ER_TIMEOUT"); + wifi_manager_restart_wps(); + break; default: break; } @@ -434,6 +585,7 @@ wifi_manager_init_start_wifi( /* STA - Wifi Station configuration setup */ wifi_manager_netif_configure_sta(); + LOG_INFO("%s: ### Configure WiFi mode: Station", __func__); /* by default the mode is STA because wifi_manager will not start the access point unless it has to! */ err = esp_wifi_set_mode(WIFI_MODE_STA); if (ESP_OK != err) @@ -625,6 +777,24 @@ wifi_callback_on_connect_eth_cmd(void) } } +void +wifi_callback_on_wps_started(void) +{ + if (NULL != g_wifi_callbacks.cb_on_wps_started) + { + g_wifi_callbacks.cb_on_wps_started(); + } +} + +void +wifi_callback_on_wps_stopped(void) +{ + if (NULL != g_wifi_callbacks.cb_on_wps_stopped) + { + g_wifi_callbacks.cb_on_wps_stopped(); + } +} + void wifi_callback_on_ap_started(void) { diff --git a/src/wifi_manager_internal.h b/src/wifi_manager_internal.h index d68f036b..4d1dd9b8 100644 --- a/src/wifi_manager_internal.h +++ b/src/wifi_manager_internal.h @@ -15,6 +15,7 @@ #include "os_sema.h" #include "os_timer.h" #include "http_req.h" +#include "esp_wps.h" #ifdef __cplusplus extern "C" { @@ -72,6 +73,9 @@ typedef struct wifi_manager_scan_info_t extern EventGroupHandle_t g_p_wifi_manager_event_group; +extern esp_wps_config_t g_wps_config; +extern bool g_wifi_wps_enabled; + void wifi_manager_init_mutex(void); @@ -164,6 +168,12 @@ wifi_manager_scan_timer_stop(void); void wifi_callback_on_connect_eth_cmd(void); +void +wifi_callback_on_wps_started(void); + +void +wifi_callback_on_wps_stopped(void); + void wifi_callback_on_ap_started(void); diff --git a/src/wifiman_msg.c b/src/wifiman_msg.c index 39f29537..bc93d01f 100644 --- a/src/wifiman_msg.c +++ b/src/wifiman_msg.c @@ -224,6 +224,24 @@ wifiman_msg_send_cmd_start_ap(const bool flag_block_req_from_lan) return wifiman_msg_send(ORDER_START_AP, msg_param); } +bool +wifiman_msg_send_cmd_enable_wps(void) +{ + const wifiman_msg_param_t msg_param = { + .ptr = NULL, + }; + return wifiman_msg_send(ORDER_ENABLE_WPS, msg_param); +} + +bool +wifiman_msg_send_cmd_disable_wps(void) +{ + const wifiman_msg_param_t msg_param = { + .ptr = NULL, + }; + return wifiman_msg_send(ORDER_DISABLE_WPS, msg_param); +} + bool wifiman_msg_send_cmd_stop_ap(void) { diff --git a/src/wifiman_msg.h b/src/wifiman_msg.h index 2c0288fc..524fd057 100644 --- a/src/wifiman_msg.h +++ b/src/wifiman_msg.h @@ -55,6 +55,12 @@ wifiman_msg_send_cmd_task_watchdog_feed(void); bool wifiman_msg_send_cmd_start_ap(const bool flag_block_req_from_lan); +bool +wifiman_msg_send_cmd_enable_wps(void); + +bool +wifiman_msg_send_cmd_disable_wps(void); + bool wifiman_msg_send_cmd_stop_ap(void); diff --git a/tests/test_wifiman_cfg_blob_convert/include/esp_wps.h b/tests/test_wifiman_cfg_blob_convert/include/esp_wps.h new file mode 100644 index 00000000..e172dc1b --- /dev/null +++ b/tests/test_wifiman_cfg_blob_convert/include/esp_wps.h @@ -0,0 +1,151 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. + +#ifndef __ESP_WPS_H__ +#define __ESP_WPS_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP32 WPS APIs + * + * WPS can only be used when ESP32 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +#define ESP_ERR_WIFI_REGISTRAR (ESP_ERR_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ +#define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + +typedef enum wps_type +{ + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_MAX, +} wps_type_t; + +#define WPS_MAX_MANUFACTURER_LEN 65 +#define WPS_MAX_MODEL_NUMBER_LEN 33 +#define WPS_MAX_MODEL_NAME_LEN 33 +#define WPS_MAX_DEVICE_NAME_LEN 33 + +typedef struct +{ + char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer, null-terminated string. The default manufcturer is + used if the string is empty */ + char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number, null-terminated string. The default model number is + used if the string is empty */ + char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name, null-terminated string. The default model name is used if + the string is empty */ + char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name, null-terminated string. The default device name is used + if the string is empty */ +} wps_factory_information_t; + +typedef struct +{ + wps_type_t wps_type; + wps_factory_information_t factory_info; +} esp_wps_config_t; + +#define WPS_CONFIG_INIT_DEFAULT(type) \ + { \ + .wps_type = type, .factory_info = { \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP32") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_name, "ESPRESSIF IOT") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(device_name, "ESP STATION") \ + } \ + } + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_FAIL : wps initialization fails + */ +esp_err_t +esp_wifi_wps_enable(const esp_wps_config_t* config); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + */ +esp_err_t +esp_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time (not supported in IDF v1.0) + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_FAIL : wps initialization fails + */ +esp_err_t +esp_wifi_wps_start(int timeout_ms); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPS_H__ */