diff --git a/.flake8 b/.flake8 index 7fe9791683..8d1222a8b3 100644 --- a/.flake8 +++ b/.flake8 @@ -155,6 +155,7 @@ exclude = components/protocomm/python/sec1_pb2.py, components/protocomm/python/sec2_pb2.py, components/protocomm/python/session_pb2.py, + components/wifi_provisioning/python/wifi_ctrl_pb2.py, components/wifi_provisioning/python/wifi_scan_pb2.py, components/wifi_provisioning/python/wifi_config_pb2.py, components/wifi_provisioning/python/wifi_constants_pb2.py, diff --git a/components/wifi_provisioning/CMakeLists.txt b/components/wifi_provisioning/CMakeLists.txt index 4826f72004..df306ad264 100644 --- a/components/wifi_provisioning/CMakeLists.txt +++ b/components/wifi_provisioning/CMakeLists.txt @@ -1,10 +1,12 @@ set(srcs "src/wifi_config.c" "src/wifi_scan.c" + "src/wifi_ctrl.c" "src/manager.c" "src/handlers.c" "src/scheme_console.c" "proto-c/wifi_config.pb-c.c" "proto-c/wifi_scan.pb-c.c" + "proto-c/wifi_ctrl.pb-c.c" "proto-c/wifi_constants.pb-c.c") if(CONFIG_ESP_WIFI_SOFTAP_SUPPORT) diff --git a/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.c b/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.c new file mode 100644 index 0000000000..a1a0fbf84a --- /dev/null +++ b/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.c @@ -0,0 +1,444 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: wifi_ctrl.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "wifi_ctrl.pb-c.h" +void cmd_ctrl_reset__init + (CmdCtrlReset *message) +{ + static const CmdCtrlReset init_value = CMD_CTRL_RESET__INIT; + *message = init_value; +} +size_t cmd_ctrl_reset__get_packed_size + (const CmdCtrlReset *message) +{ + assert(message->base.descriptor == &cmd_ctrl_reset__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t cmd_ctrl_reset__pack + (const CmdCtrlReset *message, + uint8_t *out) +{ + assert(message->base.descriptor == &cmd_ctrl_reset__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t cmd_ctrl_reset__pack_to_buffer + (const CmdCtrlReset *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &cmd_ctrl_reset__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +CmdCtrlReset * + cmd_ctrl_reset__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (CmdCtrlReset *) + protobuf_c_message_unpack (&cmd_ctrl_reset__descriptor, + allocator, len, data); +} +void cmd_ctrl_reset__free_unpacked + (CmdCtrlReset *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &cmd_ctrl_reset__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void resp_ctrl_reset__init + (RespCtrlReset *message) +{ + static const RespCtrlReset init_value = RESP_CTRL_RESET__INIT; + *message = init_value; +} +size_t resp_ctrl_reset__get_packed_size + (const RespCtrlReset *message) +{ + assert(message->base.descriptor == &resp_ctrl_reset__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t resp_ctrl_reset__pack + (const RespCtrlReset *message, + uint8_t *out) +{ + assert(message->base.descriptor == &resp_ctrl_reset__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t resp_ctrl_reset__pack_to_buffer + (const RespCtrlReset *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &resp_ctrl_reset__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +RespCtrlReset * + resp_ctrl_reset__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (RespCtrlReset *) + protobuf_c_message_unpack (&resp_ctrl_reset__descriptor, + allocator, len, data); +} +void resp_ctrl_reset__free_unpacked + (RespCtrlReset *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &resp_ctrl_reset__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void cmd_ctrl_reprov__init + (CmdCtrlReprov *message) +{ + static const CmdCtrlReprov init_value = CMD_CTRL_REPROV__INIT; + *message = init_value; +} +size_t cmd_ctrl_reprov__get_packed_size + (const CmdCtrlReprov *message) +{ + assert(message->base.descriptor == &cmd_ctrl_reprov__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t cmd_ctrl_reprov__pack + (const CmdCtrlReprov *message, + uint8_t *out) +{ + assert(message->base.descriptor == &cmd_ctrl_reprov__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t cmd_ctrl_reprov__pack_to_buffer + (const CmdCtrlReprov *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &cmd_ctrl_reprov__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +CmdCtrlReprov * + cmd_ctrl_reprov__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (CmdCtrlReprov *) + protobuf_c_message_unpack (&cmd_ctrl_reprov__descriptor, + allocator, len, data); +} +void cmd_ctrl_reprov__free_unpacked + (CmdCtrlReprov *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &cmd_ctrl_reprov__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void resp_ctrl_reprov__init + (RespCtrlReprov *message) +{ + static const RespCtrlReprov init_value = RESP_CTRL_REPROV__INIT; + *message = init_value; +} +size_t resp_ctrl_reprov__get_packed_size + (const RespCtrlReprov *message) +{ + assert(message->base.descriptor == &resp_ctrl_reprov__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t resp_ctrl_reprov__pack + (const RespCtrlReprov *message, + uint8_t *out) +{ + assert(message->base.descriptor == &resp_ctrl_reprov__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t resp_ctrl_reprov__pack_to_buffer + (const RespCtrlReprov *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &resp_ctrl_reprov__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +RespCtrlReprov * + resp_ctrl_reprov__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (RespCtrlReprov *) + protobuf_c_message_unpack (&resp_ctrl_reprov__descriptor, + allocator, len, data); +} +void resp_ctrl_reprov__free_unpacked + (RespCtrlReprov *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &resp_ctrl_reprov__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void wi_fi_ctrl_payload__init + (WiFiCtrlPayload *message) +{ + static const WiFiCtrlPayload init_value = WI_FI_CTRL_PAYLOAD__INIT; + *message = init_value; +} +size_t wi_fi_ctrl_payload__get_packed_size + (const WiFiCtrlPayload *message) +{ + assert(message->base.descriptor == &wi_fi_ctrl_payload__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t wi_fi_ctrl_payload__pack + (const WiFiCtrlPayload *message, + uint8_t *out) +{ + assert(message->base.descriptor == &wi_fi_ctrl_payload__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t wi_fi_ctrl_payload__pack_to_buffer + (const WiFiCtrlPayload *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &wi_fi_ctrl_payload__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +WiFiCtrlPayload * + wi_fi_ctrl_payload__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (WiFiCtrlPayload *) + protobuf_c_message_unpack (&wi_fi_ctrl_payload__descriptor, + allocator, len, data); +} +void wi_fi_ctrl_payload__free_unpacked + (WiFiCtrlPayload *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &wi_fi_ctrl_payload__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +#define cmd_ctrl_reset__field_descriptors NULL +#define cmd_ctrl_reset__field_indices_by_name NULL +#define cmd_ctrl_reset__number_ranges NULL +const ProtobufCMessageDescriptor cmd_ctrl_reset__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "CmdCtrlReset", + "CmdCtrlReset", + "CmdCtrlReset", + "", + sizeof(CmdCtrlReset), + 0, + cmd_ctrl_reset__field_descriptors, + cmd_ctrl_reset__field_indices_by_name, + 0, cmd_ctrl_reset__number_ranges, + (ProtobufCMessageInit) cmd_ctrl_reset__init, + NULL,NULL,NULL /* reserved[123] */ +}; +#define resp_ctrl_reset__field_descriptors NULL +#define resp_ctrl_reset__field_indices_by_name NULL +#define resp_ctrl_reset__number_ranges NULL +const ProtobufCMessageDescriptor resp_ctrl_reset__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "RespCtrlReset", + "RespCtrlReset", + "RespCtrlReset", + "", + sizeof(RespCtrlReset), + 0, + resp_ctrl_reset__field_descriptors, + resp_ctrl_reset__field_indices_by_name, + 0, resp_ctrl_reset__number_ranges, + (ProtobufCMessageInit) resp_ctrl_reset__init, + NULL,NULL,NULL /* reserved[123] */ +}; +#define cmd_ctrl_reprov__field_descriptors NULL +#define cmd_ctrl_reprov__field_indices_by_name NULL +#define cmd_ctrl_reprov__number_ranges NULL +const ProtobufCMessageDescriptor cmd_ctrl_reprov__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "CmdCtrlReprov", + "CmdCtrlReprov", + "CmdCtrlReprov", + "", + sizeof(CmdCtrlReprov), + 0, + cmd_ctrl_reprov__field_descriptors, + cmd_ctrl_reprov__field_indices_by_name, + 0, cmd_ctrl_reprov__number_ranges, + (ProtobufCMessageInit) cmd_ctrl_reprov__init, + NULL,NULL,NULL /* reserved[123] */ +}; +#define resp_ctrl_reprov__field_descriptors NULL +#define resp_ctrl_reprov__field_indices_by_name NULL +#define resp_ctrl_reprov__number_ranges NULL +const ProtobufCMessageDescriptor resp_ctrl_reprov__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "RespCtrlReprov", + "RespCtrlReprov", + "RespCtrlReprov", + "", + sizeof(RespCtrlReprov), + 0, + resp_ctrl_reprov__field_descriptors, + resp_ctrl_reprov__field_indices_by_name, + 0, resp_ctrl_reprov__number_ranges, + (ProtobufCMessageInit) resp_ctrl_reprov__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor wi_fi_ctrl_payload__field_descriptors[6] = +{ + { + "msg", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(WiFiCtrlPayload, msg), + &wi_fi_ctrl_msg_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "status", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(WiFiCtrlPayload, status), + &status__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "cmd_ctrl_reset", + 11, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(WiFiCtrlPayload, payload_case), + offsetof(WiFiCtrlPayload, cmd_ctrl_reset), + &cmd_ctrl_reset__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "resp_ctrl_reset", + 12, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(WiFiCtrlPayload, payload_case), + offsetof(WiFiCtrlPayload, resp_ctrl_reset), + &resp_ctrl_reset__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "cmd_ctrl_reprov", + 13, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(WiFiCtrlPayload, payload_case), + offsetof(WiFiCtrlPayload, cmd_ctrl_reprov), + &cmd_ctrl_reprov__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "resp_ctrl_reprov", + 14, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(WiFiCtrlPayload, payload_case), + offsetof(WiFiCtrlPayload, resp_ctrl_reprov), + &resp_ctrl_reprov__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned wi_fi_ctrl_payload__field_indices_by_name[] = { + 4, /* field[4] = cmd_ctrl_reprov */ + 2, /* field[2] = cmd_ctrl_reset */ + 0, /* field[0] = msg */ + 5, /* field[5] = resp_ctrl_reprov */ + 3, /* field[3] = resp_ctrl_reset */ + 1, /* field[1] = status */ +}; +static const ProtobufCIntRange wi_fi_ctrl_payload__number_ranges[2 + 1] = +{ + { 1, 0 }, + { 11, 2 }, + { 0, 6 } +}; +const ProtobufCMessageDescriptor wi_fi_ctrl_payload__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "WiFiCtrlPayload", + "WiFiCtrlPayload", + "WiFiCtrlPayload", + "", + sizeof(WiFiCtrlPayload), + 6, + wi_fi_ctrl_payload__field_descriptors, + wi_fi_ctrl_payload__field_indices_by_name, + 2, wi_fi_ctrl_payload__number_ranges, + (ProtobufCMessageInit) wi_fi_ctrl_payload__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue wi_fi_ctrl_msg_type__enum_values_by_number[5] = +{ + { "TypeCtrlReserved", "WI_FI_CTRL_MSG_TYPE__TypeCtrlReserved", 0 }, + { "TypeCmdCtrlReset", "WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReset", 1 }, + { "TypeRespCtrlReset", "WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReset", 2 }, + { "TypeCmdCtrlReprov", "WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReprov", 3 }, + { "TypeRespCtrlReprov", "WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReprov", 4 }, +}; +static const ProtobufCIntRange wi_fi_ctrl_msg_type__value_ranges[] = { +{0, 0},{0, 5} +}; +static const ProtobufCEnumValueIndex wi_fi_ctrl_msg_type__enum_values_by_name[5] = +{ + { "TypeCmdCtrlReprov", 3 }, + { "TypeCmdCtrlReset", 1 }, + { "TypeCtrlReserved", 0 }, + { "TypeRespCtrlReprov", 4 }, + { "TypeRespCtrlReset", 2 }, +}; +const ProtobufCEnumDescriptor wi_fi_ctrl_msg_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "WiFiCtrlMsgType", + "WiFiCtrlMsgType", + "WiFiCtrlMsgType", + "", + 5, + wi_fi_ctrl_msg_type__enum_values_by_number, + 5, + wi_fi_ctrl_msg_type__enum_values_by_name, + 1, + wi_fi_ctrl_msg_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.h b/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.h new file mode 100644 index 0000000000..2291bf31c8 --- /dev/null +++ b/components/wifi_provisioning/proto-c/wifi_ctrl.pb-c.h @@ -0,0 +1,230 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: wifi_ctrl.proto */ + +#ifndef PROTOBUF_C_wifi_5fctrl_2eproto__INCLUDED +#define PROTOBUF_C_wifi_5fctrl_2eproto__INCLUDED + +#include + +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 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 + +#include "constants.pb-c.h" + +typedef struct CmdCtrlReset CmdCtrlReset; +typedef struct RespCtrlReset RespCtrlReset; +typedef struct CmdCtrlReprov CmdCtrlReprov; +typedef struct RespCtrlReprov RespCtrlReprov; +typedef struct WiFiCtrlPayload WiFiCtrlPayload; + + +/* --- enums --- */ + +typedef enum _WiFiCtrlMsgType { + WI_FI_CTRL_MSG_TYPE__TypeCtrlReserved = 0, + WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReset = 1, + WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReset = 2, + WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReprov = 3, + WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReprov = 4 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(WI_FI_CTRL_MSG_TYPE) +} WiFiCtrlMsgType; + +/* --- messages --- */ + +struct CmdCtrlReset +{ + ProtobufCMessage base; +}; +#define CMD_CTRL_RESET__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&cmd_ctrl_reset__descriptor) \ + } + + +struct RespCtrlReset +{ + ProtobufCMessage base; +}; +#define RESP_CTRL_RESET__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&resp_ctrl_reset__descriptor) \ + } + + +struct CmdCtrlReprov +{ + ProtobufCMessage base; +}; +#define CMD_CTRL_REPROV__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&cmd_ctrl_reprov__descriptor) \ + } + + +struct RespCtrlReprov +{ + ProtobufCMessage base; +}; +#define RESP_CTRL_REPROV__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&resp_ctrl_reprov__descriptor) \ + } + + +typedef enum { + WI_FI_CTRL_PAYLOAD__PAYLOAD__NOT_SET = 0, + WI_FI_CTRL_PAYLOAD__PAYLOAD_CMD_CTRL_RESET = 11, + WI_FI_CTRL_PAYLOAD__PAYLOAD_RESP_CTRL_RESET = 12, + WI_FI_CTRL_PAYLOAD__PAYLOAD_CMD_CTRL_REPROV = 13, + WI_FI_CTRL_PAYLOAD__PAYLOAD_RESP_CTRL_REPROV = 14 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(WI_FI_CTRL_PAYLOAD__PAYLOAD__CASE) +} WiFiCtrlPayload__PayloadCase; + +struct WiFiCtrlPayload +{ + ProtobufCMessage base; + WiFiCtrlMsgType msg; + Status status; + WiFiCtrlPayload__PayloadCase payload_case; + union { + CmdCtrlReset *cmd_ctrl_reset; + RespCtrlReset *resp_ctrl_reset; + CmdCtrlReprov *cmd_ctrl_reprov; + RespCtrlReprov *resp_ctrl_reprov; + }; +}; +#define WI_FI_CTRL_PAYLOAD__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&wi_fi_ctrl_payload__descriptor) \ + , WI_FI_CTRL_MSG_TYPE__TypeCtrlReserved, STATUS__Success, WI_FI_CTRL_PAYLOAD__PAYLOAD__NOT_SET, {0} } + + +/* CmdCtrlReset methods */ +void cmd_ctrl_reset__init + (CmdCtrlReset *message); +size_t cmd_ctrl_reset__get_packed_size + (const CmdCtrlReset *message); +size_t cmd_ctrl_reset__pack + (const CmdCtrlReset *message, + uint8_t *out); +size_t cmd_ctrl_reset__pack_to_buffer + (const CmdCtrlReset *message, + ProtobufCBuffer *buffer); +CmdCtrlReset * + cmd_ctrl_reset__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void cmd_ctrl_reset__free_unpacked + (CmdCtrlReset *message, + ProtobufCAllocator *allocator); +/* RespCtrlReset methods */ +void resp_ctrl_reset__init + (RespCtrlReset *message); +size_t resp_ctrl_reset__get_packed_size + (const RespCtrlReset *message); +size_t resp_ctrl_reset__pack + (const RespCtrlReset *message, + uint8_t *out); +size_t resp_ctrl_reset__pack_to_buffer + (const RespCtrlReset *message, + ProtobufCBuffer *buffer); +RespCtrlReset * + resp_ctrl_reset__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void resp_ctrl_reset__free_unpacked + (RespCtrlReset *message, + ProtobufCAllocator *allocator); +/* CmdCtrlReprov methods */ +void cmd_ctrl_reprov__init + (CmdCtrlReprov *message); +size_t cmd_ctrl_reprov__get_packed_size + (const CmdCtrlReprov *message); +size_t cmd_ctrl_reprov__pack + (const CmdCtrlReprov *message, + uint8_t *out); +size_t cmd_ctrl_reprov__pack_to_buffer + (const CmdCtrlReprov *message, + ProtobufCBuffer *buffer); +CmdCtrlReprov * + cmd_ctrl_reprov__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void cmd_ctrl_reprov__free_unpacked + (CmdCtrlReprov *message, + ProtobufCAllocator *allocator); +/* RespCtrlReprov methods */ +void resp_ctrl_reprov__init + (RespCtrlReprov *message); +size_t resp_ctrl_reprov__get_packed_size + (const RespCtrlReprov *message); +size_t resp_ctrl_reprov__pack + (const RespCtrlReprov *message, + uint8_t *out); +size_t resp_ctrl_reprov__pack_to_buffer + (const RespCtrlReprov *message, + ProtobufCBuffer *buffer); +RespCtrlReprov * + resp_ctrl_reprov__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void resp_ctrl_reprov__free_unpacked + (RespCtrlReprov *message, + ProtobufCAllocator *allocator); +/* WiFiCtrlPayload methods */ +void wi_fi_ctrl_payload__init + (WiFiCtrlPayload *message); +size_t wi_fi_ctrl_payload__get_packed_size + (const WiFiCtrlPayload *message); +size_t wi_fi_ctrl_payload__pack + (const WiFiCtrlPayload *message, + uint8_t *out); +size_t wi_fi_ctrl_payload__pack_to_buffer + (const WiFiCtrlPayload *message, + ProtobufCBuffer *buffer); +WiFiCtrlPayload * + wi_fi_ctrl_payload__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void wi_fi_ctrl_payload__free_unpacked + (WiFiCtrlPayload *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*CmdCtrlReset_Closure) + (const CmdCtrlReset *message, + void *closure_data); +typedef void (*RespCtrlReset_Closure) + (const RespCtrlReset *message, + void *closure_data); +typedef void (*CmdCtrlReprov_Closure) + (const CmdCtrlReprov *message, + void *closure_data); +typedef void (*RespCtrlReprov_Closure) + (const RespCtrlReprov *message, + void *closure_data); +typedef void (*WiFiCtrlPayload_Closure) + (const WiFiCtrlPayload *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor wi_fi_ctrl_msg_type__descriptor; +extern const ProtobufCMessageDescriptor cmd_ctrl_reset__descriptor; +extern const ProtobufCMessageDescriptor resp_ctrl_reset__descriptor; +extern const ProtobufCMessageDescriptor cmd_ctrl_reprov__descriptor; +extern const ProtobufCMessageDescriptor resp_ctrl_reprov__descriptor; +extern const ProtobufCMessageDescriptor wi_fi_ctrl_payload__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_wifi_5fctrl_2eproto__INCLUDED */ diff --git a/components/wifi_provisioning/proto/wifi_ctrl.proto b/components/wifi_provisioning/proto/wifi_ctrl.proto new file mode 100644 index 0000000000..a2f8c7e253 --- /dev/null +++ b/components/wifi_provisioning/proto/wifi_ctrl.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +import "constants.proto"; + +message CmdCtrlReset { + +} + +message RespCtrlReset { + +} + +message CmdCtrlReprov { + +} + +message RespCtrlReprov{ + +} + +enum WiFiCtrlMsgType { + TypeCtrlReserved = 0; + TypeCmdCtrlReset = 1; + TypeRespCtrlReset = 2; + TypeCmdCtrlReprov = 3; + TypeRespCtrlReprov = 4; +} + +message WiFiCtrlPayload { + WiFiCtrlMsgType msg = 1; + Status status = 2; + oneof payload { + CmdCtrlReset cmd_ctrl_reset = 11; + RespCtrlReset resp_ctrl_reset = 12; + CmdCtrlReprov cmd_ctrl_reprov = 13; + RespCtrlReprov resp_ctrl_reprov = 14; + } +} diff --git a/components/wifi_provisioning/python/wifi_ctrl_pb2.py b/components/wifi_provisioning/python/wifi_ctrl_pb2.py new file mode 100644 index 0000000000..1057164e9a --- /dev/null +++ b/components/wifi_provisioning/python/wifi_ctrl_pb2.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: wifi_ctrl.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import constants_pb2 as constants__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fwifi_ctrl.proto\x1a\x0f\x63onstants.proto\"\x0e\n\x0c\x43mdCtrlReset\"\x0f\n\rRespCtrlReset\"\x0f\n\rCmdCtrlReprov\"\x10\n\x0eRespCtrlReprov\"\x80\x02\n\x0fWiFiCtrlPayload\x12\x1d\n\x03msg\x18\x01 \x01(\x0e\x32\x10.WiFiCtrlMsgType\x12\x17\n\x06status\x18\x02 \x01(\x0e\x32\x07.Status\x12\'\n\x0e\x63md_ctrl_reset\x18\x0b \x01(\x0b\x32\r.CmdCtrlResetH\x00\x12)\n\x0fresp_ctrl_reset\x18\x0c \x01(\x0b\x32\x0e.RespCtrlResetH\x00\x12)\n\x0f\x63md_ctrl_reprov\x18\r \x01(\x0b\x32\x0e.CmdCtrlReprovH\x00\x12+\n\x10resp_ctrl_reprov\x18\x0e \x01(\x0b\x32\x0f.RespCtrlReprovH\x00\x42\t\n\x07payload*\x83\x01\n\x0fWiFiCtrlMsgType\x12\x14\n\x10TypeCtrlReserved\x10\x00\x12\x14\n\x10TypeCmdCtrlReset\x10\x01\x12\x15\n\x11TypeRespCtrlReset\x10\x02\x12\x15\n\x11TypeCmdCtrlReprov\x10\x03\x12\x16\n\x12TypeRespCtrlReprov\x10\x04\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_ctrl_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _WIFICTRLMSGTYPE._serialized_start=364 + _WIFICTRLMSGTYPE._serialized_end=495 + _CMDCTRLRESET._serialized_start=36 + _CMDCTRLRESET._serialized_end=50 + _RESPCTRLRESET._serialized_start=52 + _RESPCTRLRESET._serialized_end=67 + _CMDCTRLREPROV._serialized_start=69 + _CMDCTRLREPROV._serialized_end=84 + _RESPCTRLREPROV._serialized_start=86 + _RESPCTRLREPROV._serialized_end=102 + _WIFICTRLPAYLOAD._serialized_start=105 + _WIFICTRLPAYLOAD._serialized_end=361 +# @@protoc_insertion_point(module_scope) diff --git a/components/wifi_provisioning/src/handlers.c b/components/wifi_provisioning/src/handlers.c index a1b6deeac7..36f309fe26 100644 --- a/components/wifi_provisioning/src/handlers.c +++ b/components/wifi_provisioning/src/handlers.c @@ -1,16 +1,8 @@ -// 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. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -22,6 +14,7 @@ #include "wifi_provisioning/wifi_config.h" #include "wifi_provisioning/wifi_scan.h" +#include "wifi_ctrl.h" #include "wifi_provisioning/manager.h" #include "wifi_provisioning_priv.h" @@ -202,3 +195,25 @@ esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr) ptr->ctx = NULL; return ESP_OK; } + +/*************************************************************************/ + +static esp_err_t ctrl_reset(void) +{ + return wifi_prov_mgr_reset_sm_state_on_failure(); +} + +static esp_err_t ctrl_reprov(void) +{ + return wifi_prov_mgr_reset_sm_state_for_reprovision(); +} + +esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr) +{ + if (!ptr) { + return ESP_ERR_INVALID_ARG; + } + ptr->ctrl_reset = ctrl_reset; + ptr->ctrl_reprov = ctrl_reprov; + return ESP_OK; +} diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index 179e55c994..7d76a1c667 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -112,6 +112,9 @@ struct wifi_prov_mgr_ctx { /* Protocomm handlers for Wi-Fi scan endpoint */ wifi_prov_scan_handlers_t *wifi_scan_handlers; + /* Protocomm handlers for Wi-Fi ctrl endpoint */ + wifi_ctrl_handlers_t *wifi_ctrl_handlers; + /* Count of used endpoint UUIDs */ unsigned int endpoint_uuid_used; @@ -386,12 +389,36 @@ static esp_err_t wifi_prov_mgr_start_service(const char *service_name, const cha return ret; } + prov_ctx->wifi_ctrl_handlers = malloc(sizeof(wifi_ctrl_handlers_t)); + ret = get_wifi_ctrl_handlers(prov_ctx->wifi_ctrl_handlers); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to allocate memory for Wi-Fi ctrl handlers"); + free(prov_ctx->wifi_prov_handlers); + scheme->prov_stop(prov_ctx->pc); + protocomm_delete(prov_ctx->pc); + return ESP_ERR_NO_MEM; + } + + /* Add endpoint for controlling state of Wi-Fi station */ + ret = protocomm_add_endpoint(prov_ctx->pc, "prov-ctrl", + wifi_ctrl_handler, + prov_ctx->wifi_ctrl_handlers); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set Wi-Fi ctrl endpoint"); + free(prov_ctx->wifi_ctrl_handlers); + free(prov_ctx->wifi_prov_handlers); + scheme->prov_stop(prov_ctx->pc); + protocomm_delete(prov_ctx->pc); + return ret; + } + /* Register global event handler */ ret = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_prov_mgr_event_handler_internal, NULL); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to register WiFi event handler"); free(prov_ctx->wifi_scan_handlers); + free(prov_ctx->wifi_ctrl_handlers); free(prov_ctx->wifi_prov_handlers); scheme->prov_stop(prov_ctx->pc); protocomm_delete(prov_ctx->pc); @@ -405,6 +432,7 @@ static esp_err_t wifi_prov_mgr_start_service(const char *service_name, const cha esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_prov_mgr_event_handler_internal); free(prov_ctx->wifi_scan_handlers); + free(prov_ctx->wifi_ctrl_handlers); free(prov_ctx->wifi_prov_handlers); scheme->prov_stop(prov_ctx->pc); protocomm_delete(prov_ctx->pc); @@ -512,6 +540,9 @@ static void prov_stop_task(void *arg) free(prov_ctx->wifi_scan_handlers); prov_ctx->wifi_scan_handlers = NULL; + free(prov_ctx->wifi_ctrl_handlers); + prov_ctx->wifi_ctrl_handlers = NULL; + /* Switch device to Wi-Fi STA mode irrespective of * whether provisioning was completed or not */ esp_wifi_set_mode(WIFI_MODE_STA); @@ -1262,6 +1293,12 @@ esp_err_t wifi_prov_mgr_init(wifi_prov_mgr_config_t config) goto exit; } + ret = scheme->set_config_endpoint(prov_ctx->prov_scheme_config, "prov-ctrl", 0xFF4F); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to configure Wi-Fi state control endpoint"); + goto exit; + } + ret = scheme->set_config_endpoint(prov_ctx->prov_scheme_config, "prov-scan", 0xFF50); if (ret != ESP_OK) { ESP_LOGE(TAG, "failed to configure Wi-Fi scanning endpoint"); diff --git a/components/wifi_provisioning/src/wifi_ctrl.c b/components/wifi_provisioning/src/wifi_ctrl.c new file mode 100644 index 0000000000..2cf496b27b --- /dev/null +++ b/components/wifi_provisioning/src/wifi_ctrl.c @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "wifi_ctrl.pb-c.h" + +#include "wifi_ctrl.h" + +static const char *TAG = "proto_wifi_ctrl"; + +typedef struct wifi_ctrl_cmd { + int cmd_id; + esp_err_t (*command_handler)(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, void *priv_data); +} wifi_ctrl_cmd_t; + +static esp_err_t cmd_ctrl_reset_handler(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, + void *priv_data); + +static esp_err_t cmd_ctrl_reprov_handler(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, + void *priv_data); + +static wifi_ctrl_cmd_t cmd_table[] = { + { + .cmd_id = WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReset, + .command_handler = cmd_ctrl_reset_handler + }, + { + .cmd_id = WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReprov, + .command_handler = cmd_ctrl_reprov_handler + }, +}; + +static esp_err_t cmd_ctrl_reset_handler(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, void *priv_data) +{ + wifi_ctrl_handlers_t *h = (wifi_ctrl_handlers_t *) priv_data; + if (!h) { + ESP_LOGE(TAG, "Command invoked without handlers"); + return ESP_ERR_INVALID_STATE; + } + + RespCtrlReset *resp_payload = (RespCtrlReset *) malloc(sizeof(RespCtrlReset)); + if (!resp_payload) { + ESP_LOGE(TAG, "Error allocating memory"); + return ESP_ERR_NO_MEM; + } + + resp_ctrl_reset__init(resp_payload); + resp->status = (h->ctrl_reset() == ESP_OK ? + STATUS__Success : STATUS__InternalError); + resp->payload_case = WI_FI_CTRL_PAYLOAD__PAYLOAD_RESP_CTRL_RESET; + resp->resp_ctrl_reset = resp_payload; + return ESP_OK; +} + +static esp_err_t cmd_ctrl_reprov_handler(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, void *priv_data) +{ + wifi_ctrl_handlers_t *h = (wifi_ctrl_handlers_t *) priv_data; + if (!h) { + ESP_LOGE(TAG, "Command invoked without handlers"); + return ESP_ERR_INVALID_STATE; + } + + RespCtrlReprov *resp_payload = (RespCtrlReprov *) malloc(sizeof(RespCtrlReprov)); + if (!resp_payload) { + ESP_LOGE(TAG, "Error allocating memory"); + return ESP_ERR_NO_MEM; + } + + resp_ctrl_reprov__init(resp_payload); + resp->status = (h->ctrl_reprov() == ESP_OK ? + STATUS__Success : STATUS__InternalError); + resp->payload_case = WI_FI_CTRL_PAYLOAD__PAYLOAD_RESP_CTRL_REPROV; + resp->resp_ctrl_reprov = resp_payload; + return ESP_OK; +} + +static int lookup_cmd_handler(int cmd_id) +{ + for (size_t i = 0; i < sizeof(cmd_table)/sizeof(wifi_ctrl_cmd_t); i++) { + if (cmd_table[i].cmd_id == cmd_id) { + return i; + } + } + + return -1; +} + +static void wifi_ctrl_cmd_cleanup(WiFiCtrlPayload *resp, void *priv_data) +{ + switch (resp->msg) { + case WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReset: + { + free(resp->resp_ctrl_reset); + } + break; + case WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReprov: + { + free(resp->resp_ctrl_reprov); + } + break; + default: + ESP_LOGE(TAG, "Unsupported response type in cleanup_handler"); + break; + } + return; +} + +static esp_err_t wifi_ctrl_cmd_dispatcher(WiFiCtrlPayload *req, + WiFiCtrlPayload *resp, void *priv_data) +{ + esp_err_t ret; + + ESP_LOGD(TAG, "In wifi_ctrl_cmd_dispatcher Cmd=%d", req->msg); + + int cmd_index = lookup_cmd_handler(req->msg); + if (cmd_index < 0) { + ESP_LOGE(TAG, "Failed to find cmd with ID = %d in the command table", req->msg); + return ESP_FAIL; + } + + ret = cmd_table[cmd_index].command_handler(req, resp, priv_data); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Error executing command handler"); + } + + return ret; +} + +esp_err_t wifi_ctrl_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, void *priv_data) +{ + WiFiCtrlPayload *req; + WiFiCtrlPayload resp; + esp_err_t ret = ESP_OK; + + req = wi_fi_ctrl_payload__unpack(NULL, inlen, inbuf); + if (!req) { + ESP_LOGE(TAG, "Unable to unpack ctrl message"); + return ESP_ERR_INVALID_ARG; + } + + wi_fi_ctrl_payload__init(&resp); + ret = wifi_ctrl_cmd_dispatcher(req, &resp, priv_data); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Command dispatcher error %02X", ret); + ret = ESP_FAIL; + goto exit; + } + + resp.msg = req->msg + 1; /* Response is request + 1 */ + *outlen = wi_fi_ctrl_payload__get_packed_size(&resp); + if (*outlen <= 0) { + ESP_LOGE(TAG, "Invalid encoding for response"); + ret = ESP_FAIL; + goto exit; + } + + *outbuf = (uint8_t *) malloc(*outlen); + if (!*outbuf) { + ESP_LOGE(TAG, "Failed to allocate memory for the output buffer"); + ret = ESP_ERR_NO_MEM; + goto exit; + } + wi_fi_ctrl_payload__pack(&resp, *outbuf); + ESP_LOGD(TAG, "Response packet size : %d", *outlen); + exit: + + wi_fi_ctrl_payload__free_unpacked(req, NULL); + wifi_ctrl_cmd_cleanup(&resp, priv_data); + return ret; +} diff --git a/components/wifi_provisioning/src/wifi_ctrl.h b/components/wifi_provisioning/src/wifi_ctrl.h new file mode 100644 index 0000000000..dd6fc50624 --- /dev/null +++ b/components/wifi_provisioning/src/wifi_ctrl.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _PROV_WIFI_CTRL_H_ +#define _PROV_WIFI_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Internal handlers for receiving and responding to protocomm + * requests from client + * + * This is to be passed as priv_data for protocomm request handler + * (refer to `wifi_ctrl_handler()`) when calling `protocomm_add_endpoint()`. + */ +typedef struct wifi_ctrl_handlers { + /** + * Handler function called when ctrl reset command is received + */ + esp_err_t (*ctrl_reset)(void); + + /** + * Handler function called when ctrl reprov command is received + */ + esp_err_t (*ctrl_reprov)(void); + +} wifi_ctrl_handlers_t; + +/** + * @brief Handler for sending on demand Wi-Fi ctrl results + * + * This is to be registered as the `prov-ctrl` endpoint handler + * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` + */ +esp_err_t wifi_ctrl_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, void *priv_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/wifi_provisioning/src/wifi_provisioning_priv.h b/components/wifi_provisioning/src/wifi_provisioning_priv.h index a607b49dcb..a58d2589d9 100644 --- a/components/wifi_provisioning/src/wifi_provisioning_priv.h +++ b/components/wifi_provisioning/src/wifi_provisioning_priv.h @@ -1,16 +1,8 @@ -// 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. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -20,6 +12,7 @@ #include "wifi_provisioning/manager.h" #include "wifi_provisioning/wifi_config.h" #include "wifi_provisioning/wifi_scan.h" +#include "wifi_ctrl.h" /** * @brief Notify manager that provisioning is done @@ -100,3 +93,14 @@ esp_err_t get_wifi_prov_handlers(wifi_prov_config_handlers_t *ptr); * - ESP_ERR_INVALID_ARG : null argument */ esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr); + +/** + * @brief Get protocomm handlers for wifi_ctrl provisioning endpoint + * + * @param[in] ptr pointer to structure to be set + * + * @return + * - ESP_OK : success + * - ESP_ERR_INVALID_ARG : null argument + */ +esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr); diff --git a/docs/en/api-reference/provisioning/wifi_provisioning.rst b/docs/en/api-reference/provisioning/wifi_provisioning.rst index a6567ae5e5..85999f1261 100644 --- a/docs/en/api-reference/provisioning/wifi_provisioning.rst +++ b/docs/en/api-reference/provisioning/wifi_provisioning.rst @@ -204,6 +204,9 @@ Once connected to the device, the provisioning related protocomm endpoints can b * - prov-scan - http://wifi-prov.local/prov-scan - Endpoint used for starting Wi-Fi scan and receiving scan results + * - prov-ctrl + - http://wifi-prov.local/prov-ctrl + - Endpoint used for controlling Wi-Fi provisioning state * - prov-config - http://.local/prov-config - Endpoint used for configuring Wi-Fi credentials on device @@ -241,6 +244,12 @@ After session establishment, client can also request Wi-Fi scan results from the * `count` (input) - Number of entries to fetch from the starting index * `entries` (output) - List of entries returned. Each entry consists of `ssid`, `channel` and `rssi` information +The client can also control the provisioning state of the device using `wifi_ctrl` endpoint. The `wifi_ctrl` endpoint supports the following protobuf commands: + + * `ctrl_reset` - Resets internal state machine of the device and clears provisioned credentials only in case of provisioning failures. + + * `ctrl_reprov` - Resets internal state machine of the device and clears provisioned credentials only in case the device is to be provisioned again for new credentials after a previous successful provisioning + Additional Endpoints ^^^^^^^^^^^^^^^^^^^^ diff --git a/tools/ci/check_copyright_config.yaml b/tools/ci/check_copyright_config.yaml index df7774885b..d3b71ec38d 100644 --- a/tools/ci/check_copyright_config.yaml +++ b/tools/ci/check_copyright_config.yaml @@ -170,3 +170,9 @@ ignore: - '!components/bt/host/bluedroid/api/' - '!components/bt/host/bluedroid/btc/' - examples/zigbee/ + - components/esp_local_ctrl/proto-c/ + - components/esp_local_ctrl/python/ + - components/protocomm/proto-c/ + - components/protocomm/python/ + - components/wifi_provisioning/proto-c/ + - components/wifi_provisioning/python/ diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b555d1df1c..ec0891b177 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -434,9 +434,6 @@ components/esp_hid/test/test_esp_hid.c components/esp_hw_support/include/esp_clk.h components/esp_hw_support/include/soc/esp_himem.h components/esp_hw_support/include/soc/esp_spiram.h -components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.c -components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.h -components/esp_local_ctrl/python/esp_local_ctrl_pb2.py components/esp_local_ctrl/src/esp_local_ctrl_handler.c components/esp_local_ctrl/src/esp_local_ctrl_priv.h components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c @@ -886,21 +883,6 @@ components/nvs_flash/test_nvs_host/test_nvs_storage.cpp components/openthread/include/esp_openthread_lock.h components/protocomm/include/transports/protocomm_console.h components/protocomm/include/transports/protocomm_httpd.h -components/protocomm/proto-c/constants.pb-c.c -components/protocomm/proto-c/constants.pb-c.h -components/protocomm/proto-c/sec0.pb-c.c -components/protocomm/proto-c/sec0.pb-c.h -components/protocomm/proto-c/sec1.pb-c.c -components/protocomm/proto-c/sec1.pb-c.h -components/protocomm/proto-c/sec2.pb-c.c -components/protocomm/proto-c/sec2.pb-c.h -components/protocomm/proto-c/session.pb-c.c -components/protocomm/proto-c/session.pb-c.h -components/protocomm/python/constants_pb2.py -components/protocomm/python/sec0_pb2.py -components/protocomm/python/sec1_pb2.py -components/protocomm/python/sec2_pb2.py -components/protocomm/python/session_pb2.py components/pthread/pthread_cond_var.c components/pthread/pthread_internal.h components/pthread/test/test_cxx_cond_var.cpp @@ -1249,19 +1231,8 @@ components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h components/wifi_provisioning/include/wifi_provisioning/scheme_console.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h -components/wifi_provisioning/proto-c/wifi_config.pb-c.c -components/wifi_provisioning/proto-c/wifi_config.pb-c.h -components/wifi_provisioning/proto-c/wifi_constants.pb-c.c -components/wifi_provisioning/proto-c/wifi_constants.pb-c.h -components/wifi_provisioning/proto-c/wifi_scan.pb-c.c -components/wifi_provisioning/proto-c/wifi_scan.pb-c.h -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/handlers.c components/wifi_provisioning/src/scheme_console.c components/wifi_provisioning/src/wifi_config.c -components/wifi_provisioning/src/wifi_provisioning_priv.h components/wifi_provisioning/src/wifi_scan.c components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h components/wpa_supplicant/esp_supplicant/src/esp_wpa3_i.h diff --git a/tools/ci/mypy_ignore_list.txt b/tools/ci/mypy_ignore_list.txt index a50adee500..4e6952623d 100644 --- a/tools/ci/mypy_ignore_list.txt +++ b/tools/ci/mypy_ignore_list.txt @@ -20,6 +20,7 @@ components/protocomm/python/sec1_pb2.py components/protocomm/python/session_pb2.py components/wifi_provisioning/python/wifi_config_pb2.py components/wifi_provisioning/python/wifi_constants_pb2.py +components/wifi_provisioning/python/wifi_ctrl_pb2.py components/wifi_provisioning/python/wifi_scan_pb2.py components/xtensa/trax/traceparse.py docs/build_docs.py @@ -175,6 +176,7 @@ tools/esp_app_trace/logtrace_proc.py tools/esp_app_trace/sysviewtrace_proc.py tools/esp_prov/esp_prov.py tools/esp_prov/prov/custom_prov.py +tools/esp_prov/prov/wifi_ctrl.py tools/esp_prov/prov/wifi_prov.py tools/esp_prov/prov/wifi_scan.py tools/esp_prov/security/security.py diff --git a/tools/esp_prov/README.md b/tools/esp_prov/README.md index 78d4a870df..b617f2a7c5 100644 --- a/tools/esp_prov/README.md +++ b/tools/esp_prov/README.md @@ -12,6 +12,7 @@ Usage of `esp-prov` assumes that the provisioning app has specific protocomm end | prov-config | http://ip:port/prov-config | Endpoint used for configuring Wi-Fi credentials on device | | proto-ver | http://ip:port/proto-ver | Version endpoint for checking protocol compatibility | | prov-scan | http://ip:port/prov-scan | Endpoint used for scanning Wi-Fi APs | +| prov-ctrl | http://ip:port/prov-ctrl | Endpoint used for controlling Wi-Fi provisioning state | | custom-data | http://ip:port/custom-data | Optional endpoint for sending custom data (refer `wifi_prov_mgr` example) | @@ -78,6 +79,12 @@ python esp_prov.py --transport < mode of provisioning : softap \ ble \ console > - For specifying the optional `SRP6a` salt length to be used for generating protocomm endpoint security version 2 credentials - Ignored when other security versions are used and the ``--sec2_gen_cred` option is not set +* `--reset` (Optional) + - Resets internal state machine of the device and clears provisioned credentials; to be used only in case of provisioning failures + +* `--reprov` (Optional) + - Resets internal state machine of the device and clears provisioned credentials; to be used only in case the device is to be provisioned again for new credentials after a previous successful provisioning + * `--custom_data ` (Optional) An information string can be sent to the `custom-data` endpoint during provisioning using this argument. (Assumes the provisioning app has an endpoint called `custom-data` - see [provisioning/wifi_prov_mgr](https://github.com/espressif/esp-idf/tree/master/examples/provisioning/wifi_prov_mgr) example for implementation details). diff --git a/tools/esp_prov/esp_prov.py b/tools/esp_prov/esp_prov.py index 03e7b022ef..567ac16719 100644 --- a/tools/esp_prov/esp_prov.py +++ b/tools/esp_prov/esp_prov.py @@ -290,6 +290,28 @@ async def wait_wifi_connected(tp, sec): return False +async def reset_wifi(tp, sec): + try: + message = prov.ctrl_reset_request(sec) + response = await tp.send_data('prov-ctrl', message) + prov.ctrl_reset_response(sec, response) + + except RuntimeError as e: + on_except(e) + return None + + +async def reprov_wifi(tp, sec): + try: + message = prov.ctrl_reprov_request(sec) + response = await tp.send_data('prov-ctrl', message) + prov.ctrl_reprov_response(sec, response) + + except RuntimeError as e: + on_except(e) + return None + + def desc_format(*args): desc = '' for arg in args: @@ -372,6 +394,10 @@ async def main(): 'This is an optional parameter, only intended for use with ' '"examples/provisioning/wifi_prov_mgr"')) + parser.add_argument('--reset', help='Reset WiFi', action='store_true') + + parser.add_argument('--reprov', help='Reprovision WiFi', action='store_true') + parser.add_argument('-v','--verbose', help='Increase output verbosity', action='store_true') args = parser.parse_args() @@ -432,6 +458,16 @@ async def main(): raise RuntimeError('Error in establishing session') print('==== Session Established ====') + if args.reset: + print('==== Reseting WiFi====') + await reset_wifi(obj_transport, obj_security) + sys.exit() + + if args.reprov: + print('==== Reprovisioning WiFi====') + await reprov_wifi(obj_transport, obj_security) + sys.exit() + if args.custom_data != '': print('\n==== Sending Custom data to Target ====') if not await custom_data(obj_transport, obj_security, args.custom_data): diff --git a/tools/esp_prov/proto/__init__.py b/tools/esp_prov/proto/__init__.py index 24b89abd5e..f42abbcc92 100644 --- a/tools/esp_prov/proto/__init__.py +++ b/tools/esp_prov/proto/__init__.py @@ -34,3 +34,4 @@ session_pb2 = _load_source('session_pb2', idf_path + '/components/protocomm/ wifi_constants_pb2 = _load_source('wifi_constants_pb2', idf_path + '/components/wifi_provisioning/python/wifi_constants_pb2.py') wifi_config_pb2 = _load_source('wifi_config_pb2', idf_path + '/components/wifi_provisioning/python/wifi_config_pb2.py') wifi_scan_pb2 = _load_source('wifi_scan_pb2', idf_path + '/components/wifi_provisioning/python/wifi_scan_pb2.py') +wifi_ctrl_pb2 = _load_source('wifi_ctrl_pb2', idf_path + '/components/wifi_provisioning/python/wifi_ctrl_pb2.py') diff --git a/tools/esp_prov/prov/__init__.py b/tools/esp_prov/prov/__init__.py index 0778774299..8911e802df 100644 --- a/tools/esp_prov/prov/__init__.py +++ b/tools/esp_prov/prov/__init__.py @@ -3,5 +3,6 @@ # from .custom_prov import * # noqa F403 +from .wifi_ctrl import * # noqa F403 from .wifi_prov import * # noqa F403 from .wifi_scan import * # noqa F403 diff --git a/tools/esp_prov/prov/wifi_ctrl.py b/tools/esp_prov/prov/wifi_ctrl.py new file mode 100644 index 0000000000..77a5b06e87 --- /dev/null +++ b/tools/esp_prov/prov/wifi_ctrl.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +# + +# APIs for interpreting and creating protobuf packets for Wi-Fi State Controlling + +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') + + +def ctrl_reset_request(security_ctx): + # Form protobuf request packet for CtrlReset command + cmd = proto.wifi_ctrl_pb2.WiFiCtrlPayload() + cmd.msg = proto.wifi_ctrl_pb2.TypeCmdCtrlReset + enc_cmd = security_ctx.encrypt_data(cmd.SerializeToString()) + print_verbose(security_ctx, f'Client -> Device (Encrypted CmdCtrlReset): 0x{enc_cmd.hex()}') + return enc_cmd.decode('latin-1') + + +def ctrl_reset_response(security_ctx, response_data): + # Interpret protobuf response packet from CtrlReset command + dec_resp = security_ctx.decrypt_data(str_to_bytes(response_data)) + resp = proto.wifi_ctrl_pb2.WiFiCtrlPayload() + resp.ParseFromString(dec_resp) + print_verbose(security_ctx, f'CtrlReset status: 0x{str(resp.status)}') + if resp.status != 0: + raise RuntimeError + + +def ctrl_reprov_request(security_ctx): + # Form protobuf request packet for CtrlReprov command + cmd = proto.wifi_ctrl_pb2.WiFiCtrlPayload() + cmd.msg = proto.wifi_ctrl_pb2.TypeCmdCtrlReprov + enc_cmd = security_ctx.encrypt_data(cmd.SerializeToString()) + print_verbose(security_ctx, f'Client -> Device (Encrypted CmdCtrlReset): 0x{enc_cmd.hex()}') + return enc_cmd.decode('latin-1') + + +def ctrl_reprov_response(security_ctx, response_data): + # Interpret protobuf response packet from CtrlReprov command + dec_resp = security_ctx.decrypt_data(str_to_bytes(response_data)) + resp = proto.wifi_ctrl_pb2.WiFiCtrlPayload() + resp.ParseFromString(dec_resp) + print_verbose(security_ctx, f'CtrlReset status: 0x{str(resp.status)}') + if resp.status != 0: + raise RuntimeError