From fd033440c7a9147f45800eb9d2e7e4c9e258e46a Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Fri, 3 Nov 2023 15:25:44 +0800 Subject: [PATCH] thread_br: Add esp_matter_thread_br component controller: Run openthread border router with the controller Remove custom thread_br cluster --- .../esp_matter_thread_br/CMakeLists.txt | 12 + .../esp_matter_thread_br_console.cpp | 50 ++++ .../esp_matter_thread_br_console.h | 24 ++ .../esp_matter_thread_br_launcher.cpp | 215 ++++++++++++++++++ .../esp_matter_thread_br_launcher.h | 39 ++++ examples/controller/README.md | 67 +++++- examples/controller/main/CMakeLists.txt | 8 +- examples/controller/main/app_main.cpp | 63 +++-- examples/controller/main/esp_ot_config.h | 84 +++++++ examples/controller/partitions_br.csv | 5 + examples/controller/sdkconfig.defaults.otbr | 73 ++++++ 11 files changed, 618 insertions(+), 22 deletions(-) create mode 100644 components/esp_matter_thread_br/CMakeLists.txt create mode 100644 components/esp_matter_thread_br/esp_matter_thread_br_console.cpp create mode 100644 components/esp_matter_thread_br/esp_matter_thread_br_console.h create mode 100644 components/esp_matter_thread_br/esp_matter_thread_br_launcher.cpp create mode 100644 components/esp_matter_thread_br/esp_matter_thread_br_launcher.h create mode 100644 examples/controller/main/esp_ot_config.h create mode 100644 examples/controller/partitions_br.csv create mode 100644 examples/controller/sdkconfig.defaults.otbr diff --git a/components/esp_matter_thread_br/CMakeLists.txt b/components/esp_matter_thread_br/CMakeLists.txt new file mode 100644 index 000000000..243e29500 --- /dev/null +++ b/components/esp_matter_thread_br/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SRCS_LIST ) + +if (CONFIG_OPENTHREAD_BORDER_ROUTER) + list(APPEND SRCS_LIST "esp_matter_thread_br_launcher.cpp") +if (CONFIG_ENABLE_CHIP_SHELL AND CONFIG_OPENTHREAD_CLI) + list(APPEND SRCS_LIST "esp_matter_thread_br_console.cpp") +endif() +endif() + +idf_component_register(SRCS ${SRCS_LIST} + INCLUDE_DIRS "." + REQUIRES esp_matter openthread esp_netif vfs) diff --git a/components/esp_matter_thread_br/esp_matter_thread_br_console.cpp b/components/esp_matter_thread_br/esp_matter_thread_br_console.cpp new file mode 100644 index 000000000..0242f9726 --- /dev/null +++ b/components/esp_matter_thread_br/esp_matter_thread_br_console.cpp @@ -0,0 +1,50 @@ +// Copyright 2023 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. + +#include +#include + +namespace esp_matter { +namespace console { + +static esp_err_t thread_br_cli_handler(int argc, char **argv) +{ + ot_cli_buffer_t cli_buf; + memset(&cli_buf, 0, sizeof(cli_buf)); + for (size_t i = 0; i < argc; ++i) { + cli_buf.buf_len += strlen(argv[i]) + (i == argc - 1 ? 0 : 1); + if (cli_buf.buf_len > OPENTHREAD_CLI_BUFFER_LENGTH) { + return ESP_ERR_INVALID_ARG; + } + strcat(cli_buf.buf, argv[i]); + if (i < argc - 1) { + strcat(cli_buf.buf, " "); + } + } + return cli_transmit_task_post(cli_buf); +} + +esp_err_t thread_br_cli_register_command() +{ + static const command_t command = { + .name = "ot_cli", + .description = "OpenThread Cli commands. Usage: matter esp ot_cli .", + .handler = thread_br_cli_handler, + }; + + return add_commands(&command, 1); +} + +} // namespace console +} // namespace esp_matter diff --git a/components/esp_matter_thread_br/esp_matter_thread_br_console.h b/components/esp_matter_thread_br/esp_matter_thread_br_console.h new file mode 100644 index 000000000..a25ce2f6f --- /dev/null +++ b/components/esp_matter_thread_br/esp_matter_thread_br_console.h @@ -0,0 +1,24 @@ +// Copyright 2023 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. + +#pragma once +#include + +namespace esp_matter { +namespace console { + +esp_err_t thread_br_cli_register_command(); + +} // namespace console +} // namespace esp_matter diff --git a/components/esp_matter_thread_br/esp_matter_thread_br_launcher.cpp b/components/esp_matter_thread_br/esp_matter_thread_br_launcher.cpp new file mode 100644 index 000000000..d0a58ec09 --- /dev/null +++ b/components/esp_matter_thread_br/esp_matter_thread_br_launcher.cpp @@ -0,0 +1,215 @@ +// Copyright 2023 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. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TAG "thread_br_launcher" + +namespace esp_matter { + +class scoped_thread_lock { +public: + scoped_thread_lock() { esp_openthread_lock_acquire(portMAX_DELAY); } + ~scoped_thread_lock() { esp_openthread_lock_release(); } +}; + +#if CONFIG_OPENTHREAD_CLI +static TaskHandle_t cli_transmit_task = NULL; +static QueueHandle_t cli_transmit_task_queue = NULL; + +static int cli_output_callback(void *context, const char *format, va_list args) +{ + int ret = 0; + char prompt_check[3]; + vsnprintf(prompt_check, sizeof(prompt_check), format, args); + if (!strncmp(prompt_check, "> ", sizeof(prompt_check))) { + if (cli_transmit_task) { + xTaskNotifyGive(cli_transmit_task); + } + } else { + ret = vprintf(format, args); + } + return ret; +} + +static void cli_transmit_worker(void *context) +{ + cli_transmit_task_queue = xQueueCreate(4, sizeof(ot_cli_buffer_t)); + if (!cli_transmit_task_queue) { + vTaskDelete(NULL); + return; + } + while (true) { + ot_cli_buffer_t buffer; + if (xQueueReceive(cli_transmit_task_queue, &buffer, portMAX_DELAY) == pdTRUE) { + esp_openthread_cli_input(buffer.buf); + xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); + } + } +} + +esp_err_t cli_transmit_task_post(ot_cli_buffer_t &cli_buf) +{ + if (!cli_transmit_task_queue || xQueueSend(cli_transmit_task_queue, &cli_buf, portMAX_DELAY) != pdTRUE) { + return ESP_FAIL; + } + return ESP_OK; +} +#endif // CONFIG_OPENTHREAD_CLI + +static void ot_task_worker(void *aContext) +{ + esp_openthread_platform_config_t *config = static_cast(aContext); + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); + esp_netif_t *openthread_netif = esp_netif_new(&cfg); + assert(openthread_netif != NULL); + + // Initialize the OpenThread stack + ESP_ERROR_CHECK(esp_openthread_init(config)); +#if CONFIG_OPENTHREAD_CLI + otCliInit(esp_openthread_get_instance(), cli_output_callback, NULL); +#endif + // Initialize border routing features + esp_openthread_lock_acquire(portMAX_DELAY); + ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(config))); + ESP_ERROR_CHECK(esp_openthread_border_router_init()); +#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC + (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); +#endif + otInstance *instance = esp_openthread_get_instance(); + if (otDatasetIsCommissioned(instance)) { + (void)otIp6SetEnabled(instance, true); + (void)otThreadSetEnabled(instance, true); + } + esp_openthread_lock_release(); + free(config); + +#if CONFIG_OPENTHREAD_CLI + xTaskCreate(cli_transmit_worker, "ot_cli_task", 3072, NULL, 5, &cli_transmit_task); +#endif + esp_openthread_launch_mainloop(); + // Clean up + esp_netif_destroy(openthread_netif); + esp_openthread_netif_glue_deinit(); + esp_vfs_eventfd_unregister(); + vTaskDelete(NULL); +} + +esp_err_t thread_br_init(esp_openthread_platform_config_t *config) +{ + static bool thread_br_initialized = false; + if (thread_br_initialized) { + return ESP_OK; + } + // Used eventfds: + // * netif + // * task_queue + // * border router + esp_vfs_eventfd_config_t eventfd_config = { +#if CONFIG_OPENTHREAD_RADIO_NATIVE + // * radio driver + .max_fds = 4, +#else + .max_fds = 3, +#endif + }; + ESP_RETURN_ON_ERROR(esp_vfs_eventfd_register(&eventfd_config), TAG, "Failed to register eventfd"); + esp_openthread_set_backbone_netif(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); + + esp_openthread_platform_config_t *config_copy = + (esp_openthread_platform_config_t *)malloc(sizeof(esp_openthread_platform_config_t)); + if (!config_copy) { + ESP_LOGE(TAG, "Failed to allocate memory for openthread_platform_config"); + return ESP_ERR_NO_MEM; + } + memcpy(config_copy, config, sizeof(esp_openthread_platform_config_t)); + if (xTaskCreate(ot_task_worker, "ot_br", 8192, config_copy, 5, NULL) != pdTRUE) { + free(config_copy); + return ESP_FAIL; + } + + thread_br_initialized = true; + return ESP_OK; +} + +esp_err_t set_thread_enabled(bool enabled) +{ + scoped_thread_lock lock; + otInstance *instance = esp_openthread_get_instance(); + if (!instance) { + ESP_LOGE(TAG, "Thread not initialized"); + return ESP_ERR_INVALID_STATE; + } + bool is_enabled = (otThreadGetDeviceRole(instance) != OT_DEVICE_ROLE_DISABLED); + bool is_ip6_enabled = otIp6IsEnabled(instance); + + if (enabled && !is_ip6_enabled) { + ESP_RETURN_ON_FALSE(otIp6SetEnabled(instance, enabled) == OT_ERROR_NONE, ESP_FAIL, TAG, "Failed to %s netif", + enabled ? "enable" : "disable"); + } + if (enabled != is_enabled) { + ESP_RETURN_ON_FALSE(otThreadSetEnabled(instance, enabled) == OT_ERROR_NONE, ESP_FAIL, TAG, + "Failed to %s thread", enabled ? "enable" : "disable"); + } + if (!enabled && is_ip6_enabled) { + ESP_RETURN_ON_FALSE(otIp6SetEnabled(instance, enabled) == OT_ERROR_NONE, ESP_FAIL, TAG, "Failed to %s netif", + enabled ? "enable" : "disable"); + } + return ESP_OK; +} + +esp_err_t set_thread_dataset_tlvs(otOperationalDatasetTlvs *dataset_tlvs) +{ + if (!dataset_tlvs) { + return ESP_ERR_INVALID_ARG; + } + scoped_thread_lock lock; + ESP_RETURN_ON_FALSE(otDatasetSetActiveTlvs(esp_openthread_get_instance(), dataset_tlvs) == OT_ERROR_NONE, ESP_FAIL, + TAG, "Failed to set Thread DatasetTlvs"); + return ESP_OK; +} + +esp_err_t get_thread_dataset_tlvs(otOperationalDatasetTlvs *dataset_tlvs) +{ + if (!dataset_tlvs) { + return ESP_ERR_INVALID_ARG; + } + scoped_thread_lock lock; + ESP_RETURN_ON_FALSE(otDatasetGetActiveTlvs(esp_openthread_get_instance(), dataset_tlvs) == OT_ERROR_NONE, ESP_FAIL, + TAG, "Failed to get Thread DatasetTlvs"); + return ESP_OK; +} + +uint8_t get_thread_role() +{ + scoped_thread_lock lock; + otDeviceRole role = otThreadGetDeviceRole(esp_openthread_get_instance()); + return role; +} + +} // namespace esp_matter diff --git a/components/esp_matter_thread_br/esp_matter_thread_br_launcher.h b/components/esp_matter_thread_br/esp_matter_thread_br_launcher.h new file mode 100644 index 000000000..da2c8124f --- /dev/null +++ b/components/esp_matter_thread_br/esp_matter_thread_br_launcher.h @@ -0,0 +1,39 @@ +// Copyright 2023 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. + +#pragma once + +#include + +#define OPENTHREAD_CLI_BUFFER_LENGTH 255 + +namespace esp_matter { + +typedef struct { + char buf[OPENTHREAD_CLI_BUFFER_LENGTH + 1]; + uint8_t buf_len; +} ot_cli_buffer_t; + +esp_err_t thread_br_init(esp_openthread_platform_config_t *config); + +esp_err_t set_thread_enabled(bool enabled); + +esp_err_t set_thread_dataset_tlvs(otOperationalDatasetTlvs *dataset_tlvs); + +esp_err_t get_thread_dataset_tlvs(otOperationalDatasetTlvs *dataset_tlvs); + +uint8_t get_thread_role(); + +esp_err_t cli_transmit_task_post(ot_cli_buffer_t &cli_buf); +} diff --git a/examples/controller/README.md b/examples/controller/README.md index ad6d7601d..50184c049 100644 --- a/examples/controller/README.md +++ b/examples/controller/README.md @@ -16,11 +16,70 @@ about pairing and controling an end-device using this example ## 3. Controller in Rainmaker Fabric -Matter Controller in Rainmaker Fabric will be soon avaliable in [Rainmaker Matter Examples](https://github.com/espressif/esp-rainmaker/tree/master/examples/matter) +Matter Controller in Rainmaker Fabric is avaliable in [Rainmaker Matter Examples](https://github.com/espressif/esp-rainmaker/tree/master/examples/matter) -## A2 Appendix FAQs +## 4. OpenThread Border Router (OTBR) feature -### A2.1 Pairing Command Failed +### 4.1 Hardware Platform + +See the [docs](https://github.com/espressif/esp-thread-br#hardware-platforms) for more information about the hardware platform. + +### 4.2 Build + +The sdkconfig file `sdkconfig.defaults.otbr` is provided to enable the OTBR feature on the controller. +Build and flash the controller example with the sdkconfig file 'sdkconfig.defaults.otbr' + +``` +idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.otbr" set-target esp32s3 build +idf.py -p erase-flash flash monitor +``` + +*Notes*: The Thread Border Router DevKit Board uses USB port. + +### 4.3 Pair and Control + +- Pairing the controller with chip-tool + +``` +./chip-tool pairing ble-wifi 0x7483 20202021 3840 +``` + +- Initializing a new Thread network dataset and commit it as the active one + +``` +matter esp ot_cli dataset init new +matter esp ot_cli dataset commit active +``` + +- Getting the operational dataset TLV-encoded string. The `` will be printed. + +``` +matter esp ot_cli dataset active -x +``` + +- Starting the Thread network + +``` +matter esp ot_cli ifconfig up +matter esp ot_cli thread start +``` + +- Pairing the Thread end-device with chip-tool and write the ACL + +``` +./chip-tool pairing ble-thread 0x7484 hex: 20202021 3840 +./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233, 25731], "targets":null}]' 0x7484 0 +``` + +- Control the Thread end-device on the device console (On/Off cluster Toggle command) + +``` +matter esp controller invoke-cmd 0x7484 1 6 2 +``` + +## A1 Appendix FAQs + +### A1.1 Pairing Command Failed I cannot finish the commissioning on the controller example: @@ -30,7 +89,7 @@ I cannot finish the commissioning on the controller example: - The complete device logs for both the devices taken over UART. - The esp-matter and esp-idf branch you are using. -### A2.2 Command Send Failed +### A1.2 Command Send Failed I cannot send commands to the light from the controller: diff --git a/examples/controller/main/CMakeLists.txt b/examples/controller/main/CMakeLists.txt index 1103ba7ad..5d45edd60 100644 --- a/examples/controller/main/CMakeLists.txt +++ b/examples/controller/main/CMakeLists.txt @@ -1,7 +1,9 @@ +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS ".") -idf_component_register(SRC_DIRS ".") - -spiffs_create_partition_image(paa_cert ${CMAKE_SOURCE_DIR}/paa_cert FLASH_IN_PROJECT) +if(CONFIG_SPIFFS_ATTESTATION_TRUST_STORE) + spiffs_create_partition_image(paa_cert ${CMAKE_SOURCE_DIR}/paa_cert FLASH_IN_PROJECT) +endif() set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") diff --git a/examples/controller/main/app_main.cpp b/examples/controller/main/app_main.cpp index 71f0b8995..1dd1ebfae 100644 --- a/examples/controller/main/app_main.cpp +++ b/examples/controller/main/app_main.cpp @@ -12,11 +12,19 @@ #include #include -#include #include #include +#include #include - +#if CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE +#include +#include +#endif // CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE +#if CONFIG_OPENTHREAD_BORDER_ROUTER +#include +#include +#include +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER #include #include @@ -35,13 +43,26 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) 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 + 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_matter::thread_br_init(&config); +#endif #if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - case chip::DeviceLayer::DeviceEventType::kFabricCommitted: - if (chip::Server::GetInstance().GetFabricTable().FindFabricWithIndex(1)) { - esp_matter::controller::set_fabric_index(1); + // Check whether fabric exists at index 1, if yes, set the controller fabric index to 1. + // If you controller works on other fabrics, please set the fabric index to another value. + if (chip::Server::GetInstance().GetFabricTable().FindFabricWithIndex(1)) { + esp_matter::controller::set_fabric_index(1); + } +#endif } break; -#endif default: break; } @@ -53,29 +74,41 @@ extern "C" void app_main() /* Initialize the ESP NVS layer */ nvs_flash_init(); +#if CONFIG_ENABLE_CHIP_SHELL + esp_matter::console::diagnostics_register_commands(); + esp_matter::console::wifi_register_commands(); + esp_matter::console::init(); +#if CONFIG_ESP_MATTER_CONTROLLER_ENABLE + esp_matter::console::controller_register_commands(); +#endif // CONFIG_ESP_MATTER_CONTROLLER_ENABLE +#if CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_OPENTHREAD_CLI + esp_matter::console::thread_br_cli_register_command(); +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER && CONFIG_OPENTHREAD_CLI +#endif // CONFIG_ENABLE_CHIP_SHELL #if !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE // 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); -#endif + if (!node) { + ESP_LOGE(TAG, "Failed to create esp_matter node"); + return; + } + endpoint_t *root_endpoint = endpoint::get(node, 0); + if (!root_endpoint) { + ESP_LOGE(TAG, "Failed to create root_node endpoint"); + return; + } +#endif // !CONFIG_ESP_MATTER_COMMISSIONER_ENABLE /* 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(); -#if CONFIG_ESP_MATTER_CONTROLLER_ENABLE #if CONFIG_ESP_MATTER_COMMISSIONER_ENABLE esp_matter::lock::chip_stack_lock(portMAX_DELAY); esp_matter::commissioner::init(5580); esp_matter::lock::chip_stack_unlock(); #endif // CONFIG_ESP_MATTER_COMMISSIONER_ENABLE - esp_matter::console::controller_register_commands(); -#endif // CONFIG_ESP_MATTER_CONTROLLER_ENABLE -#endif // CONFIG_ENABLE_CHIP_SHELL } diff --git a/examples/controller/main/esp_ot_config.h b/examples/controller/main/esp_ot_config.h new file mode 100644 index 000000000..dbb5f34c4 --- /dev/null +++ b/examples/controller/main/esp_ot_config.h @@ -0,0 +1,84 @@ +/* + * 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" + +#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 = 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 HOST_BAUD_RATE 115200 + +#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, \ + } +#endif // CONFIG_OPENTHREAD_BORDER_ROUTER diff --git a/examples/controller/partitions_br.csv b/examples/controller/partitions_br.csv new file mode 100644 index 000000000..3f1100afa --- /dev/null +++ b/examples/controller/partitions_br.csv @@ -0,0 +1,5 @@ +# 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, diff --git a/examples/controller/sdkconfig.defaults.otbr b/examples/controller/sdkconfig.defaults.otbr new file mode 100644 index 000000000..6022066e5 --- /dev/null +++ b/examples/controller/sdkconfig.defaults.otbr @@ -0,0 +1,73 @@ +# Default to 115200 baud when monitoring device +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +# 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_BORDER_ROUTER=y +CONFIG_ENABLE_MATTER_OVER_THREAD=n + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +#LwIP config for OpenThread +CONFIG_LWIP_IPV6_AUTOCONFIG=y +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_IPV6_FORWARD=y +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y +CONFIG_LWIP_NETIF_STATUS_CALLBACK=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_br.csv" + +# mbedTLS +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_ECJPAKE_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y + +# MDNS platform +CONFIG_USE_MINIMAL_MDNS=n +CONFIG_ENABLE_EXTENDED_DISCOVERY=y +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# Enable chip shell +CONFIG_ENABLE_CHIP_SHELL=y +CONFIG_ESP_MATTER_CONSOLE_TASK_STACK=4096 + +# Increase Stack size +CONFIG_CHIP_TASK_STACK_SIZE=10240 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 + +# Wi-Fi Settings +CONFIG_ENABLE_WIFI_STATION=y +CONFIG_ENABLE_WIFI_AP=n + +# Enable Controller and disable commissioner +CONFIG_ESP_MATTER_CONTROLLER_ENABLE=y +CONFIG_ESP_MATTER_COMMISSIONER_ENABLE=n +CONFIG_ESP_MATTER_CONTROLLER_CUSTOM_CLUSTER_ENABLE=n + +# Disable chip test build +CONFIG_BUILD_CHIP_TESTS=n + +# Disable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +# Disable route hook for matter since OTBR has already initialize the route hook +CONFIG_ENABLE_ROUTE_HOOK=n + +# Use USB Jtag Console +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y