From 6590cf95604fb2476223113185fc98c581de5fed Mon Sep 17 00:00:00 2001 From: "hrushikesh.bhosale" Date: Fri, 15 Nov 2024 14:22:41 +0530 Subject: [PATCH] fix(esp_wifi_prov): Send failure msg on first fail Added new sta state WIFI_PROV_ATTEMPT_FAILED, which is returned on first failure with attemps_remaining field. --- .../include/wifi_provisioning/manager.h | 16 ++++ .../include/wifi_provisioning/wifi_config.h | 17 +++- .../proto-c/wifi_config.pb-c.c | 19 +++- .../proto-c/wifi_config.pb-c.h | 6 +- .../proto-c/wifi_constants.pb-c.c | 83 +++++++++++++++++ .../proto-c/wifi_constants.pb-c.h | 36 ++++++- .../proto-c/wifi_scan.pb-c.h | 2 +- .../wifi_provisioning/proto/wifi_config.proto | 1 + .../proto/wifi_constants.proto | 4 + .../python/wifi_config_pb2.py | 28 +++--- .../python/wifi_constants_pb2.py | 20 ++-- components/wifi_provisioning/src/handlers.c | 4 + components/wifi_provisioning/src/manager.c | 93 +++++++++++++------ .../wifi_provisioning/src/wifi_config.c | 33 ++++--- .../src/wifi_provisioning_priv.h | 17 +++- .../wifi_prov_mgr/main/Kconfig.projbuild | 6 +- .../wifi_prov_mgr/main/app_main.c | 25 ++--- tools/ci/check_copyright_ignore.txt | 1 - tools/esp_prov/prov/wifi_prov.py | 11 ++- 19 files changed, 328 insertions(+), 94 deletions(-) diff --git a/components/wifi_provisioning/include/wifi_provisioning/manager.h b/components/wifi_provisioning/include/wifi_provisioning/manager.h index a3164d31a8..89d4876053 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/manager.h +++ b/components/wifi_provisioning/include/wifi_provisioning/manager.h @@ -101,6 +101,17 @@ typedef struct { .user_data = NULL \ } +/** + * @brief Structure holding the configuration related to Wi-Fi provisioning + */ +typedef struct { + /** + * Maximum number of allowed connection attempts for Wi-Fi. If value 0 + * same as legacy behavior of infinite connection attempts. + */ + uint32_t wifi_conn_attempts; +} wifi_prov_conn_cfg_t; + /** * @brief Structure for specifying the provisioning scheme to be * followed by the manager @@ -187,6 +198,11 @@ typedef struct { * specific behavior. Use WIFI_PROV_EVENT_HANDLER_NONE when not used. */ wifi_prov_event_handler_t app_event_handler; + + /** + * This config holds the Wi-Fi provisioning related configurations. + */ + wifi_prov_conn_cfg_t wifi_prov_conn_cfg; } wifi_prov_mgr_config_t; /** diff --git a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h index 6c9d11f5ab..cd26ebef2b 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h +++ b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,8 @@ extern "C" { typedef enum { WIFI_PROV_STA_CONNECTING, WIFI_PROV_STA_CONNECTED, - WIFI_PROV_STA_DISCONNECTED + WIFI_PROV_STA_DISCONNECTED, + WIFI_PROV_STA_CONN_ATTEMPT_FAILED } wifi_prov_sta_state_t; /** @@ -46,6 +47,13 @@ typedef struct { uint8_t auth_mode; /*!< Authorization mode of the AP */ } wifi_prov_sta_conn_info_t; +/** + * @brief WiFi STA connecting status information + */ +typedef struct { + uint32_t attempts_remaining; /*!< Number of Wi-Fi connection attempts remaining */ +} wifi_prov_sta_connecting_info_t; + /** * @brief WiFi status data to be sent in response to `get_status` request from master */ @@ -61,6 +69,11 @@ typedef struct { * Connection information (valid only when `wifi_state` is `WIFI_STATION_CONNECTED`) */ wifi_prov_sta_conn_info_t conn_info; + + /** + * Connecting information (valid only when `wifi_state` is `WIFI_STATION_CONNECTING`) + */ + wifi_prov_sta_connecting_info_t connecting_info; }; } wifi_prov_config_get_data_t; diff --git a/components/wifi_provisioning/proto-c/wifi_config.pb-c.c b/components/wifi_provisioning/proto-c/wifi_config.pb-c.c index 0be6dcd867..d451dbf626 100644 --- a/components/wifi_provisioning/proto-c/wifi_config.pb-c.c +++ b/components/wifi_provisioning/proto-c/wifi_config.pb-c.c @@ -340,7 +340,7 @@ const ProtobufCMessageDescriptor cmd_get_status__descriptor = (ProtobufCMessageInit) cmd_get_status__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor resp_get_status__field_descriptors[4] = +static const ProtobufCFieldDescriptor resp_get_status__field_descriptors[5] = { { "status", @@ -390,8 +390,21 @@ static const ProtobufCFieldDescriptor resp_get_status__field_descriptors[4] = 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "attempt_failed", + 12, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(RespGetStatus, state_case), + offsetof(RespGetStatus, attempt_failed), + &wifi_attempt_failed__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned resp_get_status__field_indices_by_name[] = { + 4, /* field[4] = attempt_failed */ 3, /* field[3] = connected */ 2, /* field[2] = fail_reason */ 1, /* field[1] = sta_state */ @@ -401,7 +414,7 @@ static const ProtobufCIntRange resp_get_status__number_ranges[2 + 1] = { { 1, 0 }, { 10, 2 }, - { 0, 4 } + { 0, 5 } }; const ProtobufCMessageDescriptor resp_get_status__descriptor = { @@ -411,7 +424,7 @@ const ProtobufCMessageDescriptor resp_get_status__descriptor = "RespGetStatus", "", sizeof(RespGetStatus), - 4, + 5, resp_get_status__field_descriptors, resp_get_status__field_indices_by_name, 2, resp_get_status__number_ranges, diff --git a/components/wifi_provisioning/proto-c/wifi_config.pb-c.h b/components/wifi_provisioning/proto-c/wifi_config.pb-c.h index 3e293f23be..d0247458ab 100644 --- a/components/wifi_provisioning/proto-c/wifi_config.pb-c.h +++ b/components/wifi_provisioning/proto-c/wifi_config.pb-c.h @@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -52,7 +52,8 @@ struct CmdGetStatus typedef enum { RESP_GET_STATUS__STATE__NOT_SET = 0, RESP_GET_STATUS__STATE_FAIL_REASON = 10, - RESP_GET_STATUS__STATE_CONNECTED = 11 + RESP_GET_STATUS__STATE_CONNECTED = 11, + RESP_GET_STATUS__STATE_ATTEMPT_FAILED = 12 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(RESP_GET_STATUS__STATE__CASE) } RespGetStatus__StateCase; @@ -65,6 +66,7 @@ struct RespGetStatus union { WifiConnectFailedReason fail_reason; WifiConnectedState *connected; + WifiAttemptFailed *attempt_failed; }; }; #define RESP_GET_STATUS__INIT \ diff --git a/components/wifi_provisioning/proto-c/wifi_constants.pb-c.c b/components/wifi_provisioning/proto-c/wifi_constants.pb-c.c index aec0f41820..1cdd944f9e 100644 --- a/components/wifi_provisioning/proto-c/wifi_constants.pb-c.c +++ b/components/wifi_provisioning/proto-c/wifi_constants.pb-c.c @@ -7,6 +7,51 @@ #endif #include "wifi_constants.pb-c.h" +void wifi_attempt_failed__init + (WifiAttemptFailed *message) +{ + static const WifiAttemptFailed init_value = WIFI_ATTEMPT_FAILED__INIT; + *message = init_value; +} +size_t wifi_attempt_failed__get_packed_size + (const WifiAttemptFailed *message) +{ + assert(message->base.descriptor == &wifi_attempt_failed__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t wifi_attempt_failed__pack + (const WifiAttemptFailed *message, + uint8_t *out) +{ + assert(message->base.descriptor == &wifi_attempt_failed__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t wifi_attempt_failed__pack_to_buffer + (const WifiAttemptFailed *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &wifi_attempt_failed__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +WifiAttemptFailed * + wifi_attempt_failed__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (WifiAttemptFailed *) + protobuf_c_message_unpack (&wifi_attempt_failed__descriptor, + allocator, len, data); +} +void wifi_attempt_failed__free_unpacked + (WifiAttemptFailed *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &wifi_attempt_failed__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} void wifi_connected_state__init (WifiConnectedState *message) { @@ -52,6 +97,44 @@ void wifi_connected_state__free_unpacked assert(message->base.descriptor == &wifi_connected_state__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } +static const ProtobufCFieldDescriptor wifi_attempt_failed__field_descriptors[1] = +{ + { + "attempts_remaining", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, + 0, /* quantifier_offset */ + offsetof(WifiAttemptFailed, attempts_remaining), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned wifi_attempt_failed__field_indices_by_name[] = { + 0, /* field[0] = attempts_remaining */ +}; +static const ProtobufCIntRange wifi_attempt_failed__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor wifi_attempt_failed__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "WifiAttemptFailed", + "WifiAttemptFailed", + "WifiAttemptFailed", + "", + sizeof(WifiAttemptFailed), + 1, + wifi_attempt_failed__field_descriptors, + wifi_attempt_failed__field_indices_by_name, + 1, wifi_attempt_failed__number_ranges, + (ProtobufCMessageInit) wifi_attempt_failed__init, + NULL,NULL,NULL /* reserved[123] */ +}; static const ProtobufCFieldDescriptor wifi_connected_state__field_descriptors[5] = { { diff --git a/components/wifi_provisioning/proto-c/wifi_constants.pb-c.h b/components/wifi_provisioning/proto-c/wifi_constants.pb-c.h index abebe2956b..b2772df13f 100644 --- a/components/wifi_provisioning/proto-c/wifi_constants.pb-c.h +++ b/components/wifi_provisioning/proto-c/wifi_constants.pb-c.h @@ -10,11 +10,12 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif +typedef struct WifiAttemptFailed WifiAttemptFailed; typedef struct WifiConnectedState WifiConnectedState; @@ -46,6 +47,16 @@ typedef enum _WifiAuthMode { /* --- messages --- */ +struct WifiAttemptFailed +{ + ProtobufCMessage base; + uint32_t attempts_remaining; +}; +#define WIFI_ATTEMPT_FAILED__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&wifi_attempt_failed__descriptor) \ + , 0 } + + struct WifiConnectedState { ProtobufCMessage base; @@ -60,6 +71,25 @@ struct WifiConnectedState , (char *)protobuf_c_empty_string, WIFI_AUTH_MODE__Open, {0,NULL}, {0,NULL}, 0 } +/* WifiAttemptFailed methods */ +void wifi_attempt_failed__init + (WifiAttemptFailed *message); +size_t wifi_attempt_failed__get_packed_size + (const WifiAttemptFailed *message); +size_t wifi_attempt_failed__pack + (const WifiAttemptFailed *message, + uint8_t *out); +size_t wifi_attempt_failed__pack_to_buffer + (const WifiAttemptFailed *message, + ProtobufCBuffer *buffer); +WifiAttemptFailed * + wifi_attempt_failed__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void wifi_attempt_failed__free_unpacked + (WifiAttemptFailed *message, + ProtobufCAllocator *allocator); /* WifiConnectedState methods */ void wifi_connected_state__init (WifiConnectedState *message); @@ -81,6 +111,9 @@ void wifi_connected_state__free_unpacked ProtobufCAllocator *allocator); /* --- per-message closures --- */ +typedef void (*WifiAttemptFailed_Closure) + (const WifiAttemptFailed *message, + void *closure_data); typedef void (*WifiConnectedState_Closure) (const WifiConnectedState *message, void *closure_data); @@ -93,6 +126,7 @@ typedef void (*WifiConnectedState_Closure) extern const ProtobufCEnumDescriptor wifi_station_state__descriptor; extern const ProtobufCEnumDescriptor wifi_connect_failed_reason__descriptor; extern const ProtobufCEnumDescriptor wifi_auth_mode__descriptor; +extern const ProtobufCMessageDescriptor wifi_attempt_failed__descriptor; extern const ProtobufCMessageDescriptor wifi_connected_state__descriptor; PROTOBUF_C__END_DECLS diff --git a/components/wifi_provisioning/proto-c/wifi_scan.pb-c.h b/components/wifi_provisioning/proto-c/wifi_scan.pb-c.h index dc3975590d..bab84159de 100644 --- a/components/wifi_provisioning/proto-c/wifi_scan.pb-c.h +++ b/components/wifi_provisioning/proto-c/wifi_scan.pb-c.h @@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif diff --git a/components/wifi_provisioning/proto/wifi_config.proto b/components/wifi_provisioning/proto/wifi_config.proto index e273dc8e55..9ff79bbb6e 100644 --- a/components/wifi_provisioning/proto/wifi_config.proto +++ b/components/wifi_provisioning/proto/wifi_config.proto @@ -13,6 +13,7 @@ message RespGetStatus { oneof state { WifiConnectFailedReason fail_reason = 10; WifiConnectedState connected = 11; + WifiAttemptFailed attempt_failed = 12; } } diff --git a/components/wifi_provisioning/proto/wifi_constants.proto b/components/wifi_provisioning/proto/wifi_constants.proto index 8134b2ed70..76c3736163 100644 --- a/components/wifi_provisioning/proto/wifi_constants.proto +++ b/components/wifi_provisioning/proto/wifi_constants.proto @@ -12,6 +12,10 @@ enum WifiConnectFailedReason { NetworkNotFound = 1; } +message WifiAttemptFailed { + uint32 attempts_remaining = 1; +} + enum WifiAuthMode { Open = 0; WEP = 1; diff --git a/components/wifi_provisioning/python/wifi_config_pb2.py b/components/wifi_provisioning/python/wifi_config_pb2.py index 3d48ecfb7e..f24f9fc9cb 100644 --- a/components/wifi_provisioning/python/wifi_config_pb2.py +++ b/components/wifi_provisioning/python/wifi_config_pb2.py @@ -15,27 +15,27 @@ import constants_pb2 as constants__pb2 import wifi_constants_pb2 as wifi__constants__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11wifi_config.proto\x1a\x0f\x63onstants.proto\x1a\x14wifi_constants.proto\"\x0e\n\x0c\x43mdGetStatus\"\xb2\x01\n\rRespGetStatus\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12$\n\tsta_state\x18\x02 \x01(\x0e\x32\x11.WifiStationState\x12/\n\x0b\x66\x61il_reason\x18\n \x01(\x0e\x32\x18.WifiConnectFailedReasonH\x00\x12(\n\tconnected\x18\x0b \x01(\x0b\x32\x13.WifiConnectedStateH\x00\x42\x07\n\x05state\"P\n\x0c\x43mdSetConfig\x12\x0c\n\x04ssid\x18\x01 \x01(\x0c\x12\x12\n\npassphrase\x18\x02 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x03 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\x05\"(\n\rRespSetConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\x10\n\x0e\x43mdApplyConfig\"*\n\x0fRespApplyConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\xc3\x02\n\x11WiFiConfigPayload\x12\x1f\n\x03msg\x18\x01 \x01(\x0e\x32\x12.WiFiConfigMsgType\x12\'\n\x0e\x63md_get_status\x18\n \x01(\x0b\x32\r.CmdGetStatusH\x00\x12)\n\x0fresp_get_status\x18\x0b \x01(\x0b\x32\x0e.RespGetStatusH\x00\x12\'\n\x0e\x63md_set_config\x18\x0c \x01(\x0b\x32\r.CmdSetConfigH\x00\x12)\n\x0fresp_set_config\x18\r \x01(\x0b\x32\x0e.RespSetConfigH\x00\x12+\n\x10\x63md_apply_config\x18\x0e \x01(\x0b\x32\x0f.CmdApplyConfigH\x00\x12-\n\x11resp_apply_config\x18\x0f \x01(\x0b\x32\x10.RespApplyConfigH\x00\x42\t\n\x07payload*\x9e\x01\n\x11WiFiConfigMsgType\x12\x14\n\x10TypeCmdGetStatus\x10\x00\x12\x15\n\x11TypeRespGetStatus\x10\x01\x12\x14\n\x10TypeCmdSetConfig\x10\x02\x12\x15\n\x11TypeRespSetConfig\x10\x03\x12\x16\n\x12TypeCmdApplyConfig\x10\x04\x12\x17\n\x13TypeRespApplyConfig\x10\x05\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11wifi_config.proto\x1a\x0f\x63onstants.proto\x1a\x14wifi_constants.proto\"\x0e\n\x0c\x43mdGetStatus\"\xe0\x01\n\rRespGetStatus\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12$\n\tsta_state\x18\x02 \x01(\x0e\x32\x11.WifiStationState\x12/\n\x0b\x66\x61il_reason\x18\n \x01(\x0e\x32\x18.WifiConnectFailedReasonH\x00\x12(\n\tconnected\x18\x0b \x01(\x0b\x32\x13.WifiConnectedStateH\x00\x12,\n\x0e\x61ttempt_failed\x18\x0c \x01(\x0b\x32\x12.WifiAttemptFailedH\x00\x42\x07\n\x05state\"P\n\x0c\x43mdSetConfig\x12\x0c\n\x04ssid\x18\x01 \x01(\x0c\x12\x12\n\npassphrase\x18\x02 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x03 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\x05\"(\n\rRespSetConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\x10\n\x0e\x43mdApplyConfig\"*\n\x0fRespApplyConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\xc3\x02\n\x11WiFiConfigPayload\x12\x1f\n\x03msg\x18\x01 \x01(\x0e\x32\x12.WiFiConfigMsgType\x12\'\n\x0e\x63md_get_status\x18\n \x01(\x0b\x32\r.CmdGetStatusH\x00\x12)\n\x0fresp_get_status\x18\x0b \x01(\x0b\x32\x0e.RespGetStatusH\x00\x12\'\n\x0e\x63md_set_config\x18\x0c \x01(\x0b\x32\r.CmdSetConfigH\x00\x12)\n\x0fresp_set_config\x18\r \x01(\x0b\x32\x0e.RespSetConfigH\x00\x12+\n\x10\x63md_apply_config\x18\x0e \x01(\x0b\x32\x0f.CmdApplyConfigH\x00\x12-\n\x11resp_apply_config\x18\x0f \x01(\x0b\x32\x10.RespApplyConfigH\x00\x42\t\n\x07payload*\x9e\x01\n\x11WiFiConfigMsgType\x12\x14\n\x10TypeCmdGetStatus\x10\x00\x12\x15\n\x11TypeRespGetStatus\x10\x01\x12\x14\n\x10TypeCmdSetConfig\x10\x02\x12\x15\n\x11TypeRespSetConfig\x10\x03\x12\x16\n\x12TypeCmdApplyConfig\x10\x04\x12\x17\n\x13TypeRespApplyConfig\x10\x05\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_config_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _WIFICONFIGMSGTYPE._serialized_start=770 - _WIFICONFIGMSGTYPE._serialized_end=928 + _WIFICONFIGMSGTYPE._serialized_start=816 + _WIFICONFIGMSGTYPE._serialized_end=974 _CMDGETSTATUS._serialized_start=60 _CMDGETSTATUS._serialized_end=74 _RESPGETSTATUS._serialized_start=77 - _RESPGETSTATUS._serialized_end=255 - _CMDSETCONFIG._serialized_start=257 - _CMDSETCONFIG._serialized_end=337 - _RESPSETCONFIG._serialized_start=339 - _RESPSETCONFIG._serialized_end=379 - _CMDAPPLYCONFIG._serialized_start=381 - _CMDAPPLYCONFIG._serialized_end=397 - _RESPAPPLYCONFIG._serialized_start=399 - _RESPAPPLYCONFIG._serialized_end=441 - _WIFICONFIGPAYLOAD._serialized_start=444 - _WIFICONFIGPAYLOAD._serialized_end=767 + _RESPGETSTATUS._serialized_end=301 + _CMDSETCONFIG._serialized_start=303 + _CMDSETCONFIG._serialized_end=383 + _RESPSETCONFIG._serialized_start=385 + _RESPSETCONFIG._serialized_end=425 + _CMDAPPLYCONFIG._serialized_start=427 + _CMDAPPLYCONFIG._serialized_end=443 + _RESPAPPLYCONFIG._serialized_start=445 + _RESPAPPLYCONFIG._serialized_end=487 + _WIFICONFIGPAYLOAD._serialized_start=490 + _WIFICONFIGPAYLOAD._serialized_end=813 # @@protoc_insertion_point(module_scope) diff --git a/components/wifi_provisioning/python/wifi_constants_pb2.py b/components/wifi_provisioning/python/wifi_constants_pb2.py index 3165650d94..018dbd1ff0 100644 --- a/components/wifi_provisioning/python/wifi_constants_pb2.py +++ b/components/wifi_provisioning/python/wifi_constants_pb2.py @@ -13,19 +13,21 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14wifi_constants.proto\"v\n\x12WifiConnectedState\x12\x10\n\x08ip4_addr\x18\x01 \x01(\t\x12 \n\tauth_mode\x18\x02 \x01(\x0e\x32\r.WifiAuthMode\x12\x0c\n\x04ssid\x18\x03 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x04 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x05 \x01(\x05*Y\n\x10WifiStationState\x12\r\n\tConnected\x10\x00\x12\x0e\n\nConnecting\x10\x01\x12\x10\n\x0c\x44isconnected\x10\x02\x12\x14\n\x10\x43onnectionFailed\x10\x03*=\n\x17WifiConnectFailedReason\x12\r\n\tAuthError\x10\x00\x12\x13\n\x0fNetworkNotFound\x10\x01*\x84\x01\n\x0cWifiAuthMode\x12\x08\n\x04Open\x10\x00\x12\x07\n\x03WEP\x10\x01\x12\x0b\n\x07WPA_PSK\x10\x02\x12\x0c\n\x08WPA2_PSK\x10\x03\x12\x10\n\x0cWPA_WPA2_PSK\x10\x04\x12\x13\n\x0fWPA2_ENTERPRISE\x10\x05\x12\x0c\n\x08WPA3_PSK\x10\x06\x12\x11\n\rWPA2_WPA3_PSK\x10\x07\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14wifi_constants.proto\"/\n\x11WifiAttemptFailed\x12\x1a\n\x12\x61ttempts_remaining\x18\x01 \x01(\r\"v\n\x12WifiConnectedState\x12\x10\n\x08ip4_addr\x18\x01 \x01(\t\x12 \n\tauth_mode\x18\x02 \x01(\x0e\x32\r.WifiAuthMode\x12\x0c\n\x04ssid\x18\x03 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x04 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x05 \x01(\x05*Y\n\x10WifiStationState\x12\r\n\tConnected\x10\x00\x12\x0e\n\nConnecting\x10\x01\x12\x10\n\x0c\x44isconnected\x10\x02\x12\x14\n\x10\x43onnectionFailed\x10\x03*=\n\x17WifiConnectFailedReason\x12\r\n\tAuthError\x10\x00\x12\x13\n\x0fNetworkNotFound\x10\x01*\x84\x01\n\x0cWifiAuthMode\x12\x08\n\x04Open\x10\x00\x12\x07\n\x03WEP\x10\x01\x12\x0b\n\x07WPA_PSK\x10\x02\x12\x0c\n\x08WPA2_PSK\x10\x03\x12\x10\n\x0cWPA_WPA2_PSK\x10\x04\x12\x13\n\x0fWPA2_ENTERPRISE\x10\x05\x12\x0c\n\x08WPA3_PSK\x10\x06\x12\x11\n\rWPA2_WPA3_PSK\x10\x07\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_constants_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _WIFISTATIONSTATE._serialized_start=144 - _WIFISTATIONSTATE._serialized_end=233 - _WIFICONNECTFAILEDREASON._serialized_start=235 - _WIFICONNECTFAILEDREASON._serialized_end=296 - _WIFIAUTHMODE._serialized_start=299 - _WIFIAUTHMODE._serialized_end=431 - _WIFICONNECTEDSTATE._serialized_start=24 - _WIFICONNECTEDSTATE._serialized_end=142 + _WIFISTATIONSTATE._serialized_start=193 + _WIFISTATIONSTATE._serialized_end=282 + _WIFICONNECTFAILEDREASON._serialized_start=284 + _WIFICONNECTFAILEDREASON._serialized_end=345 + _WIFIAUTHMODE._serialized_start=348 + _WIFIAUTHMODE._serialized_end=480 + _WIFIATTEMPTFAILED._serialized_start=24 + _WIFIATTEMPTFAILED._serialized_end=71 + _WIFICONNECTEDSTATE._serialized_start=73 + _WIFICONNECTEDSTATE._serialized_end=191 # @@protoc_insertion_point(module_scope) diff --git a/components/wifi_provisioning/src/handlers.c b/components/wifi_provisioning/src/handlers.c index a3baaf243e..e6d8ae5606 100644 --- a/components/wifi_provisioning/src/handlers.c +++ b/components/wifi_provisioning/src/handlers.c @@ -78,6 +78,10 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi /* If disconnected, convey reason */ wifi_prov_mgr_get_wifi_disconnect_reason(&resp_data->fail_reason); } else { + if (wifi_prov_mgr_get_remaining_conn_attempts(&resp_data->connecting_info.attempts_remaining) != ESP_OK) { + ESP_LOGW(TAG, "Wi-Fi provisioning manager not running"); + return ESP_ERR_INVALID_STATE; + } ESP_LOGD(TAG, "Got state : connecting"); } return ESP_OK; diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index fd8b2e2edc..2714f3e894 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -144,6 +144,9 @@ struct wifi_prov_mgr_ctx { wifi_ap_record_t *ap_list[14]; wifi_ap_record_t *ap_list_sorted[MAX_SCAN_RESULTS]; wifi_scan_config_t scan_cfg; + + /* Total number of attempts done for connecting to Wi-Fi */ + uint32_t connection_attempts_completed; }; /* Mutex to lock/unlock access to provisioning singleton @@ -952,31 +955,22 @@ static void wifi_prov_mgr_event_handler_internal( /* Execute user registered callback handler */ execute_event_cb(WIFI_PROV_CRED_SUCCESS, NULL, 0); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGE(TAG, "STA Disconnected"); - /* Station couldn't connect to configured host SSID */ - prov_ctx->wifi_state = WIFI_PROV_STA_DISCONNECTED; - - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); - - /* Set code corresponding to the reason for disconnection */ - switch (disconnected->reason) { - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - case WIFI_REASON_MIC_FAILURE: - ESP_LOGE(TAG, "STA Auth Error"); - prov_ctx->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGE(TAG, "STA AP Not found"); - prov_ctx->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; - break; - default: - /* If none of the expected reasons, - * retry connecting to host SSID */ - prov_ctx->wifi_state = WIFI_PROV_STA_CONNECTING; - esp_wifi_connect(); + if (prov_ctx->mgr_config.wifi_prov_conn_cfg.wifi_conn_attempts > 0) { + prov_ctx->connection_attempts_completed += 1; /* Increasing attempt after every failure */ + if (prov_ctx->connection_attempts_completed < prov_ctx->mgr_config.wifi_prov_conn_cfg.wifi_conn_attempts) { + /* Set WiFi state to WIFI_PROV_STA_CONN_ATTEMPT_FAILED only if the user configure wifi_conn_attempts and connection_attempts_completed + * are less than wifi_conn_attempts. + */ + prov_ctx->wifi_state = WIFI_PROV_STA_CONN_ATTEMPT_FAILED; + esp_wifi_connect(); + } else { + /* Station couldn't connect to configured host SSID */ + ESP_LOGE(TAG, "STA Disconnected"); + prov_ctx->wifi_state = WIFI_PROV_STA_DISCONNECTED; + } + } else { + ESP_LOGE(TAG, "STA Disconnected"); + prov_ctx->wifi_state = WIFI_PROV_STA_DISCONNECTED; } /* In case of disconnection, update state of service and @@ -984,8 +978,34 @@ static void wifi_prov_mgr_event_handler_internal( if (prov_ctx->wifi_state == WIFI_PROV_STA_DISCONNECTED) { prov_ctx->prov_state = WIFI_PROV_STATE_FAIL; wifi_prov_sta_fail_reason_t reason = prov_ctx->wifi_disconnect_reason; - /* Execute user registered callback handler */ - execute_event_cb(WIFI_PROV_CRED_FAIL, (void *)&reason, sizeof(reason)); + wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; + ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); + + /* Set code corresponding to the reason for disconnection */ + switch (disconnected->reason) { + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: + case WIFI_REASON_AUTH_FAIL: + case WIFI_REASON_HANDSHAKE_TIMEOUT: + case WIFI_REASON_MIC_FAILURE: + ESP_LOGE(TAG, "STA Auth Error"); + prov_ctx->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; + break; + case WIFI_REASON_NO_AP_FOUND: + ESP_LOGE(TAG, "STA AP Not found"); + prov_ctx->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; + break; + default: + if (prov_ctx->mgr_config.wifi_prov_conn_cfg.wifi_conn_attempts == 0) { + /* If none of the expected reasons, + * retry connecting to host SSID */ + prov_ctx->wifi_state = WIFI_PROV_STA_CONNECTING; + esp_wifi_connect(); + } + } + if (prov_ctx->wifi_state == WIFI_PROV_STA_DISCONNECTED) { + /* Execute user registered callback handler */ + execute_event_cb(WIFI_PROV_CRED_FAIL, (void *)&reason, sizeof(reason)); + } } } else if (event_base == WIFI_PROV_MGR_PVT_EVENT && event_id == WIFI_PROV_MGR_STOP) { prov_stop_and_notify(true); @@ -1154,6 +1174,25 @@ esp_err_t wifi_prov_mgr_get_wifi_state(wifi_prov_sta_state_t *state) } *state = prov_ctx->wifi_state; + + RELEASE_LOCK(prov_ctx_lock); + return ESP_OK; +} + +esp_err_t wifi_prov_mgr_get_remaining_conn_attempts(uint32_t *attempts_remaining) +{ + if (!prov_ctx_lock) { + ESP_LOGE(TAG, "Provisioning manager not initialized"); + return ESP_ERR_INVALID_STATE; + } + + ACQUIRE_LOCK(prov_ctx_lock); + if (prov_ctx == NULL || attempts_remaining == NULL) { + RELEASE_LOCK(prov_ctx_lock); + return ESP_FAIL; + } + + *attempts_remaining = prov_ctx->mgr_config.wifi_prov_conn_cfg.wifi_conn_attempts - prov_ctx->connection_attempts_completed; RELEASE_LOCK(prov_ctx_lock); return ESP_OK; } diff --git a/components/wifi_provisioning/src/wifi_config.c b/components/wifi_provisioning/src/wifi_config.c index 1075a31808..b97ef2a552 100644 --- a/components/wifi_provisioning/src/wifi_config.c +++ b/components/wifi_provisioning/src/wifi_config.c @@ -1,16 +1,8 @@ -// Copyright 2018 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. +/* + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -124,6 +116,19 @@ static esp_err_t cmd_get_status_handler(WiFiConfigPayload *req, } else if (resp_data.fail_reason == WIFI_PROV_STA_AP_NOT_FOUND) { resp_payload->fail_reason = WIFI_CONNECT_FAILED_REASON__NetworkNotFound; } + } else if (resp_data.wifi_state == WIFI_PROV_STA_CONN_ATTEMPT_FAILED) { + resp_payload->sta_state = WIFI_STATION_STATE__Connecting; + resp_payload->state_case = RESP_GET_STATUS__STATE_ATTEMPT_FAILED; + WifiAttemptFailed *attempt_failed = (WifiAttemptFailed *)( + calloc(1, sizeof(WifiAttemptFailed))); + if (!attempt_failed) { + free(resp_payload); + ESP_LOGE(TAG, "Error allocating memory"); + return ESP_ERR_NO_MEM; + } + wifi_attempt_failed__init(attempt_failed); + attempt_failed->attempts_remaining = resp_data.connecting_info.attempts_remaining; + resp_payload->attempt_failed = attempt_failed; } resp_payload->status = STATUS__Success; } @@ -169,7 +174,7 @@ static esp_err_t cmd_set_config_handler(WiFiConfigPayload *req, } else { /* The received SSID and Passphrase are not NULL terminated so * we memcpy over zeroed out arrays. Above length checks ensure - * that there is atleast 1 extra byte for null termination */ + * that there is at least 1 extra byte for null termination */ memcpy(req_data.ssid, req->cmd_set_config->ssid.data, req->cmd_set_config->ssid.len); memcpy(req_data.password, req->cmd_set_config->passphrase.data, diff --git a/components/wifi_provisioning/src/wifi_provisioning_priv.h b/components/wifi_provisioning/src/wifi_provisioning_priv.h index a58d2589d9..3deff26c94 100644 --- a/components/wifi_provisioning/src/wifi_provisioning_priv.h +++ b/components/wifi_provisioning/src/wifi_provisioning_priv.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,3 +104,18 @@ esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr); * - ESP_ERR_INVALID_ARG : null argument */ esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr); + +/** + * @brief Retrieve the remaining number of Wi-Fi connection attempts + * + * This function provides the number of connection attempts left for + * the Wi-Fi provisioning manager before reaching the maximum retry limit. + * + * @param[out] attempts_remaining Pointer to store the remaining connection attempts + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Null pointer provided for attempts_remaining + * - ESP_FAIL: Failed to retrieve the remaining attempts + */ +esp_err_t wifi_prov_mgr_get_remaining_conn_attempts(uint32_t *attempts_remaining); diff --git a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild index a0aa2888d0..8df82bd0ec 100644 --- a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild +++ b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild @@ -81,13 +81,13 @@ menu "Example Configuration" Enable resetting provisioned credentials and state machine after session failure. This will restart the provisioning service after retries are exhausted. - config EXAMPLE_PROV_MGR_MAX_RETRY_CNT + config EXAMPLE_PROV_MGR_CONNECTION_CNT int default 5 - prompt "Max retries before resetting provisioning state machine" + prompt "Max connection attempts before resetting provisioning state machine" depends on EXAMPLE_RESET_PROV_MGR_ON_FAILURE help - Set the Maximum retry to avoid reconnecting to an inexistent AP or if credentials + Set the total number of connection attempts to avoid reconnecting to an inexistent AP or if credentials are misconfigured. Provisioned credentials are erased and internal state machine is reset after this threshold is reached. diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index b53024f24d..56318d1210 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -111,9 +111,6 @@ static EventGroupHandle_t wifi_event_group; static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { -#ifdef CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE - static int retries; -#endif if (event_base == WIFI_PROV_EVENT) { switch (event_id) { case WIFI_PROV_START: @@ -134,20 +131,19 @@ static void event_handler(void* arg, esp_event_base_t event_base, (*reason == WIFI_PROV_STA_AUTH_ERROR) ? "Wi-Fi station authentication failed" : "Wi-Fi access-point not found"); #ifdef CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE - retries++; - if (retries >= CONFIG_EXAMPLE_PROV_MGR_MAX_RETRY_CNT) { - ESP_LOGI(TAG, "Failed to connect with provisioned AP, resetting provisioned credentials"); - wifi_prov_mgr_reset_sm_state_on_failure(); - retries = 0; - } + /* Reset the state machine on provisioning failure. + * This is enabled by the CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE configuration. + * It allows the provisioning manager to retry the provisioning process + * based on the number of attempts specified in wifi_conn_attempts. After attempting + * the maximum number of retries, the provisioning manager will reset the state machine + * and the provisioning process will be terminated. + */ + wifi_prov_mgr_reset_sm_state_on_failure(); #endif break; } case WIFI_PROV_CRED_SUCCESS: ESP_LOGI(TAG, "Provisioning successful"); -#ifdef CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE - retries = 0; -#endif break; case WIFI_PROV_END: /* De-initialize manager once provisioning is finished */ @@ -346,6 +342,11 @@ void app_main(void) /* Configuration for the provisioning manager */ wifi_prov_mgr_config_t config = { +#ifdef CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE + .wifi_prov_conn_cfg = { + .wifi_conn_attempts = CONFIG_EXAMPLE_PROV_MGR_CONNECTION_CNT, + }, +#endif /* What is the Provisioning Scheme that we want ? * wifi_prov_scheme_softap or wifi_prov_scheme_ble */ #ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 54b8ab8fbb..42883f25a2 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -545,7 +545,6 @@ components/wifi_provisioning/python/wifi_config_pb2.py components/wifi_provisioning/python/wifi_constants_pb2.py components/wifi_provisioning/python/wifi_scan_pb2.py components/wifi_provisioning/src/scheme_console.c -components/wifi_provisioning/src/wifi_config.c components/wifi_provisioning/src/wifi_scan.c components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h components/wpa_supplicant/include/utils/wpa_debug.h diff --git a/tools/esp_prov/prov/wifi_prov.py b/tools/esp_prov/prov/wifi_prov.py index a7e2c75a29..8f32af19d1 100644 --- a/tools/esp_prov/prov/wifi_prov.py +++ b/tools/esp_prov/prov/wifi_prov.py @@ -1,16 +1,14 @@ -# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # - # APIs for interpreting and creating protobuf packets for Wi-Fi provisioning - import proto from utils import str_to_bytes def print_verbose(security_ctx, data): if (security_ctx.verbose): - print(f'\x1b[32;20m++++ {data} ++++\x1b[0m') + print(f'++++ {data} ++++') def config_get_status_request(security_ctx): @@ -37,6 +35,11 @@ def config_get_status_response(security_ctx, response_data): return 'connected' elif cmd_resp1.resp_get_status.sta_state == 1: print('++++ WiFi state: Connecting... ++++') + if cmd_resp1.resp_get_status.HasField('attempt_failed'): + if cmd_resp1.resp_get_status.attempt_failed.attempts_remaining: + print(cmd_resp1.resp_get_status) + else: + print('attempt_failed {\n attempts_remaining: 0\n}') return 'connecting' elif cmd_resp1.resp_get_status.sta_state == 2: print('---- WiFi state: Disconnected ----')