From 0b13dbb216d2869db4b5523424df027a97ef9962 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Wed, 21 Aug 2024 16:04:44 +0800 Subject: [PATCH] esp_matter: Add thread border router management support and thread border router example --- SUPPORTED_DEVICE_TYPES.md | 3 + .../esp_matter/esp_matter_attribute.cpp | 42 +++++++ components/esp_matter/esp_matter_attribute.h | 11 ++ components/esp_matter/esp_matter_cluster.cpp | 47 +++++++ components/esp_matter/esp_matter_cluster.h | 9 ++ components/esp_matter/esp_matter_command.cpp | 36 ++++++ components/esp_matter/esp_matter_command.h | 10 ++ .../esp_matter_delegate_callbacks.cpp | 21 ++++ .../esp_matter_delegate_callbacks.h | 1 + components/esp_matter/esp_matter_endpoint.cpp | 34 +++++ components/esp_matter/esp_matter_endpoint.h | 16 +++ components/esp_matter/esp_matter_feature.cpp | 31 +++++ components/esp_matter/esp_matter_feature.h | 13 ++ .../private/esp_matter_cluster_revisions.h | 5 + components/esp_matter_console/CMakeLists.txt | 8 +- examples/.build-rules.yml | 6 + .../all_device_types_app/main/app_main.cpp | 29 +++-- .../all_device_types_app/main/device_types.h | 4 +- .../main/esp_matter_console_helpers.cpp | 25 ++++ .../partitions_thread.csv | 6 +- .../sdkconfig.defaults.otbr | 13 +- examples/controller/main/app_main.cpp | 2 +- examples/controller/sdkconfig.defaults.otbr | 3 - examples/thread_border_router/CMakeLists.txt | 38 ++++++ examples/thread_border_router/README.md | 47 +++++++ .../thread_border_router/main/CMakeLists.txt | 5 + .../thread_border_router/main/app_main.cpp | 119 ++++++++++++++++++ .../thread_border_router/main/esp_ot_config.h | 90 +++++++++++++ examples/thread_border_router/partitions.csv | 6 + .../thread_border_router/sdkconfig.defaults | 64 ++++++++++ 30 files changed, 717 insertions(+), 27 deletions(-) create mode 100644 examples/thread_border_router/CMakeLists.txt create mode 100644 examples/thread_border_router/README.md create mode 100644 examples/thread_border_router/main/CMakeLists.txt create mode 100644 examples/thread_border_router/main/app_main.cpp create mode 100644 examples/thread_border_router/main/esp_ot_config.h create mode 100644 examples/thread_border_router/partitions.csv create mode 100644 examples/thread_border_router/sdkconfig.defaults diff --git a/SUPPORTED_DEVICE_TYPES.md b/SUPPORTED_DEVICE_TYPES.md index bbb7ff795..b8a98923c 100644 --- a/SUPPORTED_DEVICE_TYPES.md +++ b/SUPPORTED_DEVICE_TYPES.md @@ -79,3 +79,6 @@ i. Appliances j. Energy 1. EVSE (Electric Vehicle Supply Equipment) + +k. Network Infrastructure +1. Thread Border Router diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 68e2f712c..6ba96f314 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -4705,5 +4705,47 @@ attribute_t *create_allowed_vendor_list(cluster_t *cluster, uint8_t *value, uint } /* attribute */ } /* application_basic */ +namespace thread_border_router_management { +namespace attribute { + +attribute_t *create_border_router_name(cluster_t *cluster, char *value, uint16_t length) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::BorderRouterName::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); +} + +attribute_t *create_border_agent_id(cluster_t *cluster, uint8_t *value, uint16_t length) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::BorderAgentID::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_octet_str(value, length)); +} + +attribute_t *create_thread_version(cluster_t *cluster, uint16_t value) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::ThreadVersion::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); +} + +attribute_t *create_interface_enabled(cluster_t *cluster, bool value) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::InterfaceEnabled::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_bool(value)); +} + +attribute_t *create_active_dataset_timestamp(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_nullable_uint64(value)); +} + +attribute_t *create_pending_dataset_timestamp(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, ThreadBorderRouterManagement::Attributes::PendingDatasetTimestamp::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_nullable_uint64(value)); +} + +} /* attribute */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 614e5d0d0..f02391309 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -1121,5 +1121,16 @@ attribute_t *create_allowed_vendor_list(cluster_t *cluster, uint8_t *value, uint } /* attribute */ } /* application_basic */ +namespace thread_border_router_management { +namespace attribute { +attribute_t *create_border_router_name(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_border_agent_id(cluster_t *cluster, uint8_t *value, uint16_t length); +attribute_t *create_thread_version(cluster_t *cluster, uint16_t value); +attribute_t *create_interface_enabled(cluster_t *cluster, bool value); +attribute_t *create_active_dataset_timestamp(cluster_t *cluster, nullable value); +attribute_t *create_pending_dataset_timestamp(cluster_t *cluster, nullable value); +} /* attribute */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index b728c5481..0aa9f0482 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -3545,6 +3545,53 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } } /* application_basic */ +namespace thread_border_router_management { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, ThreadBorderRouterManagement::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = ThreadBorderRouterManagementDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + static const auto plugin_server_init_cb = CALL_ONCE(MatterThreadBorderRouterManagementPluginServerInitCallback); + set_plugin_server_init_callback(cluster, plugin_server_init_cb); + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + attribute::create_border_router_name(cluster, nullptr, 0); + attribute::create_border_agent_id(cluster, nullptr, 0); + attribute::create_thread_version(cluster, 0); + attribute::create_interface_enabled(cluster, false); + nullable timestamp; + attribute::create_active_dataset_timestamp(cluster, timestamp); + + /** Attributes not managed internally **/ + global::attribute::create_cluster_revision(cluster, cluster_revision); + } + + command::create_get_active_dataset_request(cluster); + command::create_get_pending_dataset_request(cluster); + command::create_dataset_response(cluster); + command::create_set_active_dataset_request(cluster); + + if (features & feature::pan_change::get_id()) { + feature::pan_change::add(cluster); + } + + return cluster; +} + +} /* thread_border_router_management */ + // namespace binary_input_basic { // // ToDo // } /* binary_input_basic */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 38ad2d3af..9d5c96184 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -864,5 +864,14 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* application_basic */ +namespace thread_border_router_management { +typedef struct config { + void *delegate; + config() : delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index ba8fe2f5d..49f5ab391 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2858,6 +2858,42 @@ command_t *create_cancel_request(cluster_t *cluster) } /* command */ } /* device_energy_management */ +namespace thread_border_router_management { +namespace command { + +command_t *create_get_active_dataset_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_get_pending_dataset_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_dataset_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ThreadBorderRouterManagement::Commands::DatasetResponse::Id, + COMMAND_FLAG_GENERATED, NULL); +} + +command_t *create_set_active_dataset_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_set_pending_dataset_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 16cef8e46..fffb2f06a 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -417,5 +417,15 @@ command_t *create_cancel_request(cluster_t *cluster); } /* command */ } /* device_energy_management */ +namespace thread_border_router_management { +namespace command { +command_t *create_get_active_dataset_request(cluster_t *cluster); +command_t *create_get_pending_dataset_request(cluster_t *cluster); +command_t *create_dataset_response(cluster_t *cluster); +command_t *create_set_active_dataset_request(cluster_t *cluster); +command_t *create_set_pending_dataset_request(cluster_t *cluster); +} /* command */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index 360fcac24..1989951d8 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include using namespace chip::app::Clusters; namespace esp_matter { @@ -354,6 +356,25 @@ void ModeSelectDelegateInitCB(void *delegate, uint16_t endpoint_id) ModeSelect::setSupportedModesManager(supported_modes_manager); } +void ThreadBorderRouterManagementDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + assert(delegate != nullptr); + esp_matter::cluster_t *cluster = esp_matter::cluster::get(endpoint_id, ThreadBorderRouterManagement::Id); + assert(cluster != nullptr); + /* Get the attribute */ + attribute_t *attribute = attribute::get(cluster, Globals::Attributes::FeatureMap::Id); + assert(attribute != nullptr); + /* Update the value if the attribute already exists */ + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + attribute::get_val(attribute, &val); + bool pan_change_supported = (val.val.u32 & thread_border_router_management::feature::pan_change::get_id()) ? true : false; + ThreadBorderRouterManagement::Delegate *thread_br_delegate = static_cast(delegate); + assert(thread_br_delegate->GetPanChangeSupported() == pan_change_supported); + ThreadBorderRouterManagement::ServerInstance *server_instance = + chip::Platform::New(endpoint_id, thread_br_delegate, chip::Server::GetInstance().GetFailSafeContext()); + server_instance->Init(); +} + } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_delegate_callbacks.h b/components/esp_matter/esp_matter_delegate_callbacks.h index a4310cfe4..888837517 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.h +++ b/components/esp_matter/esp_matter_delegate_callbacks.h @@ -45,6 +45,7 @@ void WindowCoveringDelegateInitCB(void *delegate, uint16_t endpoint_id); void DishwasherAlarmDelegateInitCB(void *delegate, uint16_t endpoint_id); void KeypadInputDelegateInitCB(void *delegate, uint16_t endpoint_id); void ModeSelectDelegateInitCB(void *delegate, uint16_t endpoint_id); +void ThreadBorderRouterManagementDelegateInitCB(void *delegate, uint16_t endpoint_id); } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 4e469c0dd..a4521f9fd 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1885,6 +1885,40 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /** device_energy_management **/ +namespace thread_border_router { + +uint32_t get_device_type_id() +{ + return ESP_MATTER_THREAD_BORDER_ROUTER_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_THREAD_BORDER_ROUTER_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + return common::create(node, config, flags, priv_data, add); +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + VerifyOrReturnError(endpoint != nullptr, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL")); + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to add device type id:%" PRIu32 ",err: %d", get_device_type_id(), err); + return err; + } + + thread_network_diagnostics::create(endpoint, &(config->thread_network_diagnostics), CLUSTER_FLAG_SERVER); + thread_border_router_management::create(endpoint, &(config->thread_border_router_management), CLUSTER_FLAG_SERVER, + thread_border_router_management::feature::pan_change::get_id()); + return ESP_OK; +} + +} /* thread_border_router */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 43b972a91..e5b0c0efb 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -131,6 +131,9 @@ #define ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_DEVICE_TYPE_ID 0x050D #define ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_THREAD_BORDER_ROUTER_DEVICE_TYPE_ID 0x0091 +#define ESP_MATTER_THREAD_BORDER_ROUTER_DEVICE_TYPE_VERSION 1 + namespace esp_matter { /** Specific endpoint (device type) create APIs @@ -853,6 +856,19 @@ endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_dat esp_err_t add(endpoint_t *endpoint, config_t *config); } /* device_energy_management */ +namespace thread_border_router { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::thread_network_diagnostics::config_t thread_network_diagnostics; + cluster::thread_border_router_management::config_t thread_border_router_management; +} config_t; + +uint32_t get_device_type_id(); +uint8_t get_device_type_version(); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +esp_err_t add(endpoint_t *endpoint, config_t *config); +} /* thread_border_router */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 004fd5dc2..6add4c96b 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -4752,5 +4752,36 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* device_energy_management */ +namespace thread_border_router_management { +namespace feature { + +namespace pan_change { + +uint32_t get_id() +{ + return static_cast(ThreadBorderRouterManagement::Feature::kPANChange); +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + /* attribute */ + nullable timestamp; + attribute::create_pending_dataset_timestamp(cluster, timestamp); + + /* command */ + command::create_set_pending_dataset_request(cluster); + return ESP_OK; +} + +} /* pan_change */ + +} /* feature */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index e331a9b08..bc829c01e 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -2084,5 +2084,18 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* device_energy_management */ +namespace thread_border_router_management { +namespace feature { + +namespace pan_change { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* pan_change */ + +} /* feature */ +} /* thread_border_router_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/private/esp_matter_cluster_revisions.h b/components/esp_matter/private/esp_matter_cluster_revisions.h index 52414564b..9d7c1e4d6 100644 --- a/components/esp_matter/private/esp_matter_cluster_revisions.h +++ b/components/esp_matter/private/esp_matter_cluster_revisions.h @@ -367,6 +367,11 @@ namespace application_basic { constexpr uint16_t cluster_revision = 1; } // namespace application_basic +namespace thread_border_router_management { +constexpr uint16_t cluster_revision = 1; +} // namespace thread_border_router_management + + } // namespace cluster } // namespace esp_matter diff --git a/components/esp_matter_console/CMakeLists.txt b/components/esp_matter_console/CMakeLists.txt index 6555e6a32..bbfad816e 100644 --- a/components/esp_matter_console/CMakeLists.txt +++ b/components/esp_matter_console/CMakeLists.txt @@ -2,6 +2,12 @@ set(src_dirs) if (CONFIG_ENABLE_CHIP_SHELL) list(APPEND src_dirs ".") endif() + +set(priv_req chip mbedtls esp_timer bt openthread) +if ("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0") + list(APPEND priv_req esp_rcp_update) +endif() + idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS . - PRIV_REQUIRES chip mbedtls esp_timer bt openthread esp_rcp_update) + PRIV_REQUIRES ${priv_req}) diff --git a/examples/.build-rules.yml b/examples/.build-rules.yml index 12ccdb6ce..3932b7c9a 100644 --- a/examples/.build-rules.yml +++ b/examples/.build-rules.yml @@ -116,3 +116,9 @@ examples/light_wifi_prov: - if: IDF_TARGET in ["esp32s3", "esp32c3"] temporary: true reason: the other targets are not tested yet + +examples/thread_border_router: + enable: + - if: IDF_TARGET in ["esp32s3"] + temporary: true + reason: the other targets are not tested yet diff --git a/examples/all_device_types_app/main/app_main.cpp b/examples/all_device_types_app/main/app_main.cpp index dbfa52704..add9c41dd 100644 --- a/examples/all_device_types_app/main/app_main.cpp +++ b/examples/all_device_types_app/main/app_main.cpp @@ -30,12 +30,10 @@ #include #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include +#include +#include +#include #endif -#if CONFIG_OPENTHREAD_BORDER_ROUTER -#include -#include -#endif // CONFIG_OPENTHREAD_BORDER_ROUTER - static const char *TAG = "app_main"; @@ -121,14 +119,15 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) case chip::DeviceLayer::DeviceEventType::kESPSystemEvent: if (event->Platform.ESPSystemEvent.Base == IP_EVENT && event->Platform.ESPSystemEvent.Id == IP_EVENT_STA_GOT_IP) { -#if CONFIG_OPENTHREAD_BORDER_ROUTER - esp_openthread_platform_config_t config = { - .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), - .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), - .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), - }; - ESP_LOGI(TAG, "init thread br"); - esp_matter::thread_br_init(&config); +#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER + static bool sThreadBRInitialized = false; + if (!sThreadBRInitialized) { + esp_openthread_set_backbone_netif(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); + esp_openthread_lock_acquire(portMAX_DELAY); + esp_openthread_border_router_init(); + esp_openthread_lock_release(); + sThreadBRInitialized = true; + } #endif } break; @@ -218,8 +217,8 @@ extern "C" void app_main() esp_matter::console::diagnostics_register_commands(); esp_matter::console::wifi_register_commands(); esp_matter::console::init(); -#if CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_OPENTHREAD_CLI - esp_matter::console::thread_br_cli_register_command(); +#ifdef CONFIG_OPENTHREAD_CLI + esp_matter::console::otcli_register_commands(); #endif // CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_OPENTHREAD_CLI #endif diff --git a/examples/all_device_types_app/main/device_types.h b/examples/all_device_types_app/main/device_types.h index 5f2899805..e0493260c 100644 --- a/examples/all_device_types_app/main/device_types.h +++ b/examples/all_device_types_app/main/device_types.h @@ -52,6 +52,7 @@ enum device_type_enum { ESP_MATTER_WATER_VALVE, ESP_MATTER_DEVICE_ENERGY_MANAGEMENT, ESP_MATTER_PUMP_CONTROLLER, + ESP_MATTER_THREAD_BORDER_ROUTER, ESP_MATTER_DEVICE_TYPE_MAX }; @@ -109,6 +110,7 @@ const device_type_name device_type_list[ESP_MATTER_DEVICE_TYPE_MAX] = { {"laundry_dryer", ESP_MATTER_LAUNDRY_DRYER}, {"water_valve", ESP_MATTER_WATER_VALVE}, {"device_energy_management", ESP_MATTER_DEVICE_ENERGY_MANAGEMENT}, - {"pump_controller", ESP_MATTER_PUMP_CONTROLLER} + {"pump_controller", ESP_MATTER_PUMP_CONTROLLER}, + {"thread_border_router", ESP_MATTER_THREAD_BORDER_ROUTER}, }; } /* namespace esp_matter */ diff --git a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp index cb831e55d..4a25d333b 100644 --- a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp +++ b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp @@ -29,6 +29,13 @@ #include #include +#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER +#include +#include +using chip::app::Clusters::ThreadBorderRouterManagement::GenericOpenThreadBorderRouterDelegate; +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER + + using namespace esp_matter; extern uint16_t app_endpoint_id; @@ -494,6 +501,24 @@ int create(uint8_t device_type_index) endpoint = esp_matter::endpoint::pump_controller::create(node, &pump_controller_config, ENDPOINT_FLAG_NONE, NULL); break; } +#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER + case ESP_MATTER_THREAD_BORDER_ROUTER: { + static chip::KvsPersistentStorageDelegate tbr_storage_delegate; + chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr(); + tbr_storage_delegate.Init(&kvsManager); + GenericOpenThreadBorderRouterDelegate *delegate = chip::Platform::New(&tbr_storage_delegate); + if (!delegate) { + ESP_LOGE(TAG, "Failed to create thread_border_router delegate"); + return 1; + } + char threadBRName[] = "Espressif-ThreadBR"; + delegate->SetThreadBorderRouterName(chip::CharSpan(threadBRName)); + esp_matter::endpoint::thread_border_router::config_t tbr_config; + tbr_config.thread_border_router_management.delegate = delegate; + endpoint = esp_matter::endpoint::thread_border_router::create(node, &tbr_config, ENDPOINT_FLAG_NONE, NULL); + break; + } +#endif default: { ESP_LOGE(TAG, "Please input a valid device type"); break; diff --git a/examples/all_device_types_app/partitions_thread.csv b/examples/all_device_types_app/partitions_thread.csv index e5f11bdd4..40b0afb0f 100644 --- a/examples/all_device_types_app/partitions_thread.csv +++ b/examples/all_device_types_app/partitions_thread.csv @@ -5,7 +5,5 @@ nvs, data, nvs, 0x10000, 0x6000, nvs_keys, data, nvs_keys, , 0x1000, encrypted otadata, data, ota, , 0x2000 phy_init, data, phy, , 0x1000, -ota_0, app, ota_0, , 0x1C0000, -ota_1, app, ota_1, , 0x1C0000, -# For Wi-Fi device, this partition can be deleted. -ot_storage,data, fat, , 0x2000, +ota_0, app, ota_0, , 1920K, +ota_1, app, ota_1, , 1920K, diff --git a/examples/all_device_types_app/sdkconfig.defaults.otbr b/examples/all_device_types_app/sdkconfig.defaults.otbr index ad74bff3b..5c3555e07 100644 --- a/examples/all_device_types_app/sdkconfig.defaults.otbr +++ b/examples/all_device_types_app/sdkconfig.defaults.otbr @@ -2,12 +2,17 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_thread.csv" + # Enable Openthread Border Router, but don't run matter over Thread CONFIG_OPENTHREAD_ENABLED=y CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n -CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y +CONFIG_OPENTHREAD_LOG_LEVEL_WARN=y CONFIG_OPENTHREAD_BORDER_ROUTER=y -CONFIG_ENABLE_MATTER_OVER_THREAD=n +CONFIG_OPENTHREAD_SRP_CLIENT=n +CONFIG_OPENTHREAD_DNS_CLIENT=n +CONFIG_THREAD_NETWORK_COMMISSIONING_DRIVER=n #enable BT CONFIG_BT_ENABLED=y @@ -74,3 +79,7 @@ CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_ENABLE_OTA_REQUESTOR=n CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=y + +# Flash optimization +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_NEWLIB_NANO_FORMAT=y diff --git a/examples/controller/main/app_main.cpp b/examples/controller/main/app_main.cpp index 0b3802627..a074ecc90 100644 --- a/examples/controller/main/app_main.cpp +++ b/examples/controller/main/app_main.cpp @@ -80,13 +80,13 @@ extern "C" void app_main() #endif // CONFIG_OPENTHREAD_BORDER_ROUTER #endif // CONFIG_ENABLE_CHIP_SHELL #ifdef CONFIG_OPENTHREAD_BORDER_ROUTER +#ifdef CONFIG_AUTO_UPDATE_RCP esp_vfs_spiffs_conf_t rcp_fw_conf = { .base_path = "/rcp_fw", .partition_label = "rcp_fw", .max_files = 10, .format_if_mount_failed = false}; if (ESP_OK != esp_vfs_spiffs_register(&rcp_fw_conf)) { ESP_LOGE(TAG, "Failed to mount rcp firmware storage"); return; } -#ifdef CONFIG_AUTO_UPDATE_RCP esp_rcp_update_config_t rcp_update_config = ESP_OPENTHREAD_RCP_UPDATE_CONFIG(); openthread_init_br_rcp(&rcp_update_config); #endif diff --git a/examples/controller/sdkconfig.defaults.otbr b/examples/controller/sdkconfig.defaults.otbr index 0aca1f6d4..7b7334803 100644 --- a/examples/controller/sdkconfig.defaults.otbr +++ b/examples/controller/sdkconfig.defaults.otbr @@ -11,9 +11,6 @@ CONFIG_OPENTHREAD_SRP_CLIENT=n CONFIG_OPENTHREAD_DNS_CLIENT=n CONFIG_THREAD_TASK_STACK_SIZE=8192 -# Auto update RCP firmware -CONFIG_AUTO_UPDATE_RCP=y - #enable BT CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/thread_border_router/CMakeLists.txt b/examples/thread_border_router/CMakeLists.txt new file mode 100644 index 000000000..3a1f2cc6b --- /dev/null +++ b/examples/thread_border_router/CMakeLists.txt @@ -0,0 +1,38 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +if(NOT DEFINED ENV{ESP_MATTER_PATH}) + message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo") +endif(NOT DEFINED ENV{ESP_MATTER_PATH}) + +if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH}) + if("${IDF_TARGET}" STREQUAL "esp32s3") + set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32s3_devkit_c) + else() + message(FATAL_ERROR "Unsupported IDF_TARGET") + endif() +endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH}) + +set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH}) +set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip) + +# This should be done before using the IDF_TARGET variable. +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake) + +set(EXTRA_COMPONENT_DIRS + "../common" + "${MATTER_SDK_PATH}/config/esp32/components" + "${ESP_MATTER_PATH}/components" + "${ESP_MATTER_PATH}/device_hal/device" + ${extra_components_dirs_append}) + +project(thread_border_router) + +idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND) +idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND) + +# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various +# flags that depend on -Wformat +idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND) diff --git a/examples/thread_border_router/README.md b/examples/thread_border_router/README.md new file mode 100644 index 000000000..ffc1368a3 --- /dev/null +++ b/examples/thread_border_router/README.md @@ -0,0 +1,47 @@ +# Thread Border Router + +This example creates a Matter Thread Border Router device using the ESP Matter data model. + + +See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware. + +## 1. Additional Environment Setup + +### 1.1 Hardware Platform + +The [ESP Thread Border Router board](https://github.com/espressif/esp-thread-br?tab=readme-ov-file#esp-thread-border-router-board) which provides an integrated module of an ESP32-S3 and an ESP32-H2 is required for this example. + +### 1.2 Firmware for RCP + +The [OpenThread RCP](https://github.com/espressif/esp-idf/tree/master/examples/openthread/ot_rcp) should be run on ESP32-H2 of the Border Router board. You can flash it directly: + + +``` +$ cd /path/to/esp-idf/examples/openthread/ot_rcp +$ idf.py set-target esp32h2 build +$ idf.py -p erase-flash flash +``` + +Or you can flash the firmware of ESP32-H2 with [esp_rcp_update](https://github.com/espressif/esp-thread-br/tree/main/components/esp_rcp_update) after enabling `AUTO_UPDATE_RCP` in menuconfig: + +``` +$ cd /path/to/esp-idf/examples/openthread/ot_rcp +$ idf.py set-target esp32h2 build +``` + +After flashing the Thread Border Router firmware to ESP32-S3, it will flash the RCP firmware to ESP32-H2 automatically. + +## 2. Post Commissioning Setup + +After commissioning the Border Router with chip-tool, you can set up the Thread network with ThreadBorderRouterManagement cluster. + +``` +$ ./chip-tool generalcommissioning arm-fail-safe 180 1 0x7283 0 +$ ./chip-tool threadborderroutermanagement set-active-dataset-request hex: 0x7283 1 +$ ./chip-tool generalcommissioning commissioning-complete 0x7283 0 +``` +Then the Thread Border Router will form/join a Thread network and you can commission a Thread End-device to the Thread network with chip-tool. + +``` +$ ./chip-tool pairing ble-thread 0x7384 hex: 20202021 3840 +``` diff --git a/examples/thread_border_router/main/CMakeLists.txt b/examples/thread_border_router/main/CMakeLists.txt new file mode 100644 index 000000000..6b91a8cf5 --- /dev/null +++ b/examples/thread_border_router/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS ".") + +set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) +target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") diff --git a/examples/thread_border_router/main/app_main.cpp b/examples/thread_border_router/main/app_main.cpp new file mode 100644 index 000000000..bf7a1756c --- /dev/null +++ b/examples/thread_border_router/main/app_main.cpp @@ -0,0 +1,119 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +static const char *TAG = "app_main"; + +using namespace esp_matter; +using namespace esp_matter::attribute; +using namespace esp_matter::endpoint; +using namespace chip::app::Clusters; +using chip::app::Clusters::ThreadBorderRouterManagement::GenericOpenThreadBorderRouterDelegate; + +static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) +{ + switch (event->Type) { + case chip::DeviceLayer::DeviceEventType::PublicEventTypes::kInterfaceIpAddressChanged: + ESP_LOGI(TAG, "Interface IP Address changed"); + break; + case chip::DeviceLayer::DeviceEventType::kESPSystemEvent: + if (event->Platform.ESPSystemEvent.Base == IP_EVENT && + event->Platform.ESPSystemEvent.Id == IP_EVENT_STA_GOT_IP) { +#if CONFIG_OPENTHREAD_BORDER_ROUTER + static bool sThreadBRInitialized = false; + if (!sThreadBRInitialized) { + esp_openthread_set_backbone_netif(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); + esp_openthread_lock_acquire(portMAX_DELAY); + esp_openthread_border_router_init(); + esp_openthread_lock_release(); + sThreadBRInitialized = true; + } +#endif + } + break; + default: + break; + } +} + +extern "C" void app_main() +{ + esp_err_t err = ESP_OK; + + /* Initialize the ESP NVS layer */ + nvs_flash_init(); + // If there is no commissioner in the controller, we need a default node so that the controller can be commissioned + // to a specific fabric. + node::config_t node_config; + node_t *node = node::create(&node_config, NULL, NULL); + static chip::KvsPersistentStorageDelegate tbr_storage_delegate; + chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr(); + tbr_storage_delegate.Init(&kvsManager); + GenericOpenThreadBorderRouterDelegate *delegate = chip::Platform::New(&tbr_storage_delegate); + char threadBRName[] = "Espressif-ThreadBR"; + delegate->SetThreadBorderRouterName(chip::CharSpan(threadBRName)); + if (!delegate) { + ESP_LOGE(TAG, "Failed to create thread_border_router delegate"); + return; + } + thread_border_router::config_t tbr_config; + tbr_config.thread_border_router_management.delegate = delegate; + endpoint_t *tbr_endpoint = thread_border_router::create(node, &tbr_config, ENDPOINT_FLAG_NONE, NULL); + if (!node || !tbr_endpoint) { + ESP_LOGE(TAG, "Failed to create data model"); + return; + } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if defined(CONFIG_OPENTHREAD_BORDER_ROUTER) && defined(CONFIG_AUTO_UPDATE_RCP) + esp_vfs_spiffs_conf_t rcp_fw_conf = { + .base_path = "/rcp_fw", .partition_label = "rcp_fw", .max_files = 10, .format_if_mount_failed = false}; + if (ESP_OK != esp_vfs_spiffs_register(&rcp_fw_conf)) { + ESP_LOGE(TAG, "Failed to mount rcp firmware storage"); + return; + } + esp_rcp_update_config_t rcp_update_config = ESP_OPENTHREAD_RCP_UPDATE_CONFIG(); + openthread_init_br_rcp(&rcp_update_config); +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_AUTO_UPDATE_RCP + /* Set OpenThread platform config */ + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + set_openthread_platform_config(&config); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + + /* Matter start */ + err = esp_matter::start(app_event_cb); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Matter start failed: %d", err); + } +#if CONFIG_ENABLE_CHIP_SHELL + esp_matter::console::diagnostics_register_commands(); + esp_matter::console::wifi_register_commands(); + esp_matter::console::init(); +#endif // CONFIG_ENABLE_CHIP_SHELL +} diff --git a/examples/thread_border_router/main/esp_ot_config.h b/examples/thread_border_router/main/esp_ot_config.h new file mode 100644 index 000000000..e73f8cf96 --- /dev/null +++ b/examples/thread_border_router/main/esp_ot_config.h @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Border Router Example + * + * This example code is in the Public Domain (or CC0 licensed, at your option.) + * + * Unless required by applicable law or agreed to in writing, this + * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. + */ + +#pragma once + +#include "sdkconfig.h" +#if CONFIG_OPENTHREAD_BORDER_ROUTER +#include "esp_openthread_types.h" +#include + +#if CONFIG_OPENTHREAD_RADIO_NATIVE +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } +#elif CONFIG_OPENTHREAD_RADIO_SPINEL_UART +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_UART_RCP, \ + .radio_uart_config = { \ + .port = UART_NUM_1, \ + .uart_config = \ + { \ + .baud_rate = 460800, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + .rx_pin = GPIO_NUM_17, \ + .tx_pin = GPIO_NUM_18, \ + }, \ + } +#else +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_SPI_RCP, \ + .radio_spi_config = { \ + .host_device = SPI2_HOST, \ + .dma_channel = 2, \ + .spi_interface = \ + { \ + .mosi_io_num = 11, \ + .sclk_io_num = 12, \ + .miso_io_num = 13, \ + }, \ + .spi_device = \ + { \ + .cs_ena_pretrans = 2, \ + .input_delay_ns = 100, \ + .mode = 0, \ + .clock_speed_hz = 2500 * 1000, \ + .spics_io_num = 10, \ + .queue_size = 5, \ + }, \ + .intr_pin = 8, \ + }, \ + } +#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI + +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_NONE, \ + } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \ + } + +#define ESP_OPENTHREAD_RCP_UPDATE_CONFIG() \ + { \ + .rcp_type = RCP_TYPE_ESP32H2_UART, .uart_rx_pin = 17, .uart_tx_pin = 18, .uart_port = 1, .uart_baudrate = 115200, \ + .reset_pin = 7, .boot_pin = 8, .update_baudrate = 460800, .firmware_dir = "/rcp_fw/ot_rcp", .target_chip = ESP32H2_CHIP, \ + } + +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER diff --git a/examples/thread_border_router/partitions.csv b/examples/thread_border_router/partitions.csv new file mode 100644 index 000000000..3d4e1b22f --- /dev/null +++ b/examples/thread_border_router/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 3000K, +rcp_fw, data, spiffs, , 600K, diff --git a/examples/thread_border_router/sdkconfig.defaults b/examples/thread_border_router/sdkconfig.defaults new file mode 100644 index 000000000..a026d3008 --- /dev/null +++ b/examples/thread_border_router/sdkconfig.defaults @@ -0,0 +1,64 @@ +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +# Increase some stack size +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=7200 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=7200 +CONFIG_ESP_TIMER_TASK_STACK_SIZE=5120 +CONFIG_THREAD_TASK_STACK_SIZE=8192 +CONFIG_CHIP_TASK_STACK_SIZE=10240 + +# partition table +CONFIG_PARTITION_TABLE_CUSTOM=y + +# USB console for Thread border board +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y + +# Disable SoftAP +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n + +# LWIP +CONFIG_LWIP_IPV6_FORWARD=y +CONFIG_LWIP_IPV6_AUTOCONFIG=y +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_NETIF_STATUS_CALLBACK=y +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y +CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM=y +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM=y + +# ESP Border Router will also enable a route hook so we don't need the route hook in matter +CONFIG_ENABLE_ROUTE_HOOK=n + +# mbedTLS +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_ECJPAKE_C=y +CONFIG_MBEDTLS_HKDF_C=y + +# OpenThread +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n +CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y +CONFIG_OPENTHREAD_SRP_CLIENT=n +CONFIG_OPENTHREAD_DNS_CLIENT=n +CONFIG_OPENTHREAD_BORDER_ROUTER=y +CONFIG_THREAD_NETWORK_COMMISSIONING_DRIVER=n + +# Use platform mDNS +CONFIG_USE_MINIMAL_MDNS=n + +# Enable Matter shell +CONFIG_ENABLE_CHIP_SHELL=y +CONFIG_ESP_MATTER_CONSOLE_TASK_STACK=4096