diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 57bc3971d44ea3..8c328c60b7c4b5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -180,6 +180,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/test-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml \ diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index eedfb7190e2f27..777b31b8a028dd 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -112,6 +112,7 @@ Generally regenerate using one of: | 1069 | 0x42D | Pm10ConcentrationMeasurement | | 1070 | 0x42E | TotalVolatileOrganicCompoundsConcentrationMeasurement | | 1071 | 0x42F | RadonConcentrationMeasurement | +| 1106 | 0x452 | ThreadBorderRouterManagement | | 1283 | 0x503 | WakeOnLan | | 1284 | 0x504 | Channel | | 1285 | 0x505 | TargetNavigator | diff --git a/examples/platform/esp32/common/CommonDeviceCallbacks.cpp b/examples/platform/esp32/common/CommonDeviceCallbacks.cpp index 7203a0cd6a92cf..2dfcffef3dece8 100644 --- a/examples/platform/esp32/common/CommonDeviceCallbacks.cpp +++ b/examples/platform/esp32/common/CommonDeviceCallbacks.cpp @@ -84,6 +84,14 @@ void CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, i // newly selected address. chip::app::DnssdServer::Instance().StartServer(); } + if (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned) + { + appDelegate = DeviceCallbacksDelegate::Instance().GetAppDelegate(); + if (appDelegate != nullptr) + { + appDelegate->OnIPv6ConnectivityEstablished(); + } + } break; } diff --git a/examples/platform/esp32/common/CommonDeviceCallbacks.h b/examples/platform/esp32/common/CommonDeviceCallbacks.h index f76cdc405aa80e..de6770f1ee311d 100644 --- a/examples/platform/esp32/common/CommonDeviceCallbacks.h +++ b/examples/platform/esp32/common/CommonDeviceCallbacks.h @@ -41,6 +41,7 @@ class DeviceCallbacksDelegate virtual void OnIPv4ConnectivityEstablished() {} virtual void OnIPv4ConnectivityLost() {} virtual void OnDnssdInitialized() {} + virtual void OnIPv6ConnectivityEstablished() {} DeviceCallbacksDelegate * mDelegate = nullptr; void SetAppDelegate(DeviceCallbacksDelegate * delegate) { mDelegate = delegate; } DeviceCallbacksDelegate * GetAppDelegate() { return mDelegate; } diff --git a/examples/platform/esp32/common/Esp32AppServer.cpp b/examples/platform/esp32/common/Esp32AppServer.cpp index 4f854c518bd01f..07669684eeae50 100644 --- a/examples/platform/esp32/common/Esp32AppServer.cpp +++ b/examples/platform/esp32/common/Esp32AppServer.cpp @@ -48,7 +48,7 @@ static constexpr char TAG[] = "ESP32Appserver"; namespace { #if CHIP_DEVICE_CONFIG_ENABLE_WIFI -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET +#if (CHIP_DEVICE_CONFIG_ENABLE_THREAD && !defined(CONFIG_OPENTHREAD_BORDER_ROUTER)) || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET constexpr chip::EndpointId kNetworkCommissioningEndpointWiFi = 0xFFFE; #else constexpr chip::EndpointId kNetworkCommissioningEndpointWiFi = 0; diff --git a/examples/platform/esp32/common/Esp32ThreadInit.h b/examples/platform/esp32/common/Esp32ThreadInit.h index f6edba24b2b82f..6395a78ef41691 100644 --- a/examples/platform/esp32/common/Esp32ThreadInit.h +++ b/examples/platform/esp32/common/Esp32ThreadInit.h @@ -22,10 +22,57 @@ #if CONFIG_OPENTHREAD_ENABLED #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 = 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() \ { \ diff --git a/examples/thread-br-app/esp32/.gitignore b/examples/thread-br-app/esp32/.gitignore new file mode 100644 index 00000000000000..234526a082ad26 --- /dev/null +++ b/examples/thread-br-app/esp32/.gitignore @@ -0,0 +1,5 @@ +*.vscode + +/build/ +/sdkconfig +/sdkconfig.old diff --git a/examples/thread-br-app/esp32/CMakeLists.txt b/examples/thread-br-app/esp32/CMakeLists.txt new file mode 100644 index 00000000000000..22ae0cf4c53c46 --- /dev/null +++ b/examples/thread-br-app/esp32/CMakeLists.txt @@ -0,0 +1,49 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# All rights reserved. +# +# 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. + +# 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) + +set(PROJECT_VER "v1.0") +set(PROJECT_VER_NUMBER 1) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../../common/cmake/idf_flashing.cmake) + +set(EXTRA_COMPONENT_DIRS + "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components" +) + +project(chip-thread-br-app) + +# C++17 is required for RPC build. +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 the C3, 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) + +# We don't need Thread Network Commissioning Driver +idf_build_set_property(COMPILE_OPTIONS "-D_NO_NETWORK_COMMISSIONING_DRIVER_" APPEND) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +idf_build_set_property(COMPILE_OPTIONS "-Wno-error=maybe-uninitialized" APPEND) + +flashing_script() diff --git a/examples/thread-br-app/esp32/README.md b/examples/thread-br-app/esp32/README.md new file mode 100644 index 00000000000000..528a420da56e7f --- /dev/null +++ b/examples/thread-br-app/esp32/README.md @@ -0,0 +1,82 @@ +# Matter ESP32 Thread Border Router Example + +A prototype application that demonstrates OpenThread Border Router on ESP32-S3 + ESP32-H2 +Thread Border Router DevKit Board. + +Please +[setup ESP-IDF and CHIP Environment](../../../docs/guides/esp32/setup_idf_chip.md) +and refer +[building and commissioning](../../../docs/guides/esp32/build_app_and_commission.md) +guides to get started. + +--- + +- [OpenThread Border Router DevKit Board](#openthread-border-router-board) +- [OpenThread RCP](#openthread-rcp) +- [OpenThread CLI](#openthread-cli) +- [Setup Thread Network](#setup-thread-network) +- [Commissioning Thread End Devices](#commissioning-thread-end-devices) + +--- + +### Thread Border Router Board + +The ESP Thread border router board provides an integrated module of an ESP32-S3 and an ESP32-H2. + +![br_dev_kit](./image/esp-thread-border-router-board.png) + +### OpenThread RCP + +We need to flash an OpenThread RCP(Radio Co-Processor) on ESP32-H2 of the Border Router Board before setting +up the Thread Border example. Connect the USB1 port of the Border Router Board to your host machine. Then +build and flash the RCP firmware + +``` +cd $IDF_PATH/examples/openthread/ot_rcp +idf.py set-target esp32-h2 +idf.py build +idf.py -p {port} erase-flash flash +``` + +### OpenThread CLI + +After you build this example and flash it to the ESP32-S3 of Border Router Board, you can access a standard +OpenThread CLI via the device console with a `matter otcli` prefix. + +For instance, you can get the state: +``` +> matter otcli state +Detached +Done +``` + +### Setup Thread Network + +You can choose to setup Thread network with the [OpenThread CLI](#openthread-cli). + +``` +> matter otcli dataset set active +> matter otcli dataset commit active +> matter otcli ifconfig up +> matter otcli thread start +``` + +Or you can send SetActiveDatasetRequest command to the Thread BR after commissioning it as a +Matter-Over-Wi-Fi device to setup the Thread network. + +``` +./chip-tool pairing ble-wifi 1 20202021 3840 +./chip-tool generalcommissioning arm-fail-safe 180 1 1 0 +./chip-tool threadborderroutermanagement set-active-dataset-request hex: 1 1 1 +``` + +The Thread BR with enable the Thread network interface and start Thread network after it receives +SetActiveDatasetRequest command. + +### Commissioning Thread End Devices + +After setting up the Thread network, you can commission a Thread End-device to the Thread network. + +``` +./chip-tool pairing ble-wifi 2 hex: +``` diff --git a/examples/thread-br-app/esp32/image/esp-thread-border-router-board.png b/examples/thread-br-app/esp32/image/esp-thread-border-router-board.png new file mode 100644 index 00000000000000..fb2db7db60e593 Binary files /dev/null and b/examples/thread-br-app/esp32/image/esp-thread-border-router-board.png differ diff --git a/examples/thread-br-app/esp32/main/CMakeLists.txt b/examples/thread-br-app/esp32/main/CMakeLists.txt new file mode 100644 index 00000000000000..c0cb1234b0cca3 --- /dev/null +++ b/examples/thread-br-app/esp32/main/CMakeLists.txt @@ -0,0 +1,73 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# 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. +# + +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +idf_component_register(PRIV_INCLUDE_DIRS + "${CMAKE_CURRENT_LIST_DIR}/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" + SRC_DIRS + "${CMAKE_CURRENT_LIST_DIR}" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/basic-information" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/bindings" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/descriptor" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ethernet-network-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/fixed-label-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/identify-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-border-router-management-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/user-label-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/group-key-mgmt-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server") + +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/thread-br-app/thread-br-common/thread-br-app.matter") +chip_app_component_zapgen("${CHIP_ROOT}/examples/thread-br-app/thread-br-common/thread-br-app.zap") + +set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) +target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") +target_compile_options(${COMPONENT_LIB} PUBLIC + "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" +) diff --git a/examples/thread-br-app/esp32/main/DeviceCallbacks.cpp b/examples/thread-br-app/esp32/main/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..6925df9b21da8f --- /dev/null +++ b/examples/thread-br-app/esp32/main/DeviceCallbacks.cpp @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ + +#include "DeviceCallbacks.h" +#include "common/Esp32ThreadInit.h" +#include "platform/ESP32/OpenthreadLauncher.h" +#include "platform/ThreadStackManager.h" +#include +#include +#include +#include + +static const char TAG[] = "thread-br-app-callbacks"; + +using namespace chip; +using namespace chip::Inet; +using namespace chip::System; +using namespace chip::app::Clusters; + +void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value) +{ + ESP_LOGI(TAG, "PostAttributeChangeCallback - Cluster ID: '0x%" PRIx32 "', EndPoint ID: '0x%x', Attribute ID: '0x%" PRIx32 "'", + clusterId, endpointId, attributeId); + + ESP_LOGI(TAG, "Current free heap: %u\n", static_cast(heap_caps_get_free_size(MALLOC_CAP_8BIT))); +} + +void AppDeviceCallbacksDelegate::OnIPv6ConnectivityEstablished(void) +{ + static bool sThreadBRInitialized = false; + if (!sThreadBRInitialized) + { + esp_openthread_lock_acquire(portMAX_DELAY); + esp_openthread_border_router_init(); + esp_openthread_lock_release(); + sThreadBRInitialized = true; + } +} diff --git a/examples/thread-br-app/esp32/main/ESP32ThreadBorderRouterDelegate.cpp b/examples/thread-br-app/esp32/main/ESP32ThreadBorderRouterDelegate.cpp new file mode 100644 index 00000000000000..6b354fde2a9548 --- /dev/null +++ b/examples/thread-br-app/esp32/main/ESP32ThreadBorderRouterDelegate.cpp @@ -0,0 +1,526 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "ESP32ThreadBorderRouterDelegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +using Protocols::InteractionModel::Status; + +namespace ThreadBorderRouterManagement { + +class ScopedThreadLock +{ +public: + ScopedThreadLock() { DeviceLayer::ThreadStackMgr().LockThreadStack(); } + ~ScopedThreadLock() { DeviceLayer::ThreadStackMgr().UnlockThreadStack(); } +}; + +static RoutingRoleEnum MapRoutingRole(otDeviceRole role, bool isFTD, bool rxOnWhenIdle) +{ + if (role == OT_DEVICE_ROLE_DISABLED || role == OT_DEVICE_ROLE_DETACHED) + { + return RoutingRoleEnum::kUnassigned; + } + else if (role == OT_DEVICE_ROLE_CHILD) + { + if (rxOnWhenIdle) + { + return isFTD ? RoutingRoleEnum::kReed : RoutingRoleEnum::kEndDevice; + } + else + { + return RoutingRoleEnum::kSleepyEndDevice; + } + } + else if (role == OT_DEVICE_ROLE_ROUTER) + { + return RoutingRoleEnum::kRouter; + } + else if (role == OT_DEVICE_ROLE_LEADER) + { + return RoutingRoleEnum::kLeader; + } + return RoutingRoleEnum::kUnspecified; +} + +void ClearThreadNode(Delegate::ThreadNode & threadNode) +{ + threadNode.Routes.Free(); + threadNode.routeTable = DataModel::List(); + threadNode.Ipv6Addresses.Free(); + threadNode.Ipv6AddressesSpans.Free(); + threadNode.IPv6s = DataModel::List(); + threadNode.Children.Free(); + threadNode.childTable = DataModel::List(); +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetBorderAgentId(MutableByteSpan & borderAgentIdSpan) +{ + otBorderAgentId borderAgentId; + if (borderAgentIdSpan.size() < sizeof(borderAgentId.mId)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + ScopedThreadLock threadLock; + otError err = otBorderAgentGetId(esp_openthread_get_instance(), &borderAgentId); + if (err == OT_ERROR_NONE) + { + memcpy(borderAgentIdSpan.data(), borderAgentId.mId, sizeof(borderAgentId.mId)); + borderAgentIdSpan.reduce_size(sizeof(borderAgentId.mId)); + return CHIP_NO_ERROR; + } + return CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetThreadVersion(uint16_t & threadVersion) +{ + threadVersion = otThreadGetVersion(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetInterfaceEnabled(bool & interfaceEnabled) +{ + ScopedThreadLock threadLock; + interfaceEnabled = otIp6IsEnabled(esp_openthread_get_instance()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetThreadNode(ThreadNode & threadNode) +{ + ScopedThreadLock threadLock; + ReturnErrorOnFailure(GetExtAddress(threadNode.extAddress)); + ReturnErrorOnFailure(GetRolc16(threadNode.rloc16)); + ReturnErrorOnFailure(GetRoutingRole(threadNode.routingRole)); + threadNode.Ipv6Addresses.Alloc(kOpenThreadMaxIPv6AddressCount); + threadNode.Ipv6AddressesSpans.Alloc(kOpenThreadMaxIPv6AddressCount); + ReturnErrorCodeIf((!threadNode.Ipv6Addresses.Get()) || (!threadNode.Ipv6AddressesSpans.Get()), CHIP_ERROR_NO_MEMORY); + Span ipv6AddrsSpan(threadNode.Ipv6Addresses.Get(), kOpenThreadMaxIPv6AddressCount); + ReturnErrorOnFailure(GetIpv6s(ipv6AddrsSpan)); + for (size_t i = 0; i < ipv6AddrsSpan.size(); ++i) + { + threadNode.Ipv6AddressesSpans[i] = + ByteSpan((uint8_t *) threadNode.Ipv6Addresses[i].Addr, sizeof(threadNode.Ipv6Addresses[i].Addr)); + } + threadNode.IPv6s = DataModel::List(threadNode.Ipv6AddressesSpans.Get(), ipv6AddrsSpan.size()); + threadNode.Routes.Alloc(kOpenThreadMaxRouterId); + ReturnErrorCodeIf(!threadNode.Routes.Get(), CHIP_ERROR_NO_MEMORY); + Span routeTableSpan(threadNode.Routes.Get(), kOpenThreadMaxRouterId); + ReturnErrorOnFailure(GetRouteTable(routeTableSpan)); + threadNode.routeTable = DataModel::List(routeTableSpan); + threadNode.Children.Alloc(kOpenThreadMaxChildCount); + ReturnErrorCodeIf(!threadNode.Children.Get(), CHIP_ERROR_NO_MEMORY); + Span childTableSpan(threadNode.Children.Get(), kOpenThreadMaxChildCount); + ReturnErrorOnFailure(GetChildTable(childTableSpan)); + threadNode.childTable = DataModel::List(childTableSpan); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetActiveDataset(chip::Thread::OperationalDataset & activeDataset) +{ + ScopedThreadLock threadLock; + otOperationalDatasetTlvs datasetTlvs; + otError otErr = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &datasetTlvs); + if (otErr == OT_ERROR_NONE) + { + return activeDataset.Init(ByteSpan(datasetTlvs.mTlvs, datasetTlvs.mLength)); + } + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetPendingDataset(chip::Thread::OperationalDataset & pendingDataset) +{ + ScopedThreadLock threadLock; + otOperationalDatasetTlvs datasetTlvs; + otError otErr = otDatasetGetPendingTlvs(esp_openthread_get_instance(), &datasetTlvs); + if (otErr == OT_ERROR_NONE) + { + return pendingDataset.Init(ByteSpan(datasetTlvs.mTlvs, datasetTlvs.mLength)); + } + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::SetActiveDataset(const chip::Thread::OperationalDataset & activeDataset) +{ + otInstance * otInst = esp_openthread_get_instance(); + ReturnErrorCodeIf(!otInst, CHIP_ERROR_INCORRECT_STATE); + otOperationalDatasetTlvs datasetTlvs; + ScopedThreadLock threadLock; + if (otDatasetGetActiveTlvs(otInst, &datasetTlvs) != OT_ERROR_NONE || activeDataset.AsByteSpan().size() != datasetTlvs.mLength || + memcmp(datasetTlvs.mTlvs, activeDataset.AsByteSpan().data(), datasetTlvs.mLength) != 0) + { + memcpy(datasetTlvs.mTlvs, activeDataset.AsByteSpan().data(), activeDataset.AsByteSpan().size()); + datasetTlvs.mLength = activeDataset.AsByteSpan().size(); + + // Disable thread before setting active dataset + ReturnErrorOnFailure(SetThreadEnabled(false)); + ReturnErrorCodeIf(otDatasetSetActiveTlvs(otInst, &datasetTlvs) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + } + ReturnErrorOnFailure(SetThreadEnabled(true)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::SetPendingDataset(const chip::Thread::OperationalDataset & pendingDataset) +{ + ScopedThreadLock threadLock; + otOperationalDatasetTlvs datasetTlvs; + memcpy(datasetTlvs.mTlvs, pendingDataset.AsByteSpan().data(), pendingDataset.AsByteSpan().size()); + datasetTlvs.mLength = pendingDataset.AsByteSpan().size(); + ReturnErrorCodeIf(otDatasetSetPendingTlvs(esp_openthread_get_instance(), &datasetTlvs) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + return CHIP_NO_ERROR; +} + +void ESP32ThreadBorderRouterDelegate::OnTopologyRequestCompleted(chip::System::Layer * systemLayer, void * appState) +{ + ESP32ThreadBorderRouterDelegate * delegate = (ESP32ThreadBorderRouterDelegate *) appState; + if (delegate) + { + // Finish the topology request + delegate->mCurrentSnapshot++; + if (delegate->mCurrentSnapshot == 0) + { + delegate->mCurrentSnapshot = 1; + } + auto topology = Span(delegate->mThreadNodesBuffer, delegate->mThreadNodesCount); + delegate->mCallback->OnTopologyRequestFinished(Status::Success, delegate->mCurrentSnapshot, topology); + } +} + +void ESP32ThreadBorderRouterDelegate::DiagnosticReceiveHandler(otError error, otMessage * message, + const otMessageInfo * messageInfo, void * context) +{ + ESP32ThreadBorderRouterDelegate * delegate = (ESP32ThreadBorderRouterDelegate *) context; + // This should never happen + VerifyOrDie(delegate); + if (error != OT_ERROR_NONE) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mCallback->OnTopologyRequestFinished(Status::Failure, 0, Span()); }); + // Some error when requesting topology + return; + } + if (delegate->mThreadNodesCount >= kMaxThreadNodesCount) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mCallback->OnTopologyRequestFinished(Status::ResourceExhausted, 0, Span()); }); + return; + } + DeviceLayer::PlatformMgr().LockChipStack(); + // ExtendTimer when receiving a diagnostic message + DeviceLayer::SystemLayer().ExtendTimerTo(System::Clock::Milliseconds32(1000), OnTopologyRequestCompleted, delegate); + DeviceLayer::PlatformMgr().UnlockChipStack(); + otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT; + otNetworkDiagTlv diagTlv; + otLinkModeConfig linkMode = { + .mRxOnWhenIdle = false, + .mDeviceType = false, + .mNetworkData = false, + }; + bool linkModeGet = false, rloc16Get = false, isLeader = false; + auto & currentThreadNode = delegate->mThreadNodesBuffer[delegate->mThreadNodesCount]; + ClearThreadNode(currentThreadNode); + while ((error = otThreadGetNextDiagnosticTlv(message, &iterator, &diagTlv)) == OT_ERROR_NONE) + { + switch (diagTlv.mType) + { + case OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS: + memcpy(&(currentThreadNode.extAddress), diagTlv.mData.mExtAddress.m8, sizeof(uint64_t)); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS: + currentThreadNode.rloc16 = diagTlv.mData.mAddr16; + rloc16Get = true; + break; + case OT_NETWORK_DIAGNOSTIC_TLV_MODE: + linkMode = diagTlv.mData.mMode; + linkModeGet = true; + break; + case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE: { + if (diagTlv.mData.mRoute.mRouteCount == 0) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mCallback->OnTopologyRequestFinished(Status::Failure, 0, Span()); }); + return; + } + currentThreadNode.Routes.Alloc(diagTlv.mData.mRoute.mRouteCount); + if (!currentThreadNode.Routes.Get()) + { + DeviceLayer::SystemLayer().ScheduleLambda([delegate]() { + delegate->mCallback->OnTopologyRequestFinished(Status::ResourceExhausted, 0, Span()); + }); + return; + } + for (size_t routeIndex = 0; routeIndex < diagTlv.mData.mRoute.mRouteCount; ++routeIndex) + { + currentThreadNode.Routes[routeIndex].routerId = diagTlv.mData.mRoute.mRouteData[routeIndex].mRouterId; + currentThreadNode.Routes[routeIndex].pathCost = diagTlv.mData.mRoute.mRouteData[routeIndex].mRouteCost; + currentThreadNode.Routes[routeIndex].LQIIn = diagTlv.mData.mRoute.mRouteData[routeIndex].mLinkQualityIn; + currentThreadNode.Routes[routeIndex].LQIOut = diagTlv.mData.mRoute.mRouteData[routeIndex].mLinkQualityOut; + if (currentThreadNode.Routes[routeIndex].routerId == delegate->mLeaderRouterId && + currentThreadNode.Routes[routeIndex].LQIIn == 0 && currentThreadNode.Routes[routeIndex].LQIOut == 0) + { + isLeader = true; + } + } + Span routeTableSpan = + Span(currentThreadNode.Routes.Get(), diagTlv.mData.mRoute.mRouteCount); + currentThreadNode.routeTable = DataModel::List(routeTableSpan); + break; + } + case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST: { + if (diagTlv.mData.mIp6AddrList.mCount == 0) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mCallback->OnTopologyRequestFinished(Status::Failure, 0, Span()); }); + return; + } + currentThreadNode.Ipv6Addresses.Alloc(diagTlv.mData.mIp6AddrList.mCount); + currentThreadNode.Ipv6AddressesSpans.Alloc(diagTlv.mData.mIp6AddrList.mCount); + if ((!currentThreadNode.Ipv6Addresses.Get()) || (!currentThreadNode.Ipv6AddressesSpans.Get())) + { + DeviceLayer::SystemLayer().ScheduleLambda([delegate]() { + delegate->mCallback->OnTopologyRequestFinished(Status::ResourceExhausted, 0, Span()); + }); + return; + } + for (size_t ipAddrIndex = 0; ipAddrIndex < diagTlv.mData.mIp6AddrList.mCount; ++ipAddrIndex) + { + memcpy(currentThreadNode.Ipv6Addresses[ipAddrIndex].Addr, diagTlv.mData.mIp6AddrList.mList[ipAddrIndex].mFields.m8, + OT_IP6_ADDRESS_SIZE); + currentThreadNode.Ipv6AddressesSpans[ipAddrIndex] = + ByteSpan((uint8_t *) currentThreadNode.Ipv6Addresses[ipAddrIndex].Addr, + sizeof(currentThreadNode.Ipv6Addresses[ipAddrIndex].Addr)); + } + currentThreadNode.IPv6s = + DataModel::List(currentThreadNode.Ipv6AddressesSpans.Get(), diagTlv.mData.mIp6AddrList.mCount); + break; + } + case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE: + if (diagTlv.mData.mChildTable.mCount > 0) + { + currentThreadNode.Children.Alloc(diagTlv.mData.mChildTable.mCount); + if (!currentThreadNode.Children.Get()) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mCallback->OnTopologyRequestFinished(Status::Failure, 0, Span()); }); + return; + } + for (size_t childIndex = 0; childIndex < diagTlv.mData.mChildTable.mCount; ++childIndex) + { + currentThreadNode.Children[childIndex].linkQuality = diagTlv.mData.mChildTable.mTable[childIndex].mLinkQuality; + currentThreadNode.Children[childIndex].rloc16 = diagTlv.mData.mChildTable.mTable[childIndex].mChildId; + currentThreadNode.Children[childIndex].routingRole = + MapRoutingRole(OT_DEVICE_ROLE_CHILD, diagTlv.mData.mChildTable.mTable[childIndex].mMode.mDeviceType, + diagTlv.mData.mChildTable.mTable[childIndex].mMode.mRxOnWhenIdle); + } + currentThreadNode.childTable = + DataModel::List(currentThreadNode.Children.Get(), diagTlv.mData.mChildTable.mCount); + } + break; + default: + break; + } + } + if (linkModeGet && rloc16Get && currentThreadNode.routeTable.size() > 0) + { + if ((currentThreadNode.rloc16 & 0x00FF) == 0) + { + currentThreadNode.routingRole = isLeader ? RoutingRoleEnum::kLeader : RoutingRoleEnum::kRouter; + } + else + { + currentThreadNode.routingRole = MapRoutingRole(OT_DEVICE_ROLE_CHILD, linkMode.mDeviceType, linkMode.mRxOnWhenIdle); + } + } + if (rloc16Get && currentThreadNode.childTable.size() > 0) + { + for (size_t i = 0; i < currentThreadNode.childTable.size(); ++i) + { + currentThreadNode.Children[i].rloc16 |= (currentThreadNode.rloc16 & 0xFF00); + } + } + delegate->mThreadNodesCount++; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetTopology(uint8_t snapshot, Callback * callback) +{ + if (!callback) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (snapshot != 0) + { + if (snapshot != mCurrentSnapshot) + { + return CHIP_ERROR_NOT_FOUND; + } + auto topology = Span(mThreadNodesBuffer, mThreadNodesCount); + callback->OnTopologyRequestFinished(Status::Success, snapshot, topology); + return CHIP_NO_ERROR; + } + // snapshot is zero, we need to create a new snapshot. + mThreadNodesCount = 0; + mCallback = callback; + ScopedThreadLock threadLock; + otIp6Address multicastAddress; + // Get Leader RouterId to distinguish Router and Leader in DiagnosticReceiveHandler + otLeaderData leaderdata; + ReturnErrorCodeIf(otThreadGetLeaderData(esp_openthread_get_instance(), &leaderdata) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + mLeaderRouterId = leaderdata.mLeaderRouterId; + // Send DiagnosticGet message to all the Routers to create a topology snapshot + ReturnErrorCodeIf(otIp6AddressFromString(kMulticastAddrAllRouters, &multicastAddress) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + ReturnErrorCodeIf(otThreadSendDiagnosticGet(esp_openthread_get_instance(), &multicastAddress, kDiagTLVTypes, + sizeof(kDiagTLVTypes), DiagnosticReceiveHandler, this) != OT_ERROR_NONE, + CHIP_ERROR_INTERNAL); + // If the BR doesn't receive diagnostic message in 1 seconds, we consider that the topology request is done + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(1000), OnTopologyRequestCompleted, this); + return CHIP_NO_ERROR; +} + +// These function should be called when Thread stack is locked +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetExtAddress(uint64_t & extAddr) +{ + otInstance * otInst = esp_openthread_get_instance(); + const otExtAddress * extAddress = otLinkGetExtendedAddress(otInst); + memcpy(&extAddr, extAddress->m8, sizeof(extAddress->m8)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetRolc16(uint16_t & rloc16) +{ + rloc16 = otThreadGetRloc16(esp_openthread_get_instance()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetRoutingRole(RoutingRoleEnum & routingRole) +{ + otInstance * otInst = esp_openthread_get_instance(); + otDeviceRole role = otThreadGetDeviceRole(otInst); + otLinkModeConfig linkModeConfig = otThreadGetLinkMode(otInst); + routingRole = MapRoutingRole(role, linkModeConfig.mDeviceType, linkModeConfig.mRxOnWhenIdle); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetIpv6s(Span & ipv6Addrs) +{ + otInstance * otInst = esp_openthread_get_instance(); + const otNetifAddress * netifAddrs = otIp6GetUnicastAddresses(otInst); + size_t addrIndex = 0; + for (const otNetifAddress * addr = netifAddrs; addr; addr = addr->mNext) + { + if (addrIndex >= ipv6Addrs.size()) + { + return CHIP_ERROR_NO_MEMORY; + } + memcpy(ipv6Addrs[addrIndex].Addr, addr->mAddress.mFields.m8, OT_IP6_ADDRESS_SIZE); + addrIndex++; + } + ipv6Addrs.reduce_size(addrIndex); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetRouteTable(Span & routeTableSpan) +{ + otInstance * otInst = esp_openthread_get_instance(); + uint8_t maxRouterId; + otRouterInfo routerInfo; + maxRouterId = otThreadGetMaxRouterId(otInst); + uint8_t routeTableIndex = 0; + for (uint8_t i = 0; i < maxRouterId && routeTableIndex < routeTableSpan.size(); ++i) + { + if (otThreadGetRouterInfo(otInst, i, &routerInfo) == OT_ERROR_NONE) + { + routeTableSpan[routeTableIndex].LQIIn = routerInfo.mLinkQualityIn; + routeTableSpan[routeTableIndex].LQIOut = routerInfo.mLinkQualityOut; + routeTableSpan[routeTableIndex].routerId = routerInfo.mRouterId; + routeTableSpan[routeTableIndex].pathCost = routerInfo.mPathCost; + routeTableIndex++; + } + } + routeTableSpan.reduce_size(routeTableIndex); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::GetChildTable(Span & childTable) +{ + otInstance * otInst = esp_openthread_get_instance(); + uint16_t maxChildren = otThreadGetMaxAllowedChildren(otInst); + uint16_t childTableIndex = 0; + otChildInfo childInfo; + for (uint8_t i = 0; i < maxChildren && childTableIndex < childTable.size(); ++i) + { + if (otThreadGetChildInfoByIndex(otInst, i, &childInfo) == OT_ERROR_NONE) + { + childTable[childTableIndex].rloc16 = childInfo.mRloc16; + childTable[childTableIndex].linkQuality = childInfo.mLinkQualityIn; + childTable[childTableIndex].routingRole = + MapRoutingRole(OT_DEVICE_ROLE_CHILD, childInfo.mFullThreadDevice, childInfo.mRxOnWhenIdle); + childTableIndex++; + } + } + childTable.reduce_size(childTableIndex); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32ThreadBorderRouterDelegate::SetThreadEnabled(bool enabled) +{ + otInstance * instance = esp_openthread_get_instance(); + bool isEnabled = (otThreadGetDeviceRole(instance) != OT_DEVICE_ROLE_DISABLED); + bool isIp6Enabled = otIp6IsEnabled(instance); + if (enabled && !isIp6Enabled) + { + ReturnErrorCodeIf(otIp6SetEnabled(instance, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + } + if (enabled != isEnabled) + { + ReturnErrorCodeIf(otThreadSetEnabled(instance, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + } + if (!enabled && isIp6Enabled) + { + ReturnErrorCodeIf(otIp6SetEnabled(instance, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + } + return CHIP_NO_ERROR; +} + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/thread-br-app/esp32/main/Kconfig.projbuild b/examples/thread-br-app/esp32/main/Kconfig.projbuild new file mode 100644 index 00000000000000..7f65d083795e42 --- /dev/null +++ b/examples/thread-br-app/esp32/main/Kconfig.projbuild @@ -0,0 +1,45 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# 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. +# +# Description: +# Configuration options CHIP ESP32 demo application. +# + +menu "Demo" + choice + prompt "Rendezvous Mode" + default RENDEZVOUS_MODE_BLE + help + Specifies the Rendezvous mode of the peripheral. + + config RENDEZVOUS_MODE_WIFI + bool "Wi-Fi" + config RENDEZVOUS_MODE_BLE + bool "BLE" + config RENDEZVOUS_MODE_THREAD + bool "Thread" + config RENDEZVOUS_MODE_ETHERNET + bool "Ethernet" + endchoice + + config RENDEZVOUS_MODE + int + range 0 8 + default 1 if RENDEZVOUS_MODE_WIFI + default 2 if RENDEZVOUS_MODE_BLE + default 4 if RENDEZVOUS_MODE_THREAD + default 8 if RENDEZVOUS_MODE_ETHERNET +endmenu diff --git a/examples/thread-br-app/esp32/main/include/DeviceCallbacks.h b/examples/thread-br-app/esp32/main/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..1507e284e0d5f5 --- /dev/null +++ b/examples/thread-br-app/esp32/main/include/DeviceCallbacks.h @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include +#include + +class AppDeviceCallbacks : public CommonDeviceCallbacks +{ +public: + virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value); +}; + +class AppDeviceCallbacksDelegate : public DeviceCallbacksDelegate +{ +public: + void OnIPv4ConnectivityEstablished(void) override {} + void OnIPv4ConnectivityLost(void) override {} + void OnIPv6ConnectivityEstablished(void) override; + void OnDnssdInitialized(void) override {} +}; diff --git a/examples/thread-br-app/esp32/main/include/ESP32ThreadBorderRouterDelegate.h b/examples/thread-br-app/esp32/main/include/ESP32ThreadBorderRouterDelegate.h new file mode 100644 index 00000000000000..f49cfc7d38b4b6 --- /dev/null +++ b/examples/thread-br-app/esp32/main/include/ESP32ThreadBorderRouterDelegate.h @@ -0,0 +1,111 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 +#include +#include +#include +#include +#include + +using chip::MutableByteSpan; +using chip::MutableCharSpan; +using chip::Span; + +namespace chip { +namespace app { +namespace Clusters { + +namespace ThreadBorderRouterManagement { + +class ESP32ThreadBorderRouterDelegate : public Delegate +{ +public: + static constexpr char kThreadBorderRourterName[] = "Espressif-ThreadBR"; + static constexpr uint8_t kOpenThreadMaxRouterId = OT_NETWORK_MAX_ROUTER_ID; + static constexpr uint8_t kOpenThreadMaxChildCount = 10; + static constexpr uint8_t kOpenThreadMaxIPv6AddressCount = 8; + static constexpr uint8_t kMaxThreadNodesCount = 64; + static constexpr char kMulticastAddrAllRouters[] = "ff03::2"; + static constexpr uint8_t kDiagTLVTypes[] = { OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS, OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS, + OT_NETWORK_DIAGNOSTIC_TLV_MODE, OT_NETWORK_DIAGNOSTIC_TLV_ROUTE, + OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST, OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE }; + + ESP32ThreadBorderRouterDelegate() = default; + ~ESP32ThreadBorderRouterDelegate() = default; + + CHIP_ERROR Init() override { return CHIP_NO_ERROR; } + + CHIP_ERROR GetPanChangeSupported(bool & panChangeSupported) override + { + panChangeSupported = true; + return CHIP_NO_ERROR; + } + + CHIP_ERROR GetBorderRouterName(MutableCharSpan & borderRouterName) override + { + if (borderRouterName.size() < strlen(kThreadBorderRourterName)) + { + return CHIP_ERROR_NO_MEMORY; + } + strcpy(borderRouterName.data(), kThreadBorderRourterName); + borderRouterName.reduce_size(strlen(kThreadBorderRourterName)); + return CHIP_NO_ERROR; + } + + CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) override; + + CHIP_ERROR GetThreadVersion(uint16_t & threadVersion) override; + + CHIP_ERROR GetInterfaceEnabled(bool & interfaceEnabled) override; + + CHIP_ERROR GetThreadNode(ThreadNode & threadNode) override; + + CHIP_ERROR GetActiveDataset(chip::Thread::OperationalDataset & activeDataset) override; + + CHIP_ERROR GetPendingDataset(chip::Thread::OperationalDataset & pendingDataset) override; + + CHIP_ERROR SetActiveDataset(const chip::Thread::OperationalDataset & activeDataset) override; + + CHIP_ERROR SetPendingDataset(const chip::Thread::OperationalDataset & pendingDataset) override; + + CHIP_ERROR GetTopology(uint8_t snapshot, Callback * callback) override; + +private: + CHIP_ERROR GetExtAddress(uint64_t & extAddr); + CHIP_ERROR GetRolc16(uint16_t & rloc16); + CHIP_ERROR GetRoutingRole(RoutingRoleEnum & routingRole); + CHIP_ERROR GetIpv6s(Span & ipv6Addrs); + CHIP_ERROR GetRouteTable(Span & routeTable); + CHIP_ERROR GetChildTable(Span & childTable); + CHIP_ERROR SetThreadEnabled(bool enabled); + + static void DiagnosticReceiveHandler(otError error, otMessage * message, const otMessageInfo * messageInfo, void * aContext); + static void OnTopologyRequestCompleted(chip::System::Layer * systemLayer, void * appState); + + uint8_t mCurrentSnapshot; + size_t mThreadNodesCount = 0; + ThreadNode mThreadNodesBuffer[kMaxThreadNodesCount]; + Callback * mCallback = nullptr; + uint8_t mLeaderRouterId = 0; +}; +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/thread-br-app/esp32/main/main.cpp b/examples/thread-br-app/esp32/main/main.cpp new file mode 100644 index 00000000000000..12d0f35c8c6ddb --- /dev/null +++ b/examples/thread-br-app/esp32/main/main.cpp @@ -0,0 +1,152 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "DeviceCallbacks.h" +#include "ESP32ThreadBorderRouterDelegate.h" + +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_openthread_border_router.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs_flash.h" +#include "shell_extension/launch.h" + +#include +#include +#include +#include +#include + +#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +#include +#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER + +#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER +#include +#else +#include +#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceManager; +using namespace ::chip::DeviceLayer; +using namespace ::chip::app::Clusters; + +namespace { +#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider; +#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER + +#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER +DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider; +#else +DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER +} // namespace + +static const char TAG[] = "thread-br-app"; + +static AppDeviceCallbacks EchoCallbacks; +static AppDeviceCallbacksDelegate sAppDeviceCallbacksDelegate; + +static void InitServer(intptr_t context) +{ + // Print QR Code URL + PrintOnboardingCodes(chip::RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE)); + + Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config +} + +static constexpr EndpointId kThreadBRMgmtEndpoint = 1; + +static ThreadBorderRouterManagement::ESP32ThreadBorderRouterDelegate sThreadBRDelegate; +static ThreadBorderRouterManagement::ServerInstance sThreadBRMgmtInstance(kThreadBRMgmtEndpoint, &sThreadBRDelegate); + +extern "C" void app_main() +{ + // Initialize the ESP NVS layer. + esp_err_t err = nvs_flash_init(); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs_flash_init() failed: %s", esp_err_to_name(err)); + return; + } + err = esp_event_loop_create_default(); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "esp_event_loop_create_default() failed: %s", esp_err_to_name(err)); + return; + } + + ESP_LOGI(TAG, "=================================================="); + ESP_LOGI(TAG, "chip-esp32-thread-br-example starting"); + ESP_LOGI(TAG, "=================================================="); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + if (DeviceLayer::Internal::ESP32Utils::InitWiFiStack() != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to initialize the Wi-Fi stack"); + return; + } +#endif + +#if CONFIG_ENABLE_CHIP_SHELL +#if CONFIG_OPENTHREAD_CLI + chip::RegisterOpenThreadCliCommands(); +#endif + chip::LaunchShell(); +#endif // CONFIG_ENABLE_CHIP_SHELL + + DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks); + DeviceCallbacksDelegate::Instance().SetAppDelegate(&sAppDeviceCallbacksDelegate); + if (error != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "device.Init() failed: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + +#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER + SetCommissionableDataProvider(&sFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); +#if CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER + SetDeviceInstanceInfoProvider(&sFactoryDataProvider); +#endif +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER + esp_openthread_set_backbone_netif(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); + ESPOpenThreadInit(); + + chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); + sThreadBRMgmtInstance.Init(); +} + +extern "C" void otSysProcessDrivers(otInstance *aInstance) +{ + (void)aInstance; +} diff --git a/examples/thread-br-app/esp32/partitions.csv b/examples/thread-br-app/esp32/partitions.csv new file mode 100644 index 00000000000000..46c93555d6a4cf --- /dev/null +++ b/examples/thread-br-app/esp32/partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, , 0xC000, +otadata, data, ota, , 0x2000, +phy_init, data, phy, , 0x1000, +ota_0, app, ota_0, , 1800K, +ota_1, app, ota_1, , 1800K, diff --git a/examples/thread-br-app/esp32/sdkconfig.defaults b/examples/thread-br-app/esp32/sdkconfig.defaults new file mode 100644 index 00000000000000..1e3b6fb3ce0d51 --- /dev/null +++ b/examples/thread-br-app/esp32/sdkconfig.defaults @@ -0,0 +1,73 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# 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. +# +# Description: +# Some useful defaults for the demo app configuration. +# + +# Flash size and partition table +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y + +# BLE +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=5120 +CONFIG_ESP_TIMER_TASK_STACK_SIZE=5120 + +# 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=6 +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 + +# Use platform mDNS +CONFIG_USE_MINIMAL_MDNS=n + +# Enable Matter shell +CONFIG_ENABLE_CHIP_SHELL=y diff --git a/examples/thread-br-app/esp32/third_party/connectedhomeip b/examples/thread-br-app/esp32/third_party/connectedhomeip new file mode 120000 index 00000000000000..11a54ed360106c --- /dev/null +++ b/examples/thread-br-app/esp32/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/examples/thread-br-app/thread-br-common/thread-br-app.matter b/examples/thread-br-app/thread-br-common/thread-br-app.matter new file mode 100644 index 00000000000000..9fc5a12a8397b5 --- /dev/null +++ b/examples/thread-br-app/thread-br-common/thread-br-app.matter @@ -0,0 +1,1546 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute optional char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing common languages, units of measurements, and numerical formatting + standards. As such, Nodes that visually or audibly convey information need a mechanism by which + they can be configured to use a user’s preferred language, units, etc */ +cluster LocalizationConfiguration = 43 { + revision 1; // NOTE: Default/not specifically set + + attribute access(write: manage) char_string<35> activeLocale = 0; + readonly attribute char_string supportedLocales[] = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing preferences for how dates and times are conveyed. As such, Nodes that visually + or audibly convey time information need a mechanism by which they can be configured to use a + user’s preferred format. */ +cluster TimeFormatLocalization = 44 { + revision 1; // NOTE: Default/not specifically set + + enum CalendarTypeEnum : enum8 { + kBuddhist = 0; + kChinese = 1; + kCoptic = 2; + kEthiopian = 3; + kGregorian = 4; + kHebrew = 5; + kIndian = 6; + kIslamic = 7; + kJapanese = 8; + kKorean = 9; + kPersian = 10; + kTaiwanese = 11; + kUseActiveLocale = 255; + } + + enum HourFormatEnum : enum8 { + k12hr = 0; + k24hr = 1; + kUseActiveLocale = 255; + } + + bitmap Feature : bitmap32 { + kCalendarFormat = 0x1; + } + + attribute access(write: manage) HourFormatEnum hourFormat = 0; + attribute access(write: manage) optional CalendarTypeEnum activeCalendarType = 1; + readonly attribute optional CalendarTypeEnum supportedCalendarTypes[] = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ +cluster ThreadNetworkDiagnostics = 53 { + revision 2; + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only +labels. */ +cluster FixedLabel = 64 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + readonly attribute LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The User Label Cluster provides a feature to tag an endpoint with zero or more labels. */ +cluster UserLabel = 65 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + attribute access(write: manage) LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Thread BR management */ +cluster ThreadBorderRouterManagement = 1106 { + revision 1; + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPANChange = 0x1; + } + + struct ChildTableStruct { + int16u rloc16 = 0; + int8u linkQuality = 1; + RoutingRoleEnum routingRole = 2; + } + + struct RouteTableStruct { + int8u routerId = 0; + int8u pathCost = 1; + int8u LQIIn = 2; + int8u LQIOut = 3; + } + + struct ThreadNodeStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + octet_string IPv6s[] = 2; + RoutingRoleEnum routingRole = 3; + RouteTableStruct routeTable[] = 4; + ChildTableStruct childTable[] = 5; + } + + struct NeiborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + nullable int8s averageRssi = 3; + nullable int8s lastRssi = 4; + RoutingRoleEnum routingRole = 5; + } + + readonly attribute char_string<63> borderRouterName = 0; + readonly attribute octet_string<16> borderAgentId = 1; + readonly attribute int16u threadVersion = 2; + readonly attribute boolean interfaceEnabled = 3; + readonly attribute ThreadNodeStruct threadNode = 4; + readonly attribute nullable int64u activeDatasetTimestamp = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + response struct DatasetResponse = 2 { + octet_string<254> dataset = 0; + } + + request struct SetActiveDatasetRequestRequest { + octet_string<254> activeDataset = 0; + int64u breadcrumb = 1; + } + + request struct SetPendingDatasetRequestRequest { + octet_string<254> pendingDataset = 0; + } + + request struct TopologyRequestRequest { + int16u count = 0; + int16u startIndex = 1; + int8u snapshot = 2; + } + + response struct TopologyResponse = 6 { + status status = 0; + int8u snapshot = 1; + int16u numberOfDevices = 2; + ThreadNodeStruct threadTopology[] = 3; + } + + /** On receipt of this command, the Thread Border Router will read the active operational dataset of the Thread network that it is connaected to, and send the DatasetResponse as the response. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetActiveDatasetRequest(): DatasetResponse = 0; + /** On receipt of this command, the Thread Border Router will read the pending dataset and send the DatasetResponse as the response. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; + /** On receipt of this command, the Thread Border Router will set or update the active Dataset of the Thread network that the Stub Router is connected to. */ + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; + /** On receipt of this command, the Thread Border Router will set or update the pending Dataset */ + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; + /** On receipt of this command, the Thread Border Router will response the current topology of the Thread network that it is connected to. */ + command access(invoke: administer) TopologyRequest(TopologyRequestRequest): TopologyResponse = 5; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + binding cluster AccessControl; + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster LocalizationConfiguration { + persist attribute activeLocale default = "en-US"; + callback attribute supportedLocales; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster TimeFormatLocalization { + persist attribute hourFormat default = 0; + persist attribute activeCalendarType default = 0; + callback attribute supportedCalendarTypes; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command OpenBasicCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } + + server cluster FixedLabel { + callback attribute labelList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UserLabel { + callback attribute labelList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } +} +endpoint 1 { + device type ma_thread_border_router = 4293984273, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + } + + server cluster ThreadBorderRouterManagement { + callback attribute borderRouterName; + callback attribute borderAgentId; + callback attribute threadVersion; + callback attribute interfaceEnabled; + callback attribute threadNode; + callback attribute activeDatasetTimestamp; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command GetActiveDatasetRequest; + handle command GetPendingDatasetRequest; + handle command DatasetResponse; + handle command SetActiveDatasetRequest; + handle command SetPendingDatasetRequest; + handle command TopologyRequest; + handle command TopologyResponse; + } +} + + diff --git a/examples/thread-br-app/thread-br-common/thread-br-app.zap b/examples/thread-br-app/thread-br-common/thread-br-app.zap new file mode 100644 index 00000000000000..89f3d662a9dada --- /dev/null +++ b/examples/thread-br-app/thread-br-common/thread-br-app.zap @@ -0,0 +1,3081 @@ +{ + "fileFormat": 2, + "featureLevel": 102, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "client", + "enabled": 1, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "en-US", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "HourFormat", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "HourFormatEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveCalendarType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "CalendarTypeEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedCalendarTypes", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OpenBasicCommissioningWindow", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "User Label", + "code": 65, + "mfgCode": null, + "define": "USER_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 4293984273, + "profileId": 259, + "label": "MA-thread-border-router", + "name": "MA-thread-border-router" + }, + "deviceTypes": [ + { + "code": 4293984273, + "profileId": 259, + "label": "MA-thread-border-router", + "name": "MA-thread-border-router" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 4293984273 + ], + "deviceTypeName": "MA-thread-border-router", + "deviceTypeCode": 4293984273, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Border Router Management", + "code": 1106, + "mfgCode": null, + "define": "THREAD_BORDER_ROUTER_MANAGEMENT", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "GetActiveDatasetRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetPendingDatasetRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DatasetResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetActiveDatasetRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetPendingDatasetRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TopologyRequest", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TopologyResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BorderRouterName", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BorderAgentId", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadNode", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "ThreadNodeStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveDatasetTimestamp", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index e876bae22094c6..6a1654de8b5901 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -88,6 +88,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/temperature-measurement-clust load "../src/app/zap-templates/zcl/data-model/chip/test-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml"; diff --git a/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h b/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h new file mode 100644 index 00000000000000..eb207bced65d23 --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h @@ -0,0 +1,90 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +constexpr size_t kBorderRouterNameMaxLength = 63; +constexpr size_t kBorderAgentIdLength = 16; + +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + using RouteTableEntry = Structs::RouteTableStruct::Type; + using ChildTableEntry = Structs::ChildTableStruct::Type; + class ThreadNode : public Structs::ThreadNodeStruct::Type + { + public: + Platform::ScopedMemoryBuffer Ipv6Addresses; + Platform::ScopedMemoryBuffer Ipv6AddressesSpans; + Platform::ScopedMemoryBuffer Routes; + Platform::ScopedMemoryBuffer Children; + }; + class Callback + { + public: + virtual void OnTopologyRequestFinished(Protocols::InteractionModel::Status status, uint8_t snapshot, + const Span & threadNodes) = 0; + + virtual ~Callback() = default; + }; + + virtual CHIP_ERROR Init() = 0; + + virtual CHIP_ERROR GetPanChangeSupported(bool & panChangeSupported) = 0; + + virtual CHIP_ERROR GetBorderRouterName(MutableCharSpan & borderRouterName) = 0; + + virtual CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) = 0; + + virtual CHIP_ERROR GetThreadVersion(uint16_t & threadVersion) = 0; + + virtual CHIP_ERROR GetInterfaceEnabled(bool & interfaceEnabled) = 0; + + virtual CHIP_ERROR GetThreadNode(ThreadNode & threadNode) = 0; + + virtual CHIP_ERROR GetActiveDataset(chip::Thread::OperationalDataset & activeDataset) = 0; + + virtual CHIP_ERROR GetPendingDataset(chip::Thread::OperationalDataset & pendingDataset) = 0; + + virtual CHIP_ERROR SetActiveDataset(const chip::Thread::OperationalDataset & activeDataset) = 0; + + virtual CHIP_ERROR SetPendingDataset(const chip::Thread::OperationalDataset & pendingDataset) = 0; + + virtual CHIP_ERROR GetTopology(uint8_t snapshot, Callback * callback) = 0; +}; + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.cpp b/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.cpp new file mode 100644 index 00000000000000..aa8b073c54a1be --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.cpp @@ -0,0 +1,430 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "thread-br-mgmt-server.h" + +#include "app-common/zap-generated/cluster-objects.h" +#include "app-common/zap-generated/ids/Attributes.h" +#include "app-common/zap-generated/ids/Clusters.h" +#include "app-common/zap-generated/ids/Commands.h" +#include "app/AttributeAccessInterfaceRegistry.h" +#include "app/AttributeValueEncoder.h" +#include "app/CommandHandler.h" +#include "app/CommandHandlerInterface.h" +#include "app/InteractionModelEngine.h" +#include "app/clusters/general-commissioning-server/general-commissioning-server.h" +#include "app/data-model/List.h" +#include "app/data-model/Nullable.h" +#include "app/server/Server.h" +#include "lib/core/CHIPError.h" +#include "lib/support/CodeUtils.h" +#include "lib/support/Span.h" +#include "lib/support/ThreadOperationalDataset.h" +#include "lib/support/TypeTraits.h" +#include "protocols/interaction_model/StatusCode.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +static Protocols::InteractionModel::Status MapChipErrorToIMStatus(CHIP_ERROR err) +{ + if (err == CHIP_ERROR_NO_MEMORY) + { + return Protocols::InteractionModel::Status::ResourceExhausted; + } + else if (err == CHIP_ERROR_NO_SHARED_TRUSTED_ROOT) + { + return Protocols::InteractionModel::Status::UnsupportedAccess; + } + else if (err == CHIP_ERROR_INVALID_ARGUMENT) + { + return Protocols::InteractionModel::Status::InvalidCommand; + } + else if (err == CHIP_ERROR_INCORRECT_STATE) + { + return Protocols::InteractionModel::Status::InvalidInState; + } + else if (err == CHIP_ERROR_NOT_FOUND) + { + return Protocols::InteractionModel::Status::NotFound; + } + return Protocols::InteractionModel::Status::Failure; +} + +static CHIP_ERROR AddStatusOnError(CommandHandlerInterface::HandlerContext & ctx, CHIP_ERROR err) +{ + if (CHIP_NO_ERROR != err) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, MapChipErrorToIMStatus(err)); + } + return err; +} + +static bool CheckOverCASESession(CommandHandlerInterface::HandlerContext & ctx) +{ + chip::Messaging::ExchangeContext * exchangeCtx = ctx.mCommandHandler.GetExchangeContext(); + if (!exchangeCtx || !exchangeCtx->HasSessionHandle() || !exchangeCtx->GetSessionHandle()->IsSecureSession() || + exchangeCtx->GetSessionHandle()->AsSecureSession()->GetSecureSessionType() != Transport::SecureSession::Type::kCASE) + { + ChipLogError(Zcl, "This command MUST be over a valid CASE session"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::UnsupportedAccess); + return false; + } + return true; +} + +static bool CheckFailSafeArmed(CommandHandlerInterface::HandlerContext & ctx) +{ + auto & failSafeContext = chip::Server::GetInstance().GetFailSafeContext(); + if (failSafeContext.IsFailSafeArmed(ctx.mCommandHandler.GetAccessingFabricIndex())) + { + return true; + } + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::FailsafeRequired); + return false; +} + +void ServerInstance::HandleGetActiveDatasetRequest(HandlerContext & ctx, + const Commands::GetActiveDatasetRequest::DecodableType & req) +{ + VerifyOrReturn(CheckOverCASESession(ctx)); + + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_UNINITIALIZED)); + } + + bool interfaceEnabled; + ReturnOnFailure(AddStatusOnError(ctx, mDelegate->GetInterfaceEnabled(interfaceEnabled))); + if (!interfaceEnabled) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Success); + return; + } + Commands::DatasetResponse::Type response; + Thread::OperationalDataset activeDataset; + ReturnOnFailure(AddStatusOnError(ctx, mDelegate->GetActiveDataset(activeDataset))); + response.dataset = activeDataset.AsByteSpan(); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); +} + +void ServerInstance::HandleGetPendingDatasetRequest(HandlerContext & ctx, + const Commands::GetPendingDatasetRequest::DecodableType & req) +{ + Commands::DatasetResponse::Type response; + VerifyOrReturn(CheckOverCASESession(ctx)); + + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_UNINITIALIZED)); + } + + Thread::OperationalDataset pendingDataset; + ReturnOnFailure(AddStatusOnError(ctx, mDelegate->GetPendingDataset(pendingDataset))); + response.dataset = pendingDataset.AsByteSpan(); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); +} + +void ServerInstance::HandleSetActiveDatasetRequest(HandlerContext & ctx, + const Commands::SetActiveDatasetRequest::DecodableType & req) +{ + VerifyOrReturn(CheckOverCASESession(ctx)); + VerifyOrReturn(CheckFailSafeArmed(ctx)); + + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_UNINITIALIZED)); + } + Thread::OperationalDataset activeDataset; + Thread::OperationalDataset currentActiveDataset; + uint64_t currentActiveDatasetTimestamp; + if (activeDataset.Init(req.activeDataset) != CHIP_NO_ERROR) + { + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_INVALID_ARGUMENT)); + } + if (mDelegate->GetActiveDataset(currentActiveDataset) == CHIP_NO_ERROR && + currentActiveDataset.GetActiveTimestamp(currentActiveDatasetTimestamp) == CHIP_NO_ERROR) + { + // When the ActiveDatasetTimestamp attribute is not null, the command SHALL fail with a status + // code of INVALID_IN_STATE + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_INCORRECT_STATE)); + } + if (mDelegate->SetActiveDataset(activeDataset) != CHIP_NO_ERROR) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Failure); + } + else + { + GeneralCommissioning::SetBreadcrumb(req.breadcrumb); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Success); + } +} + +void ServerInstance::HandleSetPendingDatasetRequest(HandlerContext & ctx, + const Commands::SetPendingDatasetRequest::DecodableType & req) +{ + VerifyOrReturn(CheckOverCASESession(ctx)); + + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_UNINITIALIZED)); + } + bool panChangeSupported; + if (mDelegate->GetPanChangeSupported(panChangeSupported) != CHIP_NO_ERROR || !panChangeSupported) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::UnsupportedCommand); + return; + } + Thread::OperationalDataset pendingDataset; + if (pendingDataset.Init(req.pendingDataset) != CHIP_NO_ERROR) + { + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_INVALID_ARGUMENT)); + return; + } + if (mDelegate->SetPendingDataset(pendingDataset) != CHIP_NO_ERROR) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Failure); + } + else + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Success); + } +} + +void ServerInstance::OnTopologyRequestFinished(Protocols::InteractionModel::Status status, uint8_t snapshot, + const Span & threadNodes) +{ + Commands::TopologyResponse::Type response; + auto commandHandleRef = std::move(mAsyncCommandHandle); + auto commandHandle = commandHandleRef.Get(); + if (status != Protocols::InteractionModel::Status::Success) + { + response.status = to_underlying(status); + commandHandle->AddResponse(mCommandPath, response); + return; + } + if (threadNodes.size() < mTopologyReq.startIndex) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); + commandHandle->AddResponse(mCommandPath, response); + return; + } + uint16_t threadNodesCount = threadNodes.size() - mTopologyReq.startIndex; + threadNodesCount = threadNodesCount > mTopologyReq.count ? mTopologyReq.count : threadNodesCount; + response.snapshot = snapshot; + response.numberOfDevices = threadNodes.size(); + response.status = to_underlying(Protocols::InteractionModel::Status::Success); + if (threadNodesCount == 0) + { + // return a response with a NULL ThreadTopology + commandHandle->AddResponse(mCommandPath, response); + return; + } + Platform::ScopedMemoryBuffer threadNodesStuctsBuffer; + threadNodesStuctsBuffer.Alloc(threadNodesCount); + if (!threadNodesStuctsBuffer.Get()) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); + commandHandle->AddResponse(mCommandPath, response); + return; + } + for (size_t index = 0; index < threadNodesCount; ++index) + { + threadNodesStuctsBuffer[index] = threadNodes[mTopologyReq.startIndex + index]; + } + response.threadTopology = + DataModel::List(threadNodesStuctsBuffer.Get(), threadNodesCount); + commandHandle->AddResponse(mCommandPath, response); +} + +void ServerInstance::HandleTopologyRequest(HandlerContext & ctx, const Commands::TopologyRequest::DecodableType & req) +{ + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + ReturnOnFailure(AddStatusOnError(ctx, CHIP_ERROR_UNINITIALIZED)); + } + mAsyncCommandHandle = CommandHandler::Handle(&ctx.mCommandHandler); + mTopologyReq = req; + ctx.mCommandHandler.FlushAcksRightAwayOnSlowCommand(); + CHIP_ERROR err = mDelegate->GetTopology(req.snapshot, this); + if (err != CHIP_NO_ERROR) + { + OnTopologyRequestFinished(MapChipErrorToIMStatus(err), 0, Span()); + } +} + +void ServerInstance::InvokeCommand(HandlerContext & ctx) +{ + if (mAsyncCommandHandle.Get() != nullptr) + { + // We have a command processing in the backend, reject all incoming commands. + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Busy); + ctx.SetCommandHandled(); + return; + } + mCommandPath = ctx.mRequestPath; + switch (ctx.mRequestPath.mCommandId) + { + case Commands::GetActiveDatasetRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandleGetActiveDatasetRequest(ctx, req); }); + return; + case Commands::GetPendingDatasetRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandleGetPendingDatasetRequest(ctx, req); }); + return; + case Commands::SetActiveDatasetRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandleSetActiveDatasetRequest(ctx, req); }); + return; + case Commands::SetPendingDatasetRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandleSetPendingDatasetRequest(ctx, req); }); + return; + case Commands::TopologyRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandleTopologyRequest(ctx, req); }); + return; + } +} + +CHIP_ERROR ServerInstance::ReadFeatureMap(AttributeValueEncoder & aEncoder) +{ + BitFlags featureMap; + bool panChangeSupported; + ReturnErrorOnFailure(mDelegate->GetPanChangeSupported(panChangeSupported)); + if (panChangeSupported) + { + featureMap.Set(Feature::kPANChange); + } + return aEncoder.Encode(featureMap); +} + +CHIP_ERROR ServerInstance::ReadBorderRouterName(AttributeValueEncoder & aEncoder) +{ + char borderRouterName[kBorderRouterNameMaxLength]; + MutableCharSpan borderRouterNameSpan(borderRouterName); + ReturnErrorOnFailure(mDelegate->GetBorderRouterName(borderRouterNameSpan)); + return aEncoder.Encode(chip::CharSpan(borderRouterName, borderRouterNameSpan.size())); +} + +CHIP_ERROR ServerInstance::ReadBorderAgentID(AttributeValueEncoder & aEncoder) +{ + uint8_t borderAgentId[kBorderAgentIdLength]; + MutableByteSpan borderAgentIdSpan(borderAgentId); + ReturnErrorOnFailure(mDelegate->GetBorderAgentId(borderAgentIdSpan)); + return aEncoder.Encode(chip::ByteSpan(borderAgentId)); +} + +CHIP_ERROR ServerInstance::ReadThreadVersion(AttributeValueEncoder & aEncoder) +{ + uint16_t threadVersion; + ReturnErrorOnFailure(mDelegate->GetThreadVersion(threadVersion)); + return aEncoder.Encode(threadVersion); +} + +CHIP_ERROR ServerInstance::ReadInterfaceEnabled(AttributeValueEncoder & aEncoder) +{ + bool interfaceEnabled; + ReturnErrorOnFailure(mDelegate->GetInterfaceEnabled(interfaceEnabled)); + return aEncoder.Encode(interfaceEnabled); +} + +CHIP_ERROR ServerInstance::ReadThreadNode(AttributeValueEncoder & aEncoder) +{ + Delegate::ThreadNode threadNode; + ReturnErrorOnFailure(mDelegate->GetThreadNode(threadNode)); + return aEncoder.Encode(threadNode); +} + +CHIP_ERROR ServerInstance::ReadActiveDatasetTimestamp(AttributeValueEncoder & aEncoder) +{ + Thread::OperationalDataset activeDataset; + uint64_t activeDatasetTimestamp; + if (mDelegate->GetActiveDataset(activeDataset) == CHIP_NO_ERROR && + activeDataset.GetActiveTimestamp(activeDatasetTimestamp) == CHIP_NO_ERROR) + { + return aEncoder.Encode(DataModel::MakeNullable(activeDatasetTimestamp)); + } + return aEncoder.Encode(DataModel::Nullable()); +} + +CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != ThreadBorderRouterManagement::Id) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (!mDelegate) + { + ChipLogError(Zcl, "Thread Border Router Management server not initialized"); + return CHIP_ERROR_UNINITIALIZED; + } + CHIP_ERROR status = CHIP_NO_ERROR; + switch (aPath.mAttributeId) + { + case Globals::Attributes::FeatureMap::Id: + status = ReadFeatureMap(aEncoder); + break; + case Attributes::BorderRouterName::Id: + status = ReadBorderRouterName(aEncoder); + break; + case Attributes::BorderAgentId::Id: + status = ReadBorderAgentID(aEncoder); + break; + case Attributes::ThreadVersion::Id: + status = ReadThreadVersion(aEncoder); + break; + case Attributes::InterfaceEnabled::Id: + status = ReadInterfaceEnabled(aEncoder); + break; + case Attributes::ThreadNode::Id: + status = ReadThreadNode(aEncoder); + break; + case Attributes::ActiveDatasetTimestamp::Id: + status = ReadActiveDatasetTimestamp(aEncoder); + break; + default: + break; + } + return status; +} + +CHIP_ERROR ServerInstance::Init() +{ + ReturnErrorCodeIf(!mDelegate, CHIP_ERROR_INVALID_ARGUMENT); + ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + return mDelegate->Init(); +} + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip + +void MatterThreadBorderRouterManagementPluginServerInitCallback() +{ + // Nothing to do, the server init routine will be done in Instance::Init() +} diff --git a/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.h b/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.h new file mode 100644 index 00000000000000..3ea8945fbad3c3 --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-br-mgmt-server.h @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "thread-br-delegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +class ServerInstance : public CommandHandlerInterface, public AttributeAccessInterface, public Delegate::Callback +{ +public: + ServerInstance(EndpointId endpointId, Delegate * delegate) : + CommandHandlerInterface(Optional(endpointId), Id), + AttributeAccessInterface(Optional(endpointId), Id), mDelegate(delegate) + {} + virtual ~ServerInstance() = default; + + CHIP_ERROR Init(); + + // CommandHanlerInterface + void InvokeCommand(HandlerContext & ctx) override; + + // AttributeAccessInterface + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + + // DelegateInterface + + void OnTopologyRequestFinished(Protocols::InteractionModel::Status status, uint8_t snapshot, + const Span & threadNodes) override; + +private: + // Command Handlers + void HandleGetActiveDatasetRequest(HandlerContext & ctx, const Commands::GetActiveDatasetRequest::DecodableType & req); + void HandleGetPendingDatasetRequest(HandlerContext & ctx, const Commands::GetPendingDatasetRequest::DecodableType & req); + void HandleSetActiveDatasetRequest(HandlerContext & ctx, const Commands::SetActiveDatasetRequest::DecodableType & req); + void HandleSetPendingDatasetRequest(HandlerContext & ctx, const Commands::SetPendingDatasetRequest::DecodableType & req); + void HandleTopologyRequest(HandlerContext & ctx, const Commands::TopologyRequest::DecodableType & req); + + // Attribute Read handler + CHIP_ERROR ReadFeatureMap(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadBorderRouterName(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadBorderAgentID(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadThreadVersion(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadInterfaceEnabled(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadThreadNode(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadActiveDatasetTimestamp(AttributeValueEncoder & aEncoder); + + Delegate * mDelegate; + app::CommandHandler::Handle mAsyncCommandHandle; + ConcreteCommandPath mCommandPath = ConcreteCommandPath(0, 0, 0); + Commands::TopologyRequest::DecodableType mTopologyReq; +}; + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 875cdbcdbd1514..b208c6c33388c8 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -40,6 +40,7 @@ CommandHandlerInterfaceOnlyClusters: - Device Energy Management Mode - Electrical Power Measurement - Electrical Energy Measurement + - Thread Border Router Management # We need a more configurable way of deciding which clusters have which init functions.... # See https://github.com/project-chip/connectedhomeip/issues/4369 diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 86d2085718291d..93cfb9e292d1cc 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -93,6 +93,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index 795f7a71cf54bc..1161f84b7afa90 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2427,6 +2427,21 @@ limitations under the License. + + MA-thread-border-router + HRAP + Matter Thread Border Router + 0x0103 + 0xFFF10011 + Simple + Endpoint + + + + + + + MA-all-clusters-app CHIP diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml new file mode 100644 index 00000000000000..fbbd6060fc3176 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HRAP + Thread Border Router Management + 0x0452 + THREAD_BORDER_ROUTER_MANAGEMENT + true + true + Thread BR management + + + + BorderRouterName + + BorderAgentId + + ThreadVersion + + InterfaceEnabled + + ThreadNode + + ActiveDatasetTimestamp + + + + On receipt of this command, the Thread Border Router will read the active operational dataset of the Thread network that it is connaected to, and send the DatasetResponse as the response. This command must be sent over a valid CASE session + + + + + On receipt of this command, the Thread Border Router will read the pending dataset and send the DatasetResponse as the response. This command must be sent over a valid CASE session + + + + + Generated response to GetActiveDatasetRequest or GetPendingDatasetRequest commands + + + + + On receipt of this command, the Thread Border Router will set or update the active Dataset of the Thread network that the Stub Router is connected to. + + + + + + + On receipt of this command, the Thread Border Router will set or update the pending Dataset + + + + + + On receipt of this command, the Thread Border Router will response the current topology of the Thread network that it is connected to. + + + + + + + + Generated response to TopologyRequest command + + + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 7213b96cf0e012..60ff2cc43c310b 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -115,6 +115,7 @@ "test-cluster.xml", "thermostat-cluster.xml", "thermostat-user-interface-configuration-cluster.xml", + "thread-border-router-management-cluster.xml", "thread-network-diagnostics-cluster.xml", "time-format-localization-cluster.xml", "time-synchronization-cluster.xml", @@ -289,6 +290,15 @@ "general_error_boolean", "cluster_error_boolean" ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentId", + "ThreadVersion", + "InterfaceEnabled", + "ThreadNode", + "ActiveDatasetTimestamp", + "FeatureMap" + ], "Thread Network Diagnostics": [ "Channel", "RoutingRole", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 8a4159e98f7eb8..e5c44b690f6ad9 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -113,6 +113,7 @@ "test-cluster.xml", "thermostat-cluster.xml", "thermostat-user-interface-configuration-cluster.xml", + "thread-border-router-management-cluster.xml", "thread-network-diagnostics-cluster.xml", "time-format-localization-cluster.xml", "time-synchronization-cluster.xml", @@ -287,6 +288,15 @@ "general_error_boolean", "cluster_error_boolean" ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentId", + "ThreadVersion", + "InterfaceEnabled", + "ThreadNode", + "ActiveDatasetTimestamp", + "FeatureMap" + ], "Thread Network Diagnostics": [ "Channel", "RoutingRole", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 2edfb272ad23e1..fb4c438bcb5d92 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -114,6 +114,7 @@ "TEMPERATURE_MEASUREMENT_CLUSTER": [], "THERMOSTAT_CLUSTER": ["thermostat-client"], "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER": [], + "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER": [], "THREAD_NETWORK_DIAGNOSTICS_CLUSTER": [], "TIME_CLUSTER": [], "TIME_FORMAT_LOCALIZATION_CLUSTER": [], @@ -286,6 +287,7 @@ "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER": [ "thermostat-user-interface-configuration-server" ], + "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER": [], "THREAD_NETWORK_DIAGNOSTICS_CLUSTER": [ "thread-network-diagnostics-server" ], diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index c559d1d0e9b129..222003cfc67f21 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -7654,6 +7654,106 @@ cluster RadonConcentrationMeasurement = 1071 { readonly attribute int16u clusterRevision = 65533; } +/** Thread BR management */ +cluster ThreadBorderRouterManagement = 1106 { + revision 1; + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPANChange = 0x1; + } + + struct ChildTableStruct { + int16u rloc16 = 0; + int8u linkQuality = 1; + RoutingRoleEnum routingRole = 2; + } + + struct RouteTableStruct { + int8u routerId = 0; + int8u pathCost = 1; + int8u LQIIn = 2; + int8u LQIOut = 3; + } + + struct ThreadNodeStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + octet_string IPv6s[] = 2; + RoutingRoleEnum routingRole = 3; + RouteTableStruct routeTable[] = 4; + ChildTableStruct childTable[] = 5; + } + + struct NeiborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + nullable int8s averageRssi = 3; + nullable int8s lastRssi = 4; + RoutingRoleEnum routingRole = 5; + } + + readonly attribute char_string<63> borderRouterName = 0; + readonly attribute octet_string<16> borderAgentId = 1; + readonly attribute int16u threadVersion = 2; + readonly attribute boolean interfaceEnabled = 3; + readonly attribute ThreadNodeStruct threadNode = 4; + readonly attribute nullable int64u activeDatasetTimestamp = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + response struct DatasetResponse = 2 { + octet_string<254> dataset = 0; + } + + request struct SetActiveDatasetRequestRequest { + octet_string<254> activeDataset = 0; + int64u breadcrumb = 1; + } + + request struct SetPendingDatasetRequestRequest { + octet_string<254> pendingDataset = 0; + } + + request struct TopologyRequestRequest { + int16u count = 0; + int16u startIndex = 1; + int8u snapshot = 2; + } + + response struct TopologyResponse = 6 { + status status = 0; + int8u snapshot = 1; + int16u numberOfDevices = 2; + ThreadNodeStruct threadTopology[] = 3; + } + + /** On receipt of this command, the Thread Border Router will read the active operational dataset of the Thread network that it is connaected to, and send the DatasetResponse as the response. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetActiveDatasetRequest(): DatasetResponse = 0; + /** On receipt of this command, the Thread Border Router will read the pending dataset and send the DatasetResponse as the response. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; + /** On receipt of this command, the Thread Border Router will set or update the active Dataset of the Thread network that the Stub Router is connected to. */ + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; + /** On receipt of this command, the Thread Border Router will set or update the pending Dataset */ + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; + /** On receipt of this command, the Thread Border Router will response the current topology of the Thread network that it is connected to. */ + command access(invoke: administer) TopologyRequest(TopologyRequestRequest): TopologyResponse = 5; +} + /** This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. */ cluster WakeOnLan = 1283 { revision 1; diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 66863228023a7b..f78b80e09cddf8 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -1180,6 +1180,106 @@ } ] }, + { + "name": "Thread Border Router Management", + "code": 1106, + "mfgCode": null, + "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "GetActiveDatasetRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetPendingDatasetRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "DatasetResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetActiveDatasetRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetPendingDatasetRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "TopologyRequest", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "TopologyResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, { "name": "Thread Network Diagnostics", "code": 53, diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 2e64d37cd62b11..951ccf9a6b73c6 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -52829,6 +52829,532 @@ public void onSuccess(byte[] tlv) { } } + public static class ThreadBorderRouterManagementCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1106L; + + private static final long BORDER_ROUTER_NAME_ATTRIBUTE_ID = 0L; + private static final long BORDER_AGENT_ID_ATTRIBUTE_ID = 1L; + private static final long THREAD_VERSION_ATTRIBUTE_ID = 2L; + private static final long INTERFACE_ENABLED_ATTRIBUTE_ID = 3L; + private static final long THREAD_NODE_ATTRIBUTE_ID = 4L; + private static final long ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID = 5L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public ThreadBorderRouterManagementCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void getActiveDatasetRequest(DatasetResponseCallback callback) { + getActiveDatasetRequest(callback, 0); + } + + public void getActiveDatasetRequest(DatasetResponseCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long datasetFieldID = 0L; + byte[] dataset = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == datasetFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + dataset = castingValue.value(byte[].class); + } + } + } + callback.onSuccess(dataset); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void getPendingDatasetRequest(DatasetResponseCallback callback) { + getPendingDatasetRequest(callback, 0); + } + + public void getPendingDatasetRequest(DatasetResponseCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long datasetFieldID = 0L; + byte[] dataset = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == datasetFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + dataset = castingValue.value(byte[].class); + } + } + } + callback.onSuccess(dataset); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void setActiveDatasetRequest(DefaultClusterCallback callback, byte[] activeDataset, Long breadcrumb) { + setActiveDatasetRequest(callback, activeDataset, breadcrumb, 0); + } + + public void setActiveDatasetRequest(DefaultClusterCallback callback, byte[] activeDataset, Long breadcrumb, int timedInvokeTimeoutMs) { + final long commandId = 3L; + + ArrayList elements = new ArrayList<>(); + final long activeDatasetFieldID = 0L; + BaseTLVType activeDatasettlvValue = new ByteArrayType(activeDataset); + elements.add(new StructElement(activeDatasetFieldID, activeDatasettlvValue)); + + final long breadcrumbFieldID = 1L; + BaseTLVType breadcrumbtlvValue = new UIntType(breadcrumb); + elements.add(new StructElement(breadcrumbFieldID, breadcrumbtlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void setPendingDatasetRequest(DefaultClusterCallback callback, byte[] pendingDataset) { + setPendingDatasetRequest(callback, pendingDataset, 0); + } + + public void setPendingDatasetRequest(DefaultClusterCallback callback, byte[] pendingDataset, int timedInvokeTimeoutMs) { + final long commandId = 4L; + + ArrayList elements = new ArrayList<>(); + final long pendingDatasetFieldID = 0L; + BaseTLVType pendingDatasettlvValue = new ByteArrayType(pendingDataset); + elements.add(new StructElement(pendingDatasetFieldID, pendingDatasettlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void topologyRequest(TopologyResponseCallback callback, Integer count, Integer startIndex, Integer snapshot) { + topologyRequest(callback, count, startIndex, snapshot, 0); + } + + public void topologyRequest(TopologyResponseCallback callback, Integer count, Integer startIndex, Integer snapshot, int timedInvokeTimeoutMs) { + final long commandId = 5L; + + ArrayList elements = new ArrayList<>(); + final long countFieldID = 0L; + BaseTLVType counttlvValue = new UIntType(count); + elements.add(new StructElement(countFieldID, counttlvValue)); + + final long startIndexFieldID = 1L; + BaseTLVType startIndextlvValue = new UIntType(startIndex); + elements.add(new StructElement(startIndexFieldID, startIndextlvValue)); + + final long snapshotFieldID = 2L; + BaseTLVType snapshottlvValue = new UIntType(snapshot); + elements.add(new StructElement(snapshotFieldID, snapshottlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long snapshotFieldID = 1L; + Integer snapshot = null; + final long numberOfDevicesFieldID = 2L; + Integer numberOfDevices = null; + final long threadTopologyFieldID = 3L; + ArrayList threadTopology = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == statusFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == snapshotFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + snapshot = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == numberOfDevicesFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + numberOfDevices = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == threadTopologyFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + threadTopology = castingValue.map((elementcastingValue) -> ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct.decodeTlv(elementcastingValue)); + } + } + } + callback.onSuccess(status, snapshot, numberOfDevices, threadTopology); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface DatasetResponseCallback extends BaseClusterCallback { + void onSuccess(byte[] dataset); + } + + public interface TopologyResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Integer snapshot, Integer numberOfDevices, ArrayList threadTopology); + } + + public interface ThreadNodeAttributeCallback extends BaseAttributeCallback { + void onSuccess(ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct value); + } + + public interface ActiveDatasetTimestampAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readBorderRouterNameAttribute( + CharStringAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BORDER_ROUTER_NAME_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BORDER_ROUTER_NAME_ATTRIBUTE_ID, true); + } + + public void subscribeBorderRouterNameAttribute( + CharStringAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BORDER_ROUTER_NAME_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BORDER_ROUTER_NAME_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readBorderAgentIdAttribute( + OctetStringAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BORDER_AGENT_ID_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + byte[] value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BORDER_AGENT_ID_ATTRIBUTE_ID, true); + } + + public void subscribeBorderAgentIdAttribute( + OctetStringAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BORDER_AGENT_ID_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + byte[] value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BORDER_AGENT_ID_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readThreadVersionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_VERSION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_VERSION_ATTRIBUTE_ID, true); + } + + public void subscribeThreadVersionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_VERSION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_VERSION_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readInterfaceEnabledAttribute( + BooleanAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, INTERFACE_ENABLED_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, INTERFACE_ENABLED_ATTRIBUTE_ID, true); + } + + public void subscribeInterfaceEnabledAttribute( + BooleanAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, INTERFACE_ENABLED_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, INTERFACE_ENABLED_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readThreadNodeAttribute( + ThreadNodeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NODE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NODE_ATTRIBUTE_ID, true); + } + + public void subscribeThreadNodeAttribute( + ThreadNodeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NODE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NODE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readActiveDatasetTimestampAttribute( + ActiveDatasetTimestampAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID, true); + } + + public void subscribeActiveDatasetTimestampAttribute( + ActiveDatasetTimestampAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class WakeOnLanCluster extends BaseChipCluster { public static final long CLUSTER_ID = 1283L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 7730f05efe734a..4b452ae234f6fe 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -9277,6 +9277,415 @@ public String toString() { return output.toString(); } } +public static class ThreadBorderRouterManagementClusterChildTableStruct { + public Integer rloc16; + public Integer linkQuality; + public Integer routingRole; + private static final long RLOC16_ID = 0L; + private static final long LINK_QUALITY_ID = 1L; + private static final long ROUTING_ROLE_ID = 2L; + + public ThreadBorderRouterManagementClusterChildTableStruct( + Integer rloc16, + Integer linkQuality, + Integer routingRole + ) { + this.rloc16 = rloc16; + this.linkQuality = linkQuality; + this.routingRole = routingRole; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(RLOC16_ID, new UIntType(rloc16))); + values.add(new StructElement(LINK_QUALITY_ID, new UIntType(linkQuality))); + values.add(new StructElement(ROUTING_ROLE_ID, new UIntType(routingRole))); + + return new StructType(values); + } + + public static ThreadBorderRouterManagementClusterChildTableStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer rloc16 = null; + Integer linkQuality = null; + Integer routingRole = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == RLOC16_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + rloc16 = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == LINK_QUALITY_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + linkQuality = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == ROUTING_ROLE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + routingRole = castingValue.value(Integer.class); + } + } + } + return new ThreadBorderRouterManagementClusterChildTableStruct( + rloc16, + linkQuality, + routingRole + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadBorderRouterManagementClusterChildTableStruct {\n"); + output.append("\trloc16: "); + output.append(rloc16); + output.append("\n"); + output.append("\tlinkQuality: "); + output.append(linkQuality); + output.append("\n"); + output.append("\troutingRole: "); + output.append(routingRole); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ThreadBorderRouterManagementClusterRouteTableStruct { + public Integer routerId; + public Integer pathCost; + public Integer LQIIn; + public Integer LQIOut; + private static final long ROUTER_ID_ID = 0L; + private static final long PATH_COST_ID = 1L; + private static final long L_Q_I_IN_ID = 2L; + private static final long L_Q_I_OUT_ID = 3L; + + public ThreadBorderRouterManagementClusterRouteTableStruct( + Integer routerId, + Integer pathCost, + Integer LQIIn, + Integer LQIOut + ) { + this.routerId = routerId; + this.pathCost = pathCost; + this.LQIIn = LQIIn; + this.LQIOut = LQIOut; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(ROUTER_ID_ID, new UIntType(routerId))); + values.add(new StructElement(PATH_COST_ID, new UIntType(pathCost))); + values.add(new StructElement(L_Q_I_IN_ID, new UIntType(LQIIn))); + values.add(new StructElement(L_Q_I_OUT_ID, new UIntType(LQIOut))); + + return new StructType(values); + } + + public static ThreadBorderRouterManagementClusterRouteTableStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer routerId = null; + Integer pathCost = null; + Integer LQIIn = null; + Integer LQIOut = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == ROUTER_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + routerId = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == PATH_COST_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + pathCost = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == L_Q_I_IN_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + LQIIn = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == L_Q_I_OUT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + LQIOut = castingValue.value(Integer.class); + } + } + } + return new ThreadBorderRouterManagementClusterRouteTableStruct( + routerId, + pathCost, + LQIIn, + LQIOut + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadBorderRouterManagementClusterRouteTableStruct {\n"); + output.append("\trouterId: "); + output.append(routerId); + output.append("\n"); + output.append("\tpathCost: "); + output.append(pathCost); + output.append("\n"); + output.append("\tLQIIn: "); + output.append(LQIIn); + output.append("\n"); + output.append("\tLQIOut: "); + output.append(LQIOut); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ThreadBorderRouterManagementClusterThreadNodeStruct { + public Long extAddress; + public Integer rloc16; + public ArrayList IPv6s; + public Integer routingRole; + public ArrayList routeTable; + public ArrayList childTable; + private static final long EXT_ADDRESS_ID = 0L; + private static final long RLOC16_ID = 1L; + private static final long I_PV6S_ID = 2L; + private static final long ROUTING_ROLE_ID = 3L; + private static final long ROUTE_TABLE_ID = 4L; + private static final long CHILD_TABLE_ID = 5L; + + public ThreadBorderRouterManagementClusterThreadNodeStruct( + Long extAddress, + Integer rloc16, + ArrayList IPv6s, + Integer routingRole, + ArrayList routeTable, + ArrayList childTable + ) { + this.extAddress = extAddress; + this.rloc16 = rloc16; + this.IPv6s = IPv6s; + this.routingRole = routingRole; + this.routeTable = routeTable; + this.childTable = childTable; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(EXT_ADDRESS_ID, new UIntType(extAddress))); + values.add(new StructElement(RLOC16_ID, new UIntType(rloc16))); + values.add(new StructElement(I_PV6S_ID, ArrayType.generateArrayType(IPv6s, (elementIPv6s) -> new ByteArrayType(elementIPv6s)))); + values.add(new StructElement(ROUTING_ROLE_ID, new UIntType(routingRole))); + values.add(new StructElement(ROUTE_TABLE_ID, ArrayType.generateArrayType(routeTable, (elementrouteTable) -> elementrouteTable.encodeTlv()))); + values.add(new StructElement(CHILD_TABLE_ID, ArrayType.generateArrayType(childTable, (elementchildTable) -> elementchildTable.encodeTlv()))); + + return new StructType(values); + } + + public static ThreadBorderRouterManagementClusterThreadNodeStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long extAddress = null; + Integer rloc16 = null; + ArrayList IPv6s = null; + Integer routingRole = null; + ArrayList routeTable = null; + ArrayList childTable = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == EXT_ADDRESS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + extAddress = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == RLOC16_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + rloc16 = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == I_PV6S_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + IPv6s = castingValue.map((elementcastingValue) -> elementcastingValue.value(byte[].class)); + } + } else if (element.contextTagNum() == ROUTING_ROLE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + routingRole = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == ROUTE_TABLE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + routeTable = castingValue.map((elementcastingValue) -> ChipStructs.ThreadBorderRouterManagementClusterRouteTableStruct.decodeTlv(elementcastingValue)); + } + } else if (element.contextTagNum() == CHILD_TABLE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + childTable = castingValue.map((elementcastingValue) -> ChipStructs.ThreadBorderRouterManagementClusterChildTableStruct.decodeTlv(elementcastingValue)); + } + } + } + return new ThreadBorderRouterManagementClusterThreadNodeStruct( + extAddress, + rloc16, + IPv6s, + routingRole, + routeTable, + childTable + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadBorderRouterManagementClusterThreadNodeStruct {\n"); + output.append("\textAddress: "); + output.append(extAddress); + output.append("\n"); + output.append("\trloc16: "); + output.append(rloc16); + output.append("\n"); + output.append("\tIPv6s: "); + output.append(IPv6s); + output.append("\n"); + output.append("\troutingRole: "); + output.append(routingRole); + output.append("\n"); + output.append("\trouteTable: "); + output.append(routeTable); + output.append("\n"); + output.append("\tchildTable: "); + output.append(childTable); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ThreadBorderRouterManagementClusterNeiborTableStruct { + public Long extAddress; + public Long age; + public Integer rloc16; + public @Nullable Integer averageRssi; + public @Nullable Integer lastRssi; + public Integer routingRole; + private static final long EXT_ADDRESS_ID = 0L; + private static final long AGE_ID = 1L; + private static final long RLOC16_ID = 2L; + private static final long AVERAGE_RSSI_ID = 3L; + private static final long LAST_RSSI_ID = 4L; + private static final long ROUTING_ROLE_ID = 5L; + + public ThreadBorderRouterManagementClusterNeiborTableStruct( + Long extAddress, + Long age, + Integer rloc16, + @Nullable Integer averageRssi, + @Nullable Integer lastRssi, + Integer routingRole + ) { + this.extAddress = extAddress; + this.age = age; + this.rloc16 = rloc16; + this.averageRssi = averageRssi; + this.lastRssi = lastRssi; + this.routingRole = routingRole; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(EXT_ADDRESS_ID, new UIntType(extAddress))); + values.add(new StructElement(AGE_ID, new UIntType(age))); + values.add(new StructElement(RLOC16_ID, new UIntType(rloc16))); + values.add(new StructElement(AVERAGE_RSSI_ID, averageRssi != null ? new IntType(averageRssi) : new NullType())); + values.add(new StructElement(LAST_RSSI_ID, lastRssi != null ? new IntType(lastRssi) : new NullType())); + values.add(new StructElement(ROUTING_ROLE_ID, new UIntType(routingRole))); + + return new StructType(values); + } + + public static ThreadBorderRouterManagementClusterNeiborTableStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long extAddress = null; + Long age = null; + Integer rloc16 = null; + @Nullable Integer averageRssi = null; + @Nullable Integer lastRssi = null; + Integer routingRole = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == EXT_ADDRESS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + extAddress = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == AGE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + age = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == RLOC16_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + rloc16 = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == AVERAGE_RSSI_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + averageRssi = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == LAST_RSSI_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + lastRssi = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == ROUTING_ROLE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + routingRole = castingValue.value(Integer.class); + } + } + } + return new ThreadBorderRouterManagementClusterNeiborTableStruct( + extAddress, + age, + rloc16, + averageRssi, + lastRssi, + routingRole + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadBorderRouterManagementClusterNeiborTableStruct {\n"); + output.append("\textAddress: "); + output.append(extAddress); + output.append("\n"); + output.append("\tage: "); + output.append(age); + output.append("\n"); + output.append("\trloc16: "); + output.append(rloc16); + output.append("\n"); + output.append("\taverageRssi: "); + output.append(averageRssi); + output.append("\n"); + output.append("\tlastRssi: "); + output.append(lastRssi); + output.append("\n"); + output.append("\troutingRole: "); + output.append(routingRole); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class ChannelClusterProgramCastStruct { public String name; public String role; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 3437b8a981e476..2b4ccc41351393 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -328,6 +328,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == RadonConcentrationMeasurement.ID) { return new RadonConcentrationMeasurement(); } + if (clusterId == ThreadBorderRouterManagement.ID) { + return new ThreadBorderRouterManagement(); + } if (clusterId == WakeOnLan.ID) { return new WakeOnLan(); } @@ -14313,6 +14316,168 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class ThreadBorderRouterManagement implements BaseCluster { + public static final long ID = 1106L; + public long getID() { + return ID; + } + + public enum Attribute { + BorderRouterName(0L), + BorderAgentId(1L), + ThreadVersion(2L), + InterfaceEnabled(3L), + ThreadNode(4L), + ActiveDatasetTimestamp(5L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + GetActiveDatasetRequest(0L), + GetPendingDatasetRequest(1L), + SetActiveDatasetRequest(3L), + SetPendingDatasetRequest(4L), + TopologyRequest(5L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum SetActiveDatasetRequestCommandField {ActiveDataset(0),Breadcrumb(1),; + private final int id; + SetActiveDatasetRequestCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static SetActiveDatasetRequestCommandField value(int id) throws NoSuchFieldError { + for (SetActiveDatasetRequestCommandField field : SetActiveDatasetRequestCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum SetPendingDatasetRequestCommandField {PendingDataset(0),; + private final int id; + SetPendingDatasetRequestCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static SetPendingDatasetRequestCommandField value(int id) throws NoSuchFieldError { + for (SetPendingDatasetRequestCommandField field : SetPendingDatasetRequestCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum TopologyRequestCommandField {Count(0),StartIndex(1),Snapshot(2),; + private final int id; + TopologyRequestCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static TopologyRequestCommandField value(int id) throws NoSuchFieldError { + for (TopologyRequestCommandField field : TopologyRequestCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class WakeOnLan implements BaseCluster { public static final long ID = 1283L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 4ded328fad6ed5..d5ec5fb7b0e6c4 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -17299,6 +17299,183 @@ public void onError(Exception ex) { } } + + public static class DelegatedThreadBorderRouterManagementClusterDatasetResponseCallback implements ChipClusters.ThreadBorderRouterManagementCluster.DatasetResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(byte[] dataset) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo datasetResponseValue = new CommandResponseInfo("dataset", "byte[]"); + responseValues.put(datasetResponseValue, dataset); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterTopologyResponseCallback implements ChipClusters.ThreadBorderRouterManagementCluster.TopologyResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer status, Integer snapshot, Integer numberOfDevices, ArrayList threadTopology) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); + responseValues.put(statusResponseValue, status); + CommandResponseInfo snapshotResponseValue = new CommandResponseInfo("snapshot", "Integer"); + responseValues.put(snapshotResponseValue, snapshot); + CommandResponseInfo numberOfDevicesResponseValue = new CommandResponseInfo("numberOfDevices", "Integer"); + responseValues.put(numberOfDevicesResponseValue, numberOfDevices); + // threadTopology: ThreadNodeStruct + // Conversion from this type to Java is not properly implemented yet + + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedThreadBorderRouterManagementClusterThreadNodeAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.ThreadNodeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.ThreadBorderRouterManagementClusterThreadNodeStruct"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterActiveDatasetTimestampAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.ActiveDatasetTimestampAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterGeneratedCommandListAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterAcceptedCommandListAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterEventListAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadBorderRouterManagementClusterAttributeListAttributeCallback implements ChipClusters.ThreadBorderRouterManagementCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedWakeOnLanClusterGeneratedCommandListAttributeCallback implements ChipClusters.WakeOnLanCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21177,6 +21354,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.RadonConcentrationMeasurementCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("radonConcentrationMeasurement", radonConcentrationMeasurementClusterInfo); + ClusterInfo threadBorderRouterManagementClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.ThreadBorderRouterManagementCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("threadBorderRouterManagement", threadBorderRouterManagementClusterInfo); + ClusterInfo wakeOnLanClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.WakeOnLanCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("wakeOnLan", wakeOnLanClusterInfo); @@ -21353,6 +21534,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("radonConcentrationMeasurement", radonConcentrationMeasurementClusterInteractionInfoMap); + Map threadBorderRouterManagementClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map threadBorderRouterManagementgetActiveDatasetRequestCommandParams = new LinkedHashMap(); + InteractionInfo threadBorderRouterManagementgetActiveDatasetRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster) + .getActiveDatasetRequest((ChipClusters.ThreadBorderRouterManagementCluster.DatasetResponseCallback) callback + ); + }, + () -> new DelegatedThreadBorderRouterManagementClusterDatasetResponseCallback(), + threadBorderRouterManagementgetActiveDatasetRequestCommandParams + ); + threadBorderRouterManagementClusterInteractionInfoMap.put("getActiveDatasetRequest", threadBorderRouterManagementgetActiveDatasetRequestInteractionInfo); + + Map threadBorderRouterManagementgetPendingDatasetRequestCommandParams = new LinkedHashMap(); + InteractionInfo threadBorderRouterManagementgetPendingDatasetRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster) + .getPendingDatasetRequest((ChipClusters.ThreadBorderRouterManagementCluster.DatasetResponseCallback) callback + ); + }, + () -> new DelegatedThreadBorderRouterManagementClusterDatasetResponseCallback(), + threadBorderRouterManagementgetPendingDatasetRequestCommandParams + ); + threadBorderRouterManagementClusterInteractionInfoMap.put("getPendingDatasetRequest", threadBorderRouterManagementgetPendingDatasetRequestInteractionInfo); + + Map threadBorderRouterManagementsetActiveDatasetRequestCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadBorderRouterManagementsetActiveDatasetRequestactiveDatasetCommandParameterInfo = new CommandParameterInfo("activeDataset", byte[].class, byte[].class); + threadBorderRouterManagementsetActiveDatasetRequestCommandParams.put("activeDataset",threadBorderRouterManagementsetActiveDatasetRequestactiveDatasetCommandParameterInfo); + + CommandParameterInfo threadBorderRouterManagementsetActiveDatasetRequestbreadcrumbCommandParameterInfo = new CommandParameterInfo("breadcrumb", Long.class, Long.class); + threadBorderRouterManagementsetActiveDatasetRequestCommandParams.put("breadcrumb",threadBorderRouterManagementsetActiveDatasetRequestbreadcrumbCommandParameterInfo); + InteractionInfo threadBorderRouterManagementsetActiveDatasetRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster) + .setActiveDatasetRequest((DefaultClusterCallback) callback + , (byte[]) + commandArguments.get("activeDataset") + , (Long) + commandArguments.get("breadcrumb") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + threadBorderRouterManagementsetActiveDatasetRequestCommandParams + ); + threadBorderRouterManagementClusterInteractionInfoMap.put("setActiveDatasetRequest", threadBorderRouterManagementsetActiveDatasetRequestInteractionInfo); + + Map threadBorderRouterManagementsetPendingDatasetRequestCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadBorderRouterManagementsetPendingDatasetRequestpendingDatasetCommandParameterInfo = new CommandParameterInfo("pendingDataset", byte[].class, byte[].class); + threadBorderRouterManagementsetPendingDatasetRequestCommandParams.put("pendingDataset",threadBorderRouterManagementsetPendingDatasetRequestpendingDatasetCommandParameterInfo); + InteractionInfo threadBorderRouterManagementsetPendingDatasetRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster) + .setPendingDatasetRequest((DefaultClusterCallback) callback + , (byte[]) + commandArguments.get("pendingDataset") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + threadBorderRouterManagementsetPendingDatasetRequestCommandParams + ); + threadBorderRouterManagementClusterInteractionInfoMap.put("setPendingDatasetRequest", threadBorderRouterManagementsetPendingDatasetRequestInteractionInfo); + + Map threadBorderRouterManagementtopologyRequestCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadBorderRouterManagementtopologyRequestcountCommandParameterInfo = new CommandParameterInfo("count", Integer.class, Integer.class); + threadBorderRouterManagementtopologyRequestCommandParams.put("count",threadBorderRouterManagementtopologyRequestcountCommandParameterInfo); + + CommandParameterInfo threadBorderRouterManagementtopologyRequeststartIndexCommandParameterInfo = new CommandParameterInfo("startIndex", Integer.class, Integer.class); + threadBorderRouterManagementtopologyRequestCommandParams.put("startIndex",threadBorderRouterManagementtopologyRequeststartIndexCommandParameterInfo); + + CommandParameterInfo threadBorderRouterManagementtopologyRequestsnapshotCommandParameterInfo = new CommandParameterInfo("snapshot", Integer.class, Integer.class); + threadBorderRouterManagementtopologyRequestCommandParams.put("snapshot",threadBorderRouterManagementtopologyRequestsnapshotCommandParameterInfo); + InteractionInfo threadBorderRouterManagementtopologyRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster) + .topologyRequest((ChipClusters.ThreadBorderRouterManagementCluster.TopologyResponseCallback) callback + , (Integer) + commandArguments.get("count") + + , (Integer) + commandArguments.get("startIndex") + + , (Integer) + commandArguments.get("snapshot") + + ); + }, + () -> new DelegatedThreadBorderRouterManagementClusterTopologyResponseCallback(), + threadBorderRouterManagementtopologyRequestCommandParams + ); + threadBorderRouterManagementClusterInteractionInfoMap.put("topologyRequest", threadBorderRouterManagementtopologyRequestInteractionInfo); + + commandMap.put("threadBorderRouterManagement", threadBorderRouterManagementClusterInteractionInfoMap); + Map wakeOnLanClusterInteractionInfoMap = new LinkedHashMap<>(); commandMap.put("wakeOnLan", wakeOnLanClusterInteractionInfoMap); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index cc18af0810cc10..1f6165d3abf7d3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -16529,6 +16529,131 @@ private static Map readRadonConcentrationMeasurementInt return result; } + private static Map readThreadBorderRouterManagementInteractionInfo() { + Map result = new LinkedHashMap<>();Map readThreadBorderRouterManagementBorderRouterNameCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementBorderRouterNameAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readBorderRouterNameAttribute( + (ChipClusters.CharStringAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCharStringAttributeCallback(), + readThreadBorderRouterManagementBorderRouterNameCommandParams + ); + result.put("readBorderRouterNameAttribute", readThreadBorderRouterManagementBorderRouterNameAttributeInteractionInfo); + Map readThreadBorderRouterManagementBorderAgentIdCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementBorderAgentIdAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readBorderAgentIdAttribute( + (ChipClusters.OctetStringAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedOctetStringAttributeCallback(), + readThreadBorderRouterManagementBorderAgentIdCommandParams + ); + result.put("readBorderAgentIdAttribute", readThreadBorderRouterManagementBorderAgentIdAttributeInteractionInfo); + Map readThreadBorderRouterManagementThreadVersionCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementThreadVersionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readThreadVersionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readThreadBorderRouterManagementThreadVersionCommandParams + ); + result.put("readThreadVersionAttribute", readThreadBorderRouterManagementThreadVersionAttributeInteractionInfo); + Map readThreadBorderRouterManagementInterfaceEnabledCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementInterfaceEnabledAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readInterfaceEnabledAttribute( + (ChipClusters.BooleanAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedBooleanAttributeCallback(), + readThreadBorderRouterManagementInterfaceEnabledCommandParams + ); + result.put("readInterfaceEnabledAttribute", readThreadBorderRouterManagementInterfaceEnabledAttributeInteractionInfo); + Map readThreadBorderRouterManagementActiveDatasetTimestampCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementActiveDatasetTimestampAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readActiveDatasetTimestampAttribute( + (ChipClusters.ThreadBorderRouterManagementCluster.ActiveDatasetTimestampAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadBorderRouterManagementClusterActiveDatasetTimestampAttributeCallback(), + readThreadBorderRouterManagementActiveDatasetTimestampCommandParams + ); + result.put("readActiveDatasetTimestampAttribute", readThreadBorderRouterManagementActiveDatasetTimestampAttributeInteractionInfo); + Map readThreadBorderRouterManagementGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.ThreadBorderRouterManagementCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadBorderRouterManagementClusterGeneratedCommandListAttributeCallback(), + readThreadBorderRouterManagementGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readThreadBorderRouterManagementGeneratedCommandListAttributeInteractionInfo); + Map readThreadBorderRouterManagementAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.ThreadBorderRouterManagementCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadBorderRouterManagementClusterAcceptedCommandListAttributeCallback(), + readThreadBorderRouterManagementAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readThreadBorderRouterManagementAcceptedCommandListAttributeInteractionInfo); + Map readThreadBorderRouterManagementEventListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readEventListAttribute( + (ChipClusters.ThreadBorderRouterManagementCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadBorderRouterManagementClusterEventListAttributeCallback(), + readThreadBorderRouterManagementEventListCommandParams + ); + result.put("readEventListAttribute", readThreadBorderRouterManagementEventListAttributeInteractionInfo); + Map readThreadBorderRouterManagementAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readAttributeListAttribute( + (ChipClusters.ThreadBorderRouterManagementCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadBorderRouterManagementClusterAttributeListAttributeCallback(), + readThreadBorderRouterManagementAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readThreadBorderRouterManagementAttributeListAttributeInteractionInfo); + Map readThreadBorderRouterManagementFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readThreadBorderRouterManagementFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readThreadBorderRouterManagementFeatureMapAttributeInteractionInfo); + Map readThreadBorderRouterManagementClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readThreadBorderRouterManagementClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadBorderRouterManagementCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readThreadBorderRouterManagementClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readThreadBorderRouterManagementClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readWakeOnLanInteractionInfo() { Map result = new LinkedHashMap<>();Map readWakeOnLanMACAddressCommandParams = new LinkedHashMap(); InteractionInfo readWakeOnLanMACAddressAttributeInteractionInfo = new InteractionInfo( @@ -20588,6 +20713,7 @@ public Map> getReadAttributeMap() { put("pm10ConcentrationMeasurement", readPm10ConcentrationMeasurementInteractionInfo()); put("totalVolatileOrganicCompoundsConcentrationMeasurement", readTotalVolatileOrganicCompoundsConcentrationMeasurementInteractionInfo()); put("radonConcentrationMeasurement", readRadonConcentrationMeasurementInteractionInfo()); + put("threadBorderRouterManagement", readThreadBorderRouterManagementInteractionInfo()); put("wakeOnLan", readWakeOnLanInteractionInfo()); put("channel", readChannelInteractionInfo()); put("targetNavigator", readTargetNavigatorInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 0e5a32b23f04c4..833a9af6e27cac 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -3636,6 +3636,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("totalVolatileOrganicCompoundsConcentrationMeasurement", writeTotalVolatileOrganicCompoundsConcentrationMeasurementInteractionInfo); Map writeRadonConcentrationMeasurementInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("radonConcentrationMeasurement", writeRadonConcentrationMeasurementInteractionInfo); + Map writeThreadBorderRouterManagementInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("threadBorderRouterManagement", writeThreadBorderRouterManagementInteractionInfo); Map writeWakeOnLanInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("wakeOnLan", writeWakeOnLanInteractionInfo); Map writeChannelInteractionInfo = new LinkedHashMap<>(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index 34fd21bb27d770..52e323444fa65f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -123,6 +123,10 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterScheduleTransitionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterScheduleTypeStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterWeeklyScheduleTransitionStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterNeighborTableStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt new file mode 100644 index 00000000000000..a9146b6581a846 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterChildTableStruct( + val rloc16: UInt, + val linkQuality: UInt, + val routingRole: UInt +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterChildTableStruct {\n") + append("\trloc16 : $rloc16\n") + append("\tlinkQuality : $linkQuality\n") + append("\troutingRole : $routingRole\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + put(ContextSpecificTag(TAG_LINK_QUALITY), linkQuality) + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + endStructure() + } + } + + companion object { + private const val TAG_RLOC16 = 0 + private const val TAG_LINK_QUALITY = 1 + private const val TAG_ROUTING_ROLE = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterChildTableStruct { + tlvReader.enterStructure(tlvTag) + val rloc16 = tlvReader.getUInt(ContextSpecificTag(TAG_RLOC16)) + val linkQuality = tlvReader.getUInt(ContextSpecificTag(TAG_LINK_QUALITY)) + val routingRole = tlvReader.getUInt(ContextSpecificTag(TAG_ROUTING_ROLE)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterChildTableStruct(rloc16, linkQuality, routingRole) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt new file mode 100644 index 00000000000000..49aab4a8c13c81 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterNeiborTableStruct( + val extAddress: ULong, + val age: ULong, + val rloc16: UInt, + val averageRssi: Int?, + val lastRssi: Int?, + val routingRole: UInt +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterNeiborTableStruct {\n") + append("\textAddress : $extAddress\n") + append("\tage : $age\n") + append("\trloc16 : $rloc16\n") + append("\taverageRssi : $averageRssi\n") + append("\tlastRssi : $lastRssi\n") + append("\troutingRole : $routingRole\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXT_ADDRESS), extAddress) + put(ContextSpecificTag(TAG_AGE), age) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + if (averageRssi != null) { + put(ContextSpecificTag(TAG_AVERAGE_RSSI), averageRssi) + } else { + putNull(ContextSpecificTag(TAG_AVERAGE_RSSI)) + } + if (lastRssi != null) { + put(ContextSpecificTag(TAG_LAST_RSSI), lastRssi) + } else { + putNull(ContextSpecificTag(TAG_LAST_RSSI)) + } + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + endStructure() + } + } + + companion object { + private const val TAG_EXT_ADDRESS = 0 + private const val TAG_AGE = 1 + private const val TAG_RLOC16 = 2 + private const val TAG_AVERAGE_RSSI = 3 + private const val TAG_LAST_RSSI = 4 + private const val TAG_ROUTING_ROLE = 5 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterNeiborTableStruct { + tlvReader.enterStructure(tlvTag) + val extAddress = tlvReader.getULong(ContextSpecificTag(TAG_EXT_ADDRESS)) + val age = tlvReader.getULong(ContextSpecificTag(TAG_AGE)) + val rloc16 = tlvReader.getUInt(ContextSpecificTag(TAG_RLOC16)) + val averageRssi = + if (!tlvReader.isNull()) { + tlvReader.getInt(ContextSpecificTag(TAG_AVERAGE_RSSI)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AVERAGE_RSSI)) + null + } + val lastRssi = + if (!tlvReader.isNull()) { + tlvReader.getInt(ContextSpecificTag(TAG_LAST_RSSI)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LAST_RSSI)) + null + } + val routingRole = tlvReader.getUInt(ContextSpecificTag(TAG_ROUTING_ROLE)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterNeiborTableStruct( + extAddress, + age, + rloc16, + averageRssi, + lastRssi, + routingRole + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt new file mode 100644 index 00000000000000..12b5fb6e9e0e3d --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterRouteTableStruct( + val routerId: UInt, + val pathCost: UInt, + val LQIIn: UInt, + val LQIOut: UInt +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterRouteTableStruct {\n") + append("\trouterId : $routerId\n") + append("\tpathCost : $pathCost\n") + append("\tLQIIn : $LQIIn\n") + append("\tLQIOut : $LQIOut\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ROUTER_ID), routerId) + put(ContextSpecificTag(TAG_PATH_COST), pathCost) + put(ContextSpecificTag(TAG_L_Q_I_IN), LQIIn) + put(ContextSpecificTag(TAG_L_Q_I_OUT), LQIOut) + endStructure() + } + } + + companion object { + private const val TAG_ROUTER_ID = 0 + private const val TAG_PATH_COST = 1 + private const val TAG_L_Q_I_IN = 2 + private const val TAG_L_Q_I_OUT = 3 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterRouteTableStruct { + tlvReader.enterStructure(tlvTag) + val routerId = tlvReader.getUInt(ContextSpecificTag(TAG_ROUTER_ID)) + val pathCost = tlvReader.getUInt(ContextSpecificTag(TAG_PATH_COST)) + val LQIIn = tlvReader.getUInt(ContextSpecificTag(TAG_L_Q_I_IN)) + val LQIOut = tlvReader.getUInt(ContextSpecificTag(TAG_L_Q_I_OUT)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterRouteTableStruct(routerId, pathCost, LQIIn, LQIOut) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt new file mode 100644 index 00000000000000..bfe71bce903319 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterThreadNodeStruct( + val extAddress: ULong, + val rloc16: UInt, + val IPv6s: List, + val routingRole: UInt, + val routeTable: List, + val childTable: List +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterThreadNodeStruct {\n") + append("\textAddress : $extAddress\n") + append("\trloc16 : $rloc16\n") + append("\tIPv6s : $IPv6s\n") + append("\troutingRole : $routingRole\n") + append("\trouteTable : $routeTable\n") + append("\tchildTable : $childTable\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXT_ADDRESS), extAddress) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + startArray(ContextSpecificTag(TAG_I_PV6S)) + for (item in IPv6s.iterator()) { + put(AnonymousTag, item) + } + endArray() + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + startArray(ContextSpecificTag(TAG_ROUTE_TABLE)) + for (item in routeTable.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + startArray(ContextSpecificTag(TAG_CHILD_TABLE)) + for (item in childTable.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_EXT_ADDRESS = 0 + private const val TAG_RLOC16 = 1 + private const val TAG_I_PV6S = 2 + private const val TAG_ROUTING_ROLE = 3 + private const val TAG_ROUTE_TABLE = 4 + private const val TAG_CHILD_TABLE = 5 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterThreadNodeStruct { + tlvReader.enterStructure(tlvTag) + val extAddress = tlvReader.getULong(ContextSpecificTag(TAG_EXT_ADDRESS)) + val rloc16 = tlvReader.getUInt(ContextSpecificTag(TAG_RLOC16)) + val IPv6s = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_I_PV6S)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getByteArray(AnonymousTag)) + } + tlvReader.exitContainer() + } + val routingRole = tlvReader.getUInt(ContextSpecificTag(TAG_ROUTING_ROLE)) + val routeTable = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_ROUTE_TABLE)) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadBorderRouterManagementClusterRouteTableStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + val childTable = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_CHILD_TABLE)) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadBorderRouterManagementClusterChildTableStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterThreadNodeStruct( + extAddress, + rloc16, + IPv6s, + routingRole, + routeTable, + childTable + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt new file mode 100644 index 00000000000000..b2e66f23f74394 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt @@ -0,0 +1,1413 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.BooleanSubscriptionState +import matter.controller.ByteArraySubscriptionState +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.StringSubscriptionState +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementCluster( + private val controller: MatterController, + private val endpointId: UShort +) { + class DatasetResponse(val dataset: ByteArray) + + class TopologyResponse( + val status: UByte, + val snapshot: UByte, + val numberOfDevices: UShort, + val threadTopology: List + ) + + class ThreadNodeAttribute(val value: ThreadBorderRouterManagementClusterThreadNodeStruct) + + sealed class ThreadNodeAttributeSubscriptionState { + data class Success(val value: ThreadBorderRouterManagementClusterThreadNodeStruct) : + ThreadNodeAttributeSubscriptionState() + + data class Error(val exception: Exception) : ThreadNodeAttributeSubscriptionState() + + object SubscriptionEstablished : ThreadNodeAttributeSubscriptionState() + } + + class ActiveDatasetTimestampAttribute(val value: ULong?) + + sealed class ActiveDatasetTimestampAttributeSubscriptionState { + data class Success(val value: ULong?) : ActiveDatasetTimestampAttributeSubscriptionState() + + data class Error(val exception: Exception) : ActiveDatasetTimestampAttributeSubscriptionState() + + object SubscriptionEstablished : ActiveDatasetTimestampAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun getActiveDatasetRequest(timedInvokeTimeout: Duration? = null): DatasetResponse { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_DATASET: Int = 0 + var dataset_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_DATASET)) { + dataset_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (dataset_decoded == null) { + throw IllegalStateException("dataset not found in TLV") + } + + tlvReader.exitContainer() + + return DatasetResponse(dataset_decoded) + } + + suspend fun getPendingDatasetRequest(timedInvokeTimeout: Duration? = null): DatasetResponse { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_DATASET: Int = 0 + var dataset_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_DATASET)) { + dataset_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (dataset_decoded == null) { + throw IllegalStateException("dataset not found in TLV") + } + + tlvReader.exitContainer() + + return DatasetResponse(dataset_decoded) + } + + suspend fun setActiveDatasetRequest( + activeDataset: ByteArray, + breadcrumb: ULong, + timedInvokeTimeout: Duration? = null + ) { + val commandId: UInt = 3u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTIVE_DATASET_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTIVE_DATASET_REQ), activeDataset) + + val TAG_BREADCRUMB_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun setPendingDatasetRequest( + pendingDataset: ByteArray, + timedInvokeTimeout: Duration? = null + ) { + val commandId: UInt = 4u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_PENDING_DATASET_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_PENDING_DATASET_REQ), pendingDataset) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun topologyRequest( + count: UShort, + startIndex: UShort, + snapshot: UByte, + timedInvokeTimeout: Duration? = null + ): TopologyResponse { + val commandId: UInt = 5u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COUNT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COUNT_REQ), count) + + val TAG_START_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_START_INDEX_REQ), startIndex) + + val TAG_SNAPSHOT_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_SNAPSHOT_REQ), snapshot) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_SNAPSHOT: Int = 1 + var snapshot_decoded: UByte? = null + + val TAG_NUMBER_OF_DEVICES: Int = 2 + var numberOfDevices_decoded: UShort? = null + + val TAG_THREAD_TOPOLOGY: Int = 3 + var threadTopology_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_SNAPSHOT)) { + snapshot_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_NUMBER_OF_DEVICES)) { + numberOfDevices_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_THREAD_TOPOLOGY)) { + threadTopology_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadBorderRouterManagementClusterThreadNodeStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + } else { + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + if (snapshot_decoded == null) { + throw IllegalStateException("snapshot not found in TLV") + } + + if (numberOfDevices_decoded == null) { + throw IllegalStateException("numberOfDevices not found in TLV") + } + + if (threadTopology_decoded == null) { + throw IllegalStateException("threadTopology not found in TLV") + } + + tlvReader.exitContainer() + + return TopologyResponse( + status_decoded, + snapshot_decoded, + numberOfDevices_decoded, + threadTopology_decoded + ) + } + + suspend fun readBorderRouterNameAttribute(): String { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Borderroutername attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeBorderRouterNameAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + StringSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Borderroutername attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + emit(StringSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(StringSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readBorderAgentIdAttribute(): ByteArray { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Borderagentid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray = tlvReader.getByteArray(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeBorderAgentIdAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + ByteArraySubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Borderagentid attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray = tlvReader.getByteArray(AnonymousTag) + + emit(ByteArraySubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(ByteArraySubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readThreadVersionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeThreadVersionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Threadversion attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readInterfaceEnabledAttribute(): Boolean { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Interfaceenabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeInterfaceEnabledAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 3u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + BooleanSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Interfaceenabled attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + emit(BooleanSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(BooleanSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readThreadNodeAttribute(): ThreadNodeAttribute { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadnode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ThreadBorderRouterManagementClusterThreadNodeStruct = + ThreadBorderRouterManagementClusterThreadNodeStruct.fromTlv(AnonymousTag, tlvReader) + + return ThreadNodeAttribute(decodedValue) + } + + suspend fun subscribeThreadNodeAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 4u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + ThreadNodeAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Threadnode attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ThreadBorderRouterManagementClusterThreadNodeStruct = + ThreadBorderRouterManagementClusterThreadNodeStruct.fromTlv(AnonymousTag, tlvReader) + + emit(ThreadNodeAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(ThreadNodeAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readActiveDatasetTimestampAttribute(): ActiveDatasetTimestampAttribute { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activedatasettimestamp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ActiveDatasetTimestampAttribute(decodedValue) + } + + suspend fun subscribeActiveDatasetTimestampAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 5u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + ActiveDatasetTimestampAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Activedatasettimestamp attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(ActiveDatasetTimestampAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(ActiveDatasetTimestampAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(ThreadBorderRouterManagementCluster::class.java.name) + const val CLUSTER_ID: UInt = 1106u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index f62cee23bdd5b3..431b3eb8751913 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -123,6 +123,10 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterScheduleTransitionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterScheduleTypeStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterWeeklyScheduleTransitionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterNeighborTableStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt", @@ -330,6 +334,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TemperatureMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimeFormatLocalizationCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimerCluster.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt new file mode 100644 index 00000000000000..daff3dd5bb484e --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterChildTableStruct.kt @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterChildTableStruct( + val rloc16: UShort, + val linkQuality: UByte, + val routingRole: UByte +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterChildTableStruct {\n") + append("\trloc16 : $rloc16\n") + append("\tlinkQuality : $linkQuality\n") + append("\troutingRole : $routingRole\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + put(ContextSpecificTag(TAG_LINK_QUALITY), linkQuality) + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + endStructure() + } + } + + companion object { + private const val TAG_RLOC16 = 0 + private const val TAG_LINK_QUALITY = 1 + private const val TAG_ROUTING_ROLE = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterChildTableStruct { + tlvReader.enterStructure(tlvTag) + val rloc16 = tlvReader.getUShort(ContextSpecificTag(TAG_RLOC16)) + val linkQuality = tlvReader.getUByte(ContextSpecificTag(TAG_LINK_QUALITY)) + val routingRole = tlvReader.getUByte(ContextSpecificTag(TAG_ROUTING_ROLE)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterChildTableStruct(rloc16, linkQuality, routingRole) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt new file mode 100644 index 00000000000000..b2544366c2e29e --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterNeiborTableStruct.kt @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterNeiborTableStruct( + val extAddress: ULong, + val age: UInt, + val rloc16: UShort, + val averageRssi: Byte?, + val lastRssi: Byte?, + val routingRole: UByte +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterNeiborTableStruct {\n") + append("\textAddress : $extAddress\n") + append("\tage : $age\n") + append("\trloc16 : $rloc16\n") + append("\taverageRssi : $averageRssi\n") + append("\tlastRssi : $lastRssi\n") + append("\troutingRole : $routingRole\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXT_ADDRESS), extAddress) + put(ContextSpecificTag(TAG_AGE), age) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + if (averageRssi != null) { + put(ContextSpecificTag(TAG_AVERAGE_RSSI), averageRssi) + } else { + putNull(ContextSpecificTag(TAG_AVERAGE_RSSI)) + } + if (lastRssi != null) { + put(ContextSpecificTag(TAG_LAST_RSSI), lastRssi) + } else { + putNull(ContextSpecificTag(TAG_LAST_RSSI)) + } + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + endStructure() + } + } + + companion object { + private const val TAG_EXT_ADDRESS = 0 + private const val TAG_AGE = 1 + private const val TAG_RLOC16 = 2 + private const val TAG_AVERAGE_RSSI = 3 + private const val TAG_LAST_RSSI = 4 + private const val TAG_ROUTING_ROLE = 5 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterNeiborTableStruct { + tlvReader.enterStructure(tlvTag) + val extAddress = tlvReader.getULong(ContextSpecificTag(TAG_EXT_ADDRESS)) + val age = tlvReader.getUInt(ContextSpecificTag(TAG_AGE)) + val rloc16 = tlvReader.getUShort(ContextSpecificTag(TAG_RLOC16)) + val averageRssi = + if (!tlvReader.isNull()) { + tlvReader.getByte(ContextSpecificTag(TAG_AVERAGE_RSSI)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AVERAGE_RSSI)) + null + } + val lastRssi = + if (!tlvReader.isNull()) { + tlvReader.getByte(ContextSpecificTag(TAG_LAST_RSSI)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LAST_RSSI)) + null + } + val routingRole = tlvReader.getUByte(ContextSpecificTag(TAG_ROUTING_ROLE)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterNeiborTableStruct( + extAddress, + age, + rloc16, + averageRssi, + lastRssi, + routingRole + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt new file mode 100644 index 00000000000000..d6f352f3db8be2 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterRouteTableStruct.kt @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterRouteTableStruct( + val routerId: UByte, + val pathCost: UByte, + val LQIIn: UByte, + val LQIOut: UByte +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterRouteTableStruct {\n") + append("\trouterId : $routerId\n") + append("\tpathCost : $pathCost\n") + append("\tLQIIn : $LQIIn\n") + append("\tLQIOut : $LQIOut\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ROUTER_ID), routerId) + put(ContextSpecificTag(TAG_PATH_COST), pathCost) + put(ContextSpecificTag(TAG_L_Q_I_IN), LQIIn) + put(ContextSpecificTag(TAG_L_Q_I_OUT), LQIOut) + endStructure() + } + } + + companion object { + private const val TAG_ROUTER_ID = 0 + private const val TAG_PATH_COST = 1 + private const val TAG_L_Q_I_IN = 2 + private const val TAG_L_Q_I_OUT = 3 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterRouteTableStruct { + tlvReader.enterStructure(tlvTag) + val routerId = tlvReader.getUByte(ContextSpecificTag(TAG_ROUTER_ID)) + val pathCost = tlvReader.getUByte(ContextSpecificTag(TAG_PATH_COST)) + val LQIIn = tlvReader.getUByte(ContextSpecificTag(TAG_L_Q_I_IN)) + val LQIOut = tlvReader.getUByte(ContextSpecificTag(TAG_L_Q_I_OUT)) + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterRouteTableStruct(routerId, pathCost, LQIIn, LQIOut) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt new file mode 100644 index 00000000000000..27bdec40817eba --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadBorderRouterManagementClusterThreadNodeStruct.kt @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadBorderRouterManagementClusterThreadNodeStruct( + val extAddress: ULong, + val rloc16: UShort, + val IPv6s: List, + val routingRole: UByte, + val routeTable: List, + val childTable: List +) { + override fun toString(): String = buildString { + append("ThreadBorderRouterManagementClusterThreadNodeStruct {\n") + append("\textAddress : $extAddress\n") + append("\trloc16 : $rloc16\n") + append("\tIPv6s : $IPv6s\n") + append("\troutingRole : $routingRole\n") + append("\trouteTable : $routeTable\n") + append("\tchildTable : $childTable\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXT_ADDRESS), extAddress) + put(ContextSpecificTag(TAG_RLOC16), rloc16) + startArray(ContextSpecificTag(TAG_I_PV6S)) + for (item in IPv6s.iterator()) { + put(AnonymousTag, item) + } + endArray() + put(ContextSpecificTag(TAG_ROUTING_ROLE), routingRole) + startArray(ContextSpecificTag(TAG_ROUTE_TABLE)) + for (item in routeTable.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + startArray(ContextSpecificTag(TAG_CHILD_TABLE)) + for (item in childTable.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_EXT_ADDRESS = 0 + private const val TAG_RLOC16 = 1 + private const val TAG_I_PV6S = 2 + private const val TAG_ROUTING_ROLE = 3 + private const val TAG_ROUTE_TABLE = 4 + private const val TAG_CHILD_TABLE = 5 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadBorderRouterManagementClusterThreadNodeStruct { + tlvReader.enterStructure(tlvTag) + val extAddress = tlvReader.getULong(ContextSpecificTag(TAG_EXT_ADDRESS)) + val rloc16 = tlvReader.getUShort(ContextSpecificTag(TAG_RLOC16)) + val IPv6s = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_I_PV6S)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getByteArray(AnonymousTag)) + } + tlvReader.exitContainer() + } + val routingRole = tlvReader.getUByte(ContextSpecificTag(TAG_ROUTING_ROLE)) + val routeTable = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_ROUTE_TABLE)) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadBorderRouterManagementClusterRouteTableStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + val childTable = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_CHILD_TABLE)) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadBorderRouterManagementClusterChildTableStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return ThreadBorderRouterManagementClusterThreadNodeStruct( + extAddress, + rloc16, + IPv6s, + routingRole, + routeTable, + childTable + ) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 2400ba818c7cb9..4d8e0ef8af6d9a 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -37156,6 +37156,414 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::ThreadBorderRouterManagement::Id: { + using namespace app::Clusters::ThreadBorderRouterManagement; + switch (aPath.mAttributeId) + { + case Attributes::BorderRouterName::Id: { + using TypeInfo = Attributes::BorderRouterName::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue, value)); + return value; + } + case Attributes::BorderAgentId::Id: { + using TypeInfo = Attributes::BorderAgentId::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + jbyteArray valueByteArray = env->NewByteArray(static_cast(cppValue.size())); + env->SetByteArrayRegion(valueByteArray, 0, static_cast(cppValue.size()), + reinterpret_cast(cppValue.data())); + value = valueByteArray; + return value; + } + case Attributes::ThreadVersion::Id: { + using TypeInfo = Attributes::ThreadVersion::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::InterfaceEnabled::Id: { + using TypeInfo = Attributes::InterfaceEnabled::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Boolean"; + std::string valueCtorSignature = "(Z)V"; + jboolean jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ThreadNode::Id: { + using TypeInfo = Attributes::ThreadNode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + jobject value_extAddress; + std::string value_extAddressClassName = "java/lang/Long"; + std::string value_extAddressCtorSignature = "(J)V"; + jlong jnivalue_extAddress = static_cast(cppValue.extAddress); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_extAddressClassName.c_str(), value_extAddressCtorSignature.c_str(), jnivalue_extAddress, value_extAddress); + jobject value_rloc16; + std::string value_rloc16ClassName = "java/lang/Integer"; + std::string value_rloc16CtorSignature = "(I)V"; + jint jnivalue_rloc16 = static_cast(cppValue.rloc16); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_rloc16ClassName.c_str(), value_rloc16CtorSignature.c_str(), jnivalue_rloc16, value_rloc16); + jobject value_IPv6s; + chip::JniReferences::GetInstance().CreateArrayList(value_IPv6s); + + auto iter_value_IPv6s_1 = cppValue.IPv6s.begin(); + while (iter_value_IPv6s_1.Next()) + { + auto & entry_1 = iter_value_IPv6s_1.GetValue(); + jobject newElement_1; + jbyteArray newElement_1ByteArray = env->NewByteArray(static_cast(entry_1.size())); + env->SetByteArrayRegion(newElement_1ByteArray, 0, static_cast(entry_1.size()), + reinterpret_cast(entry_1.data())); + newElement_1 = newElement_1ByteArray; + chip::JniReferences::GetInstance().AddToList(value_IPv6s, newElement_1); + } + jobject value_routingRole; + std::string value_routingRoleClassName = "java/lang/Integer"; + std::string value_routingRoleCtorSignature = "(I)V"; + jint jnivalue_routingRole = static_cast(cppValue.routingRole); + chip::JniReferences::GetInstance().CreateBoxedObject(value_routingRoleClassName.c_str(), + value_routingRoleCtorSignature.c_str(), jnivalue_routingRole, + value_routingRole); + jobject value_routeTable; + chip::JniReferences::GetInstance().CreateArrayList(value_routeTable); + + auto iter_value_routeTable_1 = cppValue.routeTable.begin(); + while (iter_value_routeTable_1.Next()) + { + auto & entry_1 = iter_value_routeTable_1.GetValue(); + jobject newElement_1; + jobject newElement_1_routerId; + std::string newElement_1_routerIdClassName = "java/lang/Integer"; + std::string newElement_1_routerIdCtorSignature = "(I)V"; + jint jninewElement_1_routerId = static_cast(entry_1.routerId); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_routerIdClassName.c_str(), + newElement_1_routerIdCtorSignature.c_str(), + jninewElement_1_routerId, newElement_1_routerId); + jobject newElement_1_pathCost; + std::string newElement_1_pathCostClassName = "java/lang/Integer"; + std::string newElement_1_pathCostCtorSignature = "(I)V"; + jint jninewElement_1_pathCost = static_cast(entry_1.pathCost); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_pathCostClassName.c_str(), + newElement_1_pathCostCtorSignature.c_str(), + jninewElement_1_pathCost, newElement_1_pathCost); + jobject newElement_1_LQIIn; + std::string newElement_1_LQIInClassName = "java/lang/Integer"; + std::string newElement_1_LQIInCtorSignature = "(I)V"; + jint jninewElement_1_LQIIn = static_cast(entry_1.LQIIn); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_LQIInClassName.c_str(), + newElement_1_LQIInCtorSignature.c_str(), + jninewElement_1_LQIIn, newElement_1_LQIIn); + jobject newElement_1_LQIOut; + std::string newElement_1_LQIOutClassName = "java/lang/Integer"; + std::string newElement_1_LQIOutCtorSignature = "(I)V"; + jint jninewElement_1_LQIOut = static_cast(entry_1.LQIOut); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_LQIOutClassName.c_str(), + newElement_1_LQIOutCtorSignature.c_str(), + jninewElement_1_LQIOut, newElement_1_LQIOut); + + jclass routeTableStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ThreadBorderRouterManagementClusterRouteTableStruct", + routeTableStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ThreadBorderRouterManagementClusterRouteTableStruct"); + return nullptr; + } + + jmethodID routeTableStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod( + env, routeTableStructStructClass_2, "", + "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", + &routeTableStructStructCtor_2); + if (err != CHIP_NO_ERROR || routeTableStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ThreadBorderRouterManagementClusterRouteTableStruct constructor"); + return nullptr; + } + + newElement_1 = env->NewObject(routeTableStructStructClass_2, routeTableStructStructCtor_2, newElement_1_routerId, + newElement_1_pathCost, newElement_1_LQIIn, newElement_1_LQIOut); + chip::JniReferences::GetInstance().AddToList(value_routeTable, newElement_1); + } + jobject value_childTable; + chip::JniReferences::GetInstance().CreateArrayList(value_childTable); + + auto iter_value_childTable_1 = cppValue.childTable.begin(); + while (iter_value_childTable_1.Next()) + { + auto & entry_1 = iter_value_childTable_1.GetValue(); + jobject newElement_1; + jobject newElement_1_rloc16; + std::string newElement_1_rloc16ClassName = "java/lang/Integer"; + std::string newElement_1_rloc16CtorSignature = "(I)V"; + jint jninewElement_1_rloc16 = static_cast(entry_1.rloc16); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_rloc16ClassName.c_str(), + newElement_1_rloc16CtorSignature.c_str(), + jninewElement_1_rloc16, newElement_1_rloc16); + jobject newElement_1_linkQuality; + std::string newElement_1_linkQualityClassName = "java/lang/Integer"; + std::string newElement_1_linkQualityCtorSignature = "(I)V"; + jint jninewElement_1_linkQuality = static_cast(entry_1.linkQuality); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_linkQualityClassName.c_str(), + newElement_1_linkQualityCtorSignature.c_str(), + jninewElement_1_linkQuality, newElement_1_linkQuality); + jobject newElement_1_routingRole; + std::string newElement_1_routingRoleClassName = "java/lang/Integer"; + std::string newElement_1_routingRoleCtorSignature = "(I)V"; + jint jninewElement_1_routingRole = static_cast(entry_1.routingRole); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_routingRoleClassName.c_str(), + newElement_1_routingRoleCtorSignature.c_str(), + jninewElement_1_routingRole, newElement_1_routingRole); + + jclass childTableStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ThreadBorderRouterManagementClusterChildTableStruct", + childTableStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ThreadBorderRouterManagementClusterChildTableStruct"); + return nullptr; + } + + jmethodID childTableStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod(env, childTableStructStructClass_2, "", + "(Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V", + &childTableStructStructCtor_2); + if (err != CHIP_NO_ERROR || childTableStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ThreadBorderRouterManagementClusterChildTableStruct constructor"); + return nullptr; + } + + newElement_1 = env->NewObject(childTableStructStructClass_2, childTableStructStructCtor_2, newElement_1_rloc16, + newElement_1_linkQuality, newElement_1_routingRole); + chip::JniReferences::GetInstance().AddToList(value_childTable, newElement_1); + } + + jclass threadNodeStructStructClass_0; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ThreadBorderRouterManagementClusterThreadNodeStruct", + threadNodeStructStructClass_0); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ThreadBorderRouterManagementClusterThreadNodeStruct"); + return nullptr; + } + + jmethodID threadNodeStructStructCtor_0; + err = chip::JniReferences::GetInstance().FindMethod(env, threadNodeStructStructClass_0, "", + "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/util/ArrayList;Ljava/" + "lang/Integer;Ljava/util/ArrayList;Ljava/util/ArrayList;)V", + &threadNodeStructStructCtor_0); + if (err != CHIP_NO_ERROR || threadNodeStructStructCtor_0 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ThreadBorderRouterManagementClusterThreadNodeStruct constructor"); + return nullptr; + } + + value = env->NewObject(threadNodeStructStructClass_0, threadNodeStructStructCtor_0, value_extAddress, value_rloc16, + value_IPv6s, value_routingRole, value_routeTable, value_childTable); + return value; + } + case Attributes::ActiveDatasetTimestamp::Id: { + using TypeInfo = Attributes::ActiveDatasetTimestamp::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::WakeOnLan::Id: { using namespace app::Clusters::WakeOnLan; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 370e510894c121..ed9d52786d8781 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -7389,6 +7389,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::ThreadBorderRouterManagement::Id: { + using namespace app::Clusters::ThreadBorderRouterManagement; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::WakeOnLan::Id: { using namespace app::Clusters::WakeOnLan; switch (aPath.mEventId) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 3bc715829f27db..3c15bd23de9724 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -11535,6 +11535,122 @@ class ChipClusters: }, }, } + _THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER_INFO = { + "clusterName": "ThreadBorderRouterManagement", + "clusterId": 0x00000452, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "GetActiveDatasetRequest", + "args": { + }, + }, + 0x00000001: { + "commandId": 0x00000001, + "commandName": "GetPendingDatasetRequest", + "args": { + }, + }, + 0x00000003: { + "commandId": 0x00000003, + "commandName": "SetActiveDatasetRequest", + "args": { + "activeDataset": "bytes", + "breadcrumb": "int", + }, + }, + 0x00000004: { + "commandId": 0x00000004, + "commandName": "SetPendingDatasetRequest", + "args": { + "pendingDataset": "bytes", + }, + }, + 0x00000005: { + "commandId": 0x00000005, + "commandName": "TopologyRequest", + "args": { + "count": "int", + "startIndex": "int", + "snapshot": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "BorderRouterName", + "attributeId": 0x00000000, + "type": "str", + "reportable": True, + }, + 0x00000001: { + "attributeName": "BorderAgentId", + "attributeId": 0x00000001, + "type": "bytes", + "reportable": True, + }, + 0x00000002: { + "attributeName": "ThreadVersion", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + }, + 0x00000003: { + "attributeName": "InterfaceEnabled", + "attributeId": 0x00000003, + "type": "bool", + "reportable": True, + }, + 0x00000004: { + "attributeName": "ThreadNode", + "attributeId": 0x00000004, + "type": "", + "reportable": True, + }, + 0x00000005: { + "attributeName": "ActiveDatasetTimestamp", + "attributeId": 0x00000005, + "type": "int", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _WAKE_ON_LAN_CLUSTER_INFO = { "clusterName": "WakeOnLan", "clusterId": 0x00000503, @@ -14638,6 +14754,7 @@ class ChipClusters: 0x0000042D: _PM10_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, 0x0000042E: _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, 0x0000042F: _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, + 0x00000452: _THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER_INFO, 0x00000503: _WAKE_ON_LAN_CLUSTER_INFO, 0x00000504: _CHANNEL_CLUSTER_INFO, 0x00000505: _TARGET_NAVIGATOR_CLUSTER_INFO, @@ -14759,6 +14876,7 @@ class ChipClusters: "Pm10ConcentrationMeasurement": _PM10_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, "TotalVolatileOrganicCompoundsConcentrationMeasurement": _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, "RadonConcentrationMeasurement": _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, + "ThreadBorderRouterManagement": _THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER_INFO, "WakeOnLan": _WAKE_ON_LAN_CLUSTER_INFO, "Channel": _CHANNEL_CLUSTER_INFO, "TargetNavigator": _TARGET_NAVIGATOR_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index cd411b93d43301..747db4dd92cf79 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -40230,6 +40230,448 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class ThreadBorderRouterManagement(Cluster): + id: typing.ClassVar[int] = 0x00000452 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="borderRouterName", Tag=0x00000000, Type=str), + ClusterObjectFieldDescriptor(Label="borderAgentId", Tag=0x00000001, Type=bytes), + ClusterObjectFieldDescriptor(Label="threadVersion", Tag=0x00000002, Type=uint), + ClusterObjectFieldDescriptor(Label="interfaceEnabled", Tag=0x00000003, Type=bool), + ClusterObjectFieldDescriptor(Label="threadNode", Tag=0x00000004, Type=ThreadBorderRouterManagement.Structs.ThreadNodeStruct), + ClusterObjectFieldDescriptor(Label="activeDatasetTimestamp", Tag=0x00000005, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + borderRouterName: 'str' = None + borderAgentId: 'bytes' = None + threadVersion: 'uint' = None + interfaceEnabled: 'bool' = None + threadNode: 'ThreadBorderRouterManagement.Structs.ThreadNodeStruct' = None + activeDatasetTimestamp: 'typing.Union[Nullable, uint]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class RoutingRoleEnum(MatterIntEnum): + kUnspecified = 0x00 + kUnassigned = 0x01 + kSleepyEndDevice = 0x02 + kEndDevice = 0x03 + kReed = 0x04 + kRouter = 0x05 + kLeader = 0x06 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 7, + + class Bitmaps: + class Feature(IntFlag): + kPANChange = 0x1 + + class Structs: + @dataclass + class ChildTableStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="rloc16", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="linkQuality", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="routingRole", Tag=2, Type=ThreadBorderRouterManagement.Enums.RoutingRoleEnum), + ]) + + rloc16: 'uint' = 0 + linkQuality: 'uint' = 0 + routingRole: 'ThreadBorderRouterManagement.Enums.RoutingRoleEnum' = 0 + + @dataclass + class RouteTableStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="routerId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="pathCost", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="LQIIn", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="LQIOut", Tag=3, Type=uint), + ]) + + routerId: 'uint' = 0 + pathCost: 'uint' = 0 + LQIIn: 'uint' = 0 + LQIOut: 'uint' = 0 + + @dataclass + class ThreadNodeStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extAddress", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="rloc16", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="IPv6s", Tag=2, Type=typing.List[bytes]), + ClusterObjectFieldDescriptor(Label="routingRole", Tag=3, Type=ThreadBorderRouterManagement.Enums.RoutingRoleEnum), + ClusterObjectFieldDescriptor(Label="routeTable", Tag=4, Type=typing.List[ThreadBorderRouterManagement.Structs.RouteTableStruct]), + ClusterObjectFieldDescriptor(Label="childTable", Tag=5, Type=typing.List[ThreadBorderRouterManagement.Structs.ChildTableStruct]), + ]) + + extAddress: 'uint' = 0 + rloc16: 'uint' = 0 + IPv6s: 'typing.List[bytes]' = field(default_factory=lambda: []) + routingRole: 'ThreadBorderRouterManagement.Enums.RoutingRoleEnum' = 0 + routeTable: 'typing.List[ThreadBorderRouterManagement.Structs.RouteTableStruct]' = field(default_factory=lambda: []) + childTable: 'typing.List[ThreadBorderRouterManagement.Structs.ChildTableStruct]' = field(default_factory=lambda: []) + + @dataclass + class NeiborTableStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extAddress", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="age", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="rloc16", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="averageRssi", Tag=3, Type=typing.Union[Nullable, int]), + ClusterObjectFieldDescriptor(Label="lastRssi", Tag=4, Type=typing.Union[Nullable, int]), + ClusterObjectFieldDescriptor(Label="routingRole", Tag=5, Type=ThreadBorderRouterManagement.Enums.RoutingRoleEnum), + ]) + + extAddress: 'uint' = 0 + age: 'uint' = 0 + rloc16: 'uint' = 0 + averageRssi: 'typing.Union[Nullable, int]' = NullValue + lastRssi: 'typing.Union[Nullable, int]' = NullValue + routingRole: 'ThreadBorderRouterManagement.Enums.RoutingRoleEnum' = 0 + + class Commands: + @dataclass + class GetActiveDatasetRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'DatasetResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + + @dataclass + class GetPendingDatasetRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'DatasetResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + + @dataclass + class DatasetResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="dataset", Tag=0, Type=bytes), + ]) + + dataset: 'bytes' = b"" + + @dataclass + class SetActiveDatasetRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000003 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="activeDataset", Tag=0, Type=bytes), + ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=uint), + ]) + + activeDataset: 'bytes' = b"" + breadcrumb: 'uint' = 0 + + @dataclass + class SetPendingDatasetRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000004 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="pendingDataset", Tag=0, Type=bytes), + ]) + + pendingDataset: 'bytes' = b"" + + @dataclass + class TopologyRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000005 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'TopologyResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="count", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="startIndex", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="snapshot", Tag=2, Type=uint), + ]) + + count: 'uint' = 0 + startIndex: 'uint' = 0 + snapshot: 'uint' = 0 + + @dataclass + class TopologyResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000452 + command_id: typing.ClassVar[int] = 0x00000006 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="snapshot", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="numberOfDevices", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="threadTopology", Tag=3, Type=typing.List[ThreadBorderRouterManagement.Structs.ThreadNodeStruct]), + ]) + + status: 'uint' = 0 + snapshot: 'uint' = 0 + numberOfDevices: 'uint' = 0 + threadTopology: 'typing.List[ThreadBorderRouterManagement.Structs.ThreadNodeStruct]' = field(default_factory=lambda: []) + + class Attributes: + @dataclass + class BorderRouterName(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=str) + + value: 'str' = "" + + @dataclass + class BorderAgentId(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=bytes) + + value: 'bytes' = b"" + + @dataclass + class ThreadVersion(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class InterfaceEnabled(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=bool) + + value: 'bool' = False + + @dataclass + class ThreadNode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000004 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=ThreadBorderRouterManagement.Structs.ThreadNodeStruct) + + value: 'ThreadBorderRouterManagement.Structs.ThreadNodeStruct' = field(default_factory=lambda: ThreadBorderRouterManagement.Structs.ThreadNodeStruct()) + + @dataclass + class ActiveDatasetTimestamp(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000005 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) + + value: 'typing.Union[Nullable, uint]' = NullValue + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000452 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class WakeOnLan(Cluster): id: typing.ClassVar[int] = 0x00000503 diff --git a/src/controller/python/chip/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index 44d9910c670098..be307d1c9c34e3 100644 --- a/src/controller/python/chip/clusters/__init__.py +++ b/src/controller/python/chip/clusters/__init__.py @@ -43,8 +43,8 @@ RadonConcentrationMeasurement, RefrigeratorAlarm, RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RvcCleanMode, RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, SoftwareDiagnostics, Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, - ThermostatUserInterfaceConfiguration, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, - TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, + ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, + TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering) __all__ = [Attribute, CHIPClusters, Command, AccessControl, AccountLogin, Actions, ActivatedCarbonFilterMonitoring, AdministratorCommissioning, AirQuality, @@ -66,6 +66,6 @@ RefrigeratorAlarm, RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RvcCleanMode, RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, SoftwareDiagnostics, Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, - ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, + ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering] diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index cb98d807f3495d..2b4e1b7459d342 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5288,6 +5288,51 @@ static BOOL AttributeIsSpecifiedInRadonConcentrationMeasurementCluster(Attribute } } } +static BOOL AttributeIsSpecifiedInThreadBorderRouterManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ThreadBorderRouterManagement; + switch (aAttributeId) { + case Attributes::BorderRouterName::Id: { + return YES; + } + case Attributes::BorderAgentId::Id: { + return YES; + } + case Attributes::ThreadVersion::Id: { + return YES; + } + case Attributes::InterfaceEnabled::Id: { + return YES; + } + case Attributes::ThreadNode::Id: { + return YES; + } + case Attributes::ActiveDatasetTimestamp::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInWakeOnLANCluster(AttributeId aAttributeId) { using namespace Clusters::WakeOnLan; @@ -6804,6 +6849,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::RadonConcentrationMeasurement::Id: { return AttributeIsSpecifiedInRadonConcentrationMeasurementCluster(aAttributeId); } + case Clusters::ThreadBorderRouterManagement::Id: { + return AttributeIsSpecifiedInThreadBorderRouterManagementCluster(aAttributeId); + } case Clusters::WakeOnLan::Id: { return AttributeIsSpecifiedInWakeOnLANCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index bae1643f3beb39..87a96d160a7f5b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -15219,6 +15219,151 @@ static id _Nullable DecodeAttributeValueForRadonConcentrationMeasurementCluster( *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForThreadBorderRouterManagementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ThreadBorderRouterManagement; + switch (aAttributeId) { + case Attributes::BorderRouterName::Id: { + using TypeInfo = Attributes::BorderRouterName::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSString * _Nonnull value; + value = AsString(cppValue); + if (value == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + return value; + } + case Attributes::BorderAgentId::Id: { + using TypeInfo = Attributes::BorderAgentId::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSData * _Nonnull value; + value = AsData(cppValue); + return value; + } + case Attributes::ThreadVersion::Id: { + using TypeInfo = Attributes::ThreadVersion::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedShort:cppValue]; + return value; + } + case Attributes::InterfaceEnabled::Id: { + using TypeInfo = Attributes::InterfaceEnabled::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithBool:cppValue]; + return value; + } + case Attributes::ThreadNode::Id: { + using TypeInfo = Attributes::ThreadNode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nonnull value; + value = [MTRThreadBorderRouterManagementClusterThreadNodeStruct new]; + value.extAddress = [NSNumber numberWithUnsignedLongLong:cppValue.extAddress]; + value.rloc16 = [NSNumber numberWithUnsignedShort:cppValue.rloc16]; + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.IPv6s.begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + NSData * newElement_1; + newElement_1 = AsData(entry_1); + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value.iPv6s = array_1; + } + value.routingRole = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.routingRole)]; + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.routeTable.begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + MTRThreadBorderRouterManagementClusterRouteTableStruct * newElement_1; + newElement_1 = [MTRThreadBorderRouterManagementClusterRouteTableStruct new]; + newElement_1.routerId = [NSNumber numberWithUnsignedChar:entry_1.routerId]; + newElement_1.pathCost = [NSNumber numberWithUnsignedChar:entry_1.pathCost]; + newElement_1.lqiIn = [NSNumber numberWithUnsignedChar:entry_1.LQIIn]; + newElement_1.lqiOut = [NSNumber numberWithUnsignedChar:entry_1.LQIOut]; + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value.routeTable = array_1; + } + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.childTable.begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + MTRThreadBorderRouterManagementClusterChildTableStruct * newElement_1; + newElement_1 = [MTRThreadBorderRouterManagementClusterChildTableStruct new]; + newElement_1.rloc16 = [NSNumber numberWithUnsignedShort:entry_1.rloc16]; + newElement_1.linkQuality = [NSNumber numberWithUnsignedChar:entry_1.linkQuality]; + newElement_1.routingRole = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.routingRole)]; + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value.childTable = array_1; + } + return value; + } + case Attributes::ActiveDatasetTimestamp::Id: { + using TypeInfo = Attributes::ActiveDatasetTimestamp::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedLongLong:cppValue.Value()]; + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForWakeOnLANCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::WakeOnLan; @@ -19593,6 +19738,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::RadonConcentrationMeasurement::Id: { return DecodeAttributeValueForRadonConcentrationMeasurementCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::ThreadBorderRouterManagement::Id: { + return DecodeAttributeValueForThreadBorderRouterManagementCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::WakeOnLan::Id: { return DecodeAttributeValueForWakeOnLANCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 3c7624201d0484..a9ba833c07b336 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -12989,6 +12989,138 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Thread Border Router Management + * + * Thread BR management + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterThreadBorderRouterManagement : MTRGenericBaseCluster + +/** + * Command GetActiveDatasetRequest + * + * On receipt of this command, the Thread Border Router will read the active operational dataset of the Thread network that it is connaected to, and send the DatasetResponse as the response. This command must be sent over a valid CASE session + */ +- (void)getActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams * _Nullable)params completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getActiveDatasetRequestWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; +/** + * Command GetPendingDatasetRequest + * + * On receipt of this command, the Thread Border Router will read the pending dataset and send the DatasetResponse as the response. This command must be sent over a valid CASE session + */ +- (void)getPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams * _Nullable)params completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getPendingDatasetRequestWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; +/** + * Command SetActiveDatasetRequest + * + * On receipt of this command, the Thread Border Router will set or update the active Dataset of the Thread network that the Stub Router is connected to. + */ +- (void)setActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command SetPendingDatasetRequest + * + * On receipt of this command, the Thread Border Router will set or update the pending Dataset + */ +- (void)setPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command TopologyRequest + * + * On receipt of this command, the Thread Border Router will response the current topology of the Thread network that it is connected to. + */ +- (void)topologyRequestWithParams:(MTRThreadBorderRouterManagementClusterTopologyRequestParams *)params completion:(void (^)(MTRThreadBorderRouterManagementClusterTopologyResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeBorderRouterNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeBorderRouterNameWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeBorderRouterNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeBorderAgentIdWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeBorderAgentIdWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeBorderAgentIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeThreadVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeThreadVersionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeThreadVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeInterfaceEnabledWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeInterfaceEnabledWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeInterfaceEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeThreadNodeWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeThreadNodeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeThreadNodeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeActiveDatasetTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeActiveDatasetTimestampWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeActiveDatasetTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterThreadBorderRouterManagement (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Wake on LAN * @@ -19483,6 +19615,20 @@ typedef NS_OPTIONS(uint32_t, MTRRadonConcentrationMeasurementFeature) { MTRRadonConcentrationMeasurementFeatureAverageMeasurement MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x20, } MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); +typedef NS_ENUM(uint8_t, MTRThreadBorderRouterManagementRoutingRole) { + MTRThreadBorderRouterManagementRoutingRoleUnspecified MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRThreadBorderRouterManagementRoutingRoleUnassigned MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRThreadBorderRouterManagementRoutingRoleSleepyEndDevice MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRThreadBorderRouterManagementRoutingRoleEndDevice MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRThreadBorderRouterManagementRoutingRoleREED MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRThreadBorderRouterManagementRoutingRoleRouter MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRThreadBorderRouterManagementRoutingRoleLeader MTR_PROVISIONALLY_AVAILABLE = 0x06, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTRThreadBorderRouterManagementFeature) { + MTRThreadBorderRouterManagementFeaturePANChange MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRChannelType) { MTRChannelTypeSatellite MTR_PROVISIONALLY_AVAILABLE = 0x00, MTRChannelTypeCable MTR_PROVISIONALLY_AVAILABLE = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index b375488f292fc8..e67baae0040e01 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -92894,6 +92894,571 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterThreadBorderRouterManagement + +- (void)getActiveDatasetRequestWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getActiveDatasetRequestWithParams:nil completion:completion]; +} +- (void)getActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams * _Nullable)params completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)getPendingDatasetRequestWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getPendingDatasetRequestWithParams:nil completion:completion]; +} +- (void)getPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams * _Nullable)params completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)setActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)setPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)topologyRequestWithParams:(MTRThreadBorderRouterManagementClusterTopologyRequestParams *)params completion:(void (^)(MTRThreadBorderRouterManagementClusterTopologyResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterTopologyRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::TopologyRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterTopologyResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeBorderRouterNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderRouterName::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeBorderRouterNameWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderRouterName::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeBorderRouterNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderRouterName::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeBorderAgentIdWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderAgentId::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeBorderAgentIdWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderAgentId::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeBorderAgentIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::BorderAgentId::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeThreadVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadVersion::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeThreadVersionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadVersion::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeThreadVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadVersion::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeInterfaceEnabledWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::InterfaceEnabled::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeInterfaceEnabledWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::InterfaceEnabled::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeInterfaceEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::InterfaceEnabled::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeThreadNodeWithCompletion:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadNode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeThreadNodeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadNode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeThreadNodeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ThreadNode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeActiveDatasetTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeActiveDatasetTimestampWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeActiveDatasetTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadBorderRouterManagement::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterWakeOnLAN - (void)readAttributeMACAddressWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 5c3f6a080fdd7b..65203988d929e0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -184,6 +184,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypePM10ConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042D, MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042E, MTRClusterIDTypeRadonConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042F, + MTRClusterIDTypeThreadBorderRouterManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000452, MTRClusterIDTypeWakeOnLANID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000503, MTRClusterIDTypeChannelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000504, MTRClusterIDTypeTargetNavigatorID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000505, @@ -4361,6 +4362,20 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster ThreadBorderRouterManagement attributes + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderRouterNameID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderAgentIdID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadVersionID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeInterfaceEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadNodeID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeActiveDatasetTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WakeOnLan deprecated attribute names MTRClusterWakeOnLanAttributeMACAddressID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterWakeOnLANAttributeMACAddressID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6575,6 +6590,15 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterColorControlCommandMoveColorTemperatureID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000004B, MTRCommandIDTypeClusterColorControlCommandStepColorTemperatureID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000004C, + // Cluster ThreadBorderRouterManagement commands + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandGetActiveDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandGetPendingDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandDatasetResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetActiveDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetPendingDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandTopologyRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandTopologyResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, + // Cluster Channel deprecated command id names MTRClusterChannelCommandChangeChannelID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterChannelCommandChangeChannelID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 474c5cacf47679..1760023379286f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -318,6 +318,9 @@ case MTRClusterIDTypeRadonConcentrationMeasurementID: result = @"RadonConcentrationMeasurement"; break; + case MTRClusterIDTypeThreadBorderRouterManagementID: + result = @"ThreadBorderRouterManagement"; + break; case MTRClusterIDTypeWakeOnLANID: result = @"WakeOnLAN"; break; @@ -7212,6 +7215,64 @@ break; } + case MTRClusterIDTypeThreadBorderRouterManagementID: + + switch (attributeID) { + + // Cluster ThreadBorderRouterManagement attributes + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderRouterNameID: + result = @"BorderRouterName"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderAgentIdID: + result = @"BorderAgentId"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadVersionID: + result = @"ThreadVersion"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeInterfaceEnabledID: + result = @"InterfaceEnabled"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadNodeID: + result = @"ThreadNode"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeActiveDatasetTimestampID: + result = @"ActiveDatasetTimestamp"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeWakeOnLANID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 6e4e0f80b44d00..2e51e22b97690b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -5993,6 +5993,64 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Thread Border Router Management + * Thread BR management + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterThreadBorderRouterManagement : MTRGenericCluster + +- (void)getActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getActiveDatasetRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; +- (void)getPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getPendingDatasetRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; +- (void)setActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)topologyRequestWithParams:(MTRThreadBorderRouterManagementClusterTopologyRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterTopologyResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeBorderRouterNameWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeBorderAgentIdWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeThreadVersionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeInterfaceEnabledWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeThreadNodeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeActiveDatasetTimestampWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterThreadBorderRouterManagement (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Wake on LAN * This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index db279250cac8bf..a2f8082f0286cf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -16768,6 +16768,213 @@ @implementation MTRClusterRadonConcentrationMeasurement @end +@implementation MTRClusterThreadBorderRouterManagement + +- (void)getActiveDatasetRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getActiveDatasetRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)getActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)getPendingDatasetRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getPendingDatasetRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)getPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)setActiveDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)setPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)topologyRequestWithParams:(MTRThreadBorderRouterManagementClusterTopologyRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadBorderRouterManagementClusterTopologyResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadBorderRouterManagementClusterTopologyRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ThreadBorderRouterManagement::Commands::TopologyRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadBorderRouterManagementClusterTopologyResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeBorderRouterNameWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderRouterNameID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeBorderAgentIdWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderAgentIdID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeThreadVersionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadVersionID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeInterfaceEnabledWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeInterfaceEnabledID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeThreadNodeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadNodeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeActiveDatasetTimestampWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeActiveDatasetTimestampID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterWakeOnLAN - (NSDictionary * _Nullable)readAttributeMACAddressWithParams:(MTRReadParams * _Nullable)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 1d1552200b5b1c..b47a4fde335ec5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -8512,6 +8512,202 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterDatasetResponseParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull dataset MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRThreadBorderRouterManagementClusterDatasetResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull activeDataset MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull breadcrumb MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull pendingDataset MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterTopologyRequestParams : NSObject + +@property (nonatomic, copy, getter=getCount) NSNumber * _Nonnull count MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull startIndex MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull snapshot MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterTopologyResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull snapshot MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull numberOfDevices MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSArray * _Nonnull threadTopology MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRThreadBorderRouterManagementClusterTopologyResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRChannelClusterChangeChannelParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 3105c9a9d21f80..86d1edc541c920 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -23968,6 +23968,652 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadBorderRouterManagementClusterDatasetResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _dataset = [NSData data]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterDatasetResponseParams alloc] init]; + + other.dataset = self.dataset; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: dataset:%@; >", NSStringFromClass([self class]), [_dataset base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterDatasetResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType &)decodableStruct +{ + { + self.dataset = AsData(decodableStruct.dataset); + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _activeDataset = [NSData data]; + + _breadcrumb = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams alloc] init]; + + other.activeDataset = self.activeDataset; + other.breadcrumb = self.breadcrumb; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: activeDataset:%@; breadcrumb:%@; >", NSStringFromClass([self class]), [_activeDataset base64EncodedStringWithOptions:0], _breadcrumb]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.activeDataset = AsByteSpan(self.activeDataset); + } + { + encodableStruct.breadcrumb = self.breadcrumb.unsignedLongLongValue; + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _pendingDataset = [NSData data]; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams alloc] init]; + + other.pendingDataset = self.pendingDataset; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: pendingDataset:%@; >", NSStringFromClass([self class]), [_pendingDataset base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.pendingDataset = AsByteSpan(self.pendingDataset); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadBorderRouterManagementClusterTopologyRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _count = @(0); + + _startIndex = @(0); + + _snapshot = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterTopologyRequestParams alloc] init]; + + other.count = self.count; + other.startIndex = self.startIndex; + other.snapshot = self.snapshot; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: count:%@; startIndex:%@; snapshot:%@; >", NSStringFromClass([self class]), _count, _startIndex, _snapshot]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterTopologyRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.count = self.count.unsignedShortValue; + } + { + encodableStruct.startIndex = self.startIndex.unsignedShortValue; + } + { + encodableStruct.snapshot = self.snapshot.unsignedCharValue; + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadBorderRouterManagementClusterTopologyResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _status = @(0); + + _snapshot = @(0); + + _numberOfDevices = @(0); + + _threadTopology = [NSArray array]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadBorderRouterManagementClusterTopologyResponseParams alloc] init]; + + other.status = self.status; + other.snapshot = self.snapshot; + other.numberOfDevices = self.numberOfDevices; + other.threadTopology = self.threadTopology; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: status:%@; snapshot:%@; numberOfDevices:%@; threadTopology:%@; >", NSStringFromClass([self class]), _status, _snapshot, _numberOfDevices, _threadTopology]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterTopologyResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType &)decodableStruct +{ + { + self.status = [NSNumber numberWithUnsignedChar:decodableStruct.status]; + } + { + self.snapshot = [NSNumber numberWithUnsignedChar:decodableStruct.snapshot]; + } + { + self.numberOfDevices = [NSNumber numberWithUnsignedShort:decodableStruct.numberOfDevices]; + } + { + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = decodableStruct.threadTopology.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRThreadBorderRouterManagementClusterThreadNodeStruct * newElement_0; + newElement_0 = [MTRThreadBorderRouterManagementClusterThreadNodeStruct new]; + newElement_0.extAddress = [NSNumber numberWithUnsignedLongLong:entry_0.extAddress]; + newElement_0.rloc16 = [NSNumber numberWithUnsignedShort:entry_0.rloc16]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.IPv6s.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + NSData * newElement_2; + newElement_2 = AsData(entry_2); + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + return err; + } + newElement_0.iPv6s = array_2; + } + newElement_0.routingRole = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.routingRole)]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.routeTable.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRThreadBorderRouterManagementClusterRouteTableStruct * newElement_2; + newElement_2 = [MTRThreadBorderRouterManagementClusterRouteTableStruct new]; + newElement_2.routerId = [NSNumber numberWithUnsignedChar:entry_2.routerId]; + newElement_2.pathCost = [NSNumber numberWithUnsignedChar:entry_2.pathCost]; + newElement_2.lqiIn = [NSNumber numberWithUnsignedChar:entry_2.LQIIn]; + newElement_2.lqiOut = [NSNumber numberWithUnsignedChar:entry_2.LQIOut]; + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + return err; + } + newElement_0.routeTable = array_2; + } + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.childTable.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRThreadBorderRouterManagementClusterChildTableStruct * newElement_2; + newElement_2 = [MTRThreadBorderRouterManagementClusterChildTableStruct new]; + newElement_2.rloc16 = [NSNumber numberWithUnsignedShort:entry_2.rloc16]; + newElement_2.linkQuality = [NSNumber numberWithUnsignedChar:entry_2.linkQuality]; + newElement_2.routingRole = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.routingRole)]; + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + return err; + } + newElement_0.childTable = array_2; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + return err; + } + self.threadTopology = array_0; + } + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRChannelClusterChangeChannelParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 2579d3bc49a9bd..12bc02dff58e8a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1570,6 +1570,48 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadBorderRouterManagementClusterDatasetResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType &)decodableStruct; + +@end + +@interface MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadBorderRouterManagementClusterTopologyRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadBorderRouterManagementClusterTopologyResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType &)decodableStruct; + +@end + @interface MTRChannelClusterChangeChannelParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 685ca8f4f035a9..ac5ebc3bac0062 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -956,6 +956,15 @@ static BOOL CommandNeedsTimedInvokeInRadonConcentrationMeasurementCluster(Attrib } } } +static BOOL CommandNeedsTimedInvokeInThreadBorderRouterManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ThreadBorderRouterManagement; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInWakeOnLANCluster(AttributeId aAttributeId) { using namespace Clusters::WakeOnLan; @@ -1419,6 +1428,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::RadonConcentrationMeasurement::Id: { return CommandNeedsTimedInvokeInRadonConcentrationMeasurementCluster(commandID); } + case Clusters::ThreadBorderRouterManagement::Id: { + return CommandNeedsTimedInvokeInThreadBorderRouterManagementCluster(commandID); + } case Clusters::WakeOnLan::Id: { return CommandNeedsTimedInvokeInWakeOnLANCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index 46427cba7fab3b..beb091be4ade9e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -97,6 +97,7 @@ { 0x00000840, DeviceTypeClass::Simple, "Matter Control Bridge" }, { 0x00000850, DeviceTypeClass::Simple, "Matter On/Off Sensor" }, { 0xFFF10010, DeviceTypeClass::Simple, "Matter Network Infrastructure Manager" }, + { 0xFFF10011, DeviceTypeClass::Simple, "Matter Thread Border Router" }, }; static_assert(ExtractVendorFromMEI(0xFFF10001) != 0, "Must have class defined for \"Matter Orphan Clusters\" if it's a standard device type"); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 3e36773ffebd99..def29aa4b7fa1e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4035,6 +4035,18 @@ static id _Nullable DecodeEventPayloadForRadonConcentrationMeasurementCluster(Ev *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForThreadBorderRouterManagementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ThreadBorderRouterManagement; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForWakeOnLANCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::WakeOnLan; @@ -4836,6 +4848,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::RadonConcentrationMeasurement::Id: { return DecodeEventPayloadForRadonConcentrationMeasurementCluster(aPath.mEventId, aReader, aError); } + case Clusters::ThreadBorderRouterManagement::Id: { + return DecodeEventPayloadForThreadBorderRouterManagementCluster(aPath.mEventId, aReader, aError); + } case Clusters::WakeOnLan::Id: { return DecodeEventPayloadForWakeOnLANCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 92bd095b954393..a47b709bcd6db0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1637,6 +1637,41 @@ MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct", @property (nonatomic, copy) NSNumber * _Nullable coolSetpoint MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct", ios(16.1, 17.4), macos(13.0, 14.4), watchos(9.1, 10.4), tvos(16.1, 17.4)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterChildTableStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull rloc16 MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull linkQuality MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull routingRole MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterRouteTableStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull routerId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull pathCost MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull lqiIn MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull lqiOut MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterThreadNodeStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull extAddress MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull rloc16 MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull iPv6s MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull routingRole MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull routeTable MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull childTable MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadBorderRouterManagementClusterNeiborTableStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull extAddress MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull age MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull rloc16 MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable averageRssi MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable lastRssi MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull routingRole MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRChannelClusterProgramCastStruct : NSObject @property (nonatomic, copy) NSString * _Nonnull name MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index c9c38c72710756..8004395e2b70ca 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -6884,6 +6884,159 @@ @implementation MTRThermostatClusterThermostatScheduleTransition : MTRThermostat @dynamic coolSetpoint; @end +@implementation MTRThreadBorderRouterManagementClusterChildTableStruct +- (instancetype)init +{ + if (self = [super init]) { + + _rloc16 = @(0); + + _linkQuality = @(0); + + _routingRole = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadBorderRouterManagementClusterChildTableStruct alloc] init]; + + other.rloc16 = self.rloc16; + other.linkQuality = self.linkQuality; + other.routingRole = self.routingRole; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: rloc16:%@; linkQuality:%@; routingRole:%@; >", NSStringFromClass([self class]), _rloc16, _linkQuality, _routingRole]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterRouteTableStruct +- (instancetype)init +{ + if (self = [super init]) { + + _routerId = @(0); + + _pathCost = @(0); + + _lqiIn = @(0); + + _lqiOut = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadBorderRouterManagementClusterRouteTableStruct alloc] init]; + + other.routerId = self.routerId; + other.pathCost = self.pathCost; + other.lqiIn = self.lqiIn; + other.lqiOut = self.lqiOut; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: routerId:%@; pathCost:%@; lqiIn:%@; lqiOut:%@; >", NSStringFromClass([self class]), _routerId, _pathCost, _lqiIn, _lqiOut]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterThreadNodeStruct +- (instancetype)init +{ + if (self = [super init]) { + + _extAddress = @(0); + + _rloc16 = @(0); + + _iPv6s = [NSArray array]; + + _routingRole = @(0); + + _routeTable = [NSArray array]; + + _childTable = [NSArray array]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadBorderRouterManagementClusterThreadNodeStruct alloc] init]; + + other.extAddress = self.extAddress; + other.rloc16 = self.rloc16; + other.iPv6s = self.iPv6s; + other.routingRole = self.routingRole; + other.routeTable = self.routeTable; + other.childTable = self.childTable; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extAddress:%@; rloc16:%@; iPv6s:%@; routingRole:%@; routeTable:%@; childTable:%@; >", NSStringFromClass([self class]), _extAddress, _rloc16, _iPv6s, _routingRole, _routeTable, _childTable]; + return descriptionString; +} + +@end + +@implementation MTRThreadBorderRouterManagementClusterNeiborTableStruct +- (instancetype)init +{ + if (self = [super init]) { + + _extAddress = @(0); + + _age = @(0); + + _rloc16 = @(0); + + _averageRssi = nil; + + _lastRssi = nil; + + _routingRole = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadBorderRouterManagementClusterNeiborTableStruct alloc] init]; + + other.extAddress = self.extAddress; + other.age = self.age; + other.rloc16 = self.rloc16; + other.averageRssi = self.averageRssi; + other.lastRssi = self.lastRssi; + other.routingRole = self.routingRole; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extAddress:%@; age:%@; rloc16:%@; averageRssi:%@; lastRssi:%@; routingRole:%@; >", NSStringFromClass([self class]), _extAddress, _age, _rloc16, _averageRssi, _lastRssi, _routingRole]; + return descriptionString; +} + +@end + @implementation MTRChannelClusterProgramCastStruct - (instancetype)init { diff --git a/third_party/infineon/repos/matter-wpan-sdk b/third_party/infineon/repos/matter-wpan-sdk index 6086f0a77620a3..f6e196cbd982cf 160000 --- a/third_party/infineon/repos/matter-wpan-sdk +++ b/third_party/infineon/repos/matter-wpan-sdk @@ -1 +1 @@ -Subproject commit 6086f0a77620a33af7ef1ae95c1d6bd959f8a5e0 +Subproject commit f6e196cbd982cfd4c74ffca6ba4128dba298b8ac diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 78c93070ca6d03..7e38797b5a877b 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -34570,6 +34570,59 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +namespace Attributes { + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadBorderRouterManagement + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index e51fb1999e9ce8..807d12a8226c96 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -5316,6 +5316,18 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +namespace Attributes { + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadBorderRouterManagement + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 350190a22e5762..47d94f00794d51 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -533,6 +533,11 @@ void emberAfTotalVolatileOrganicCompoundsConcentrationMeasurementClusterInitCall */ void emberAfRadonConcentrationMeasurementClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadBorderRouterManagementClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -4488,6 +4493,45 @@ chip::Protocols::InteractionModel::Status MatterRadonConcentrationMeasurementClu */ void emberAfRadonConcentrationMeasurementClusterServerTickCallback(chip::EndpointId endpoint); +// +// Thread Border Router Management Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadBorderRouterManagementClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterThreadBorderRouterManagementClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadBorderRouterManagementClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterThreadBorderRouterManagementClusterServerAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterThreadBorderRouterManagementClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfThreadBorderRouterManagementClusterServerTickCallback(chip::EndpointId endpoint); + // // Wake on LAN Cluster // diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index ca25c08c748e0c..e31991b523fbcd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -2707,6 +2707,24 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(OccupancySensing::Occup } } +static auto __attribute__((unused)) EnsureKnownEnumValue(ThreadBorderRouterManagement::RoutingRoleEnum val) +{ + using EnumType = ThreadBorderRouterManagement::RoutingRoleEnum; + switch (val) + { + case EnumType::kUnspecified: + case EnumType::kUnassigned: + case EnumType::kSleepyEndDevice: + case EnumType::kEndDevice: + case EnumType::kReed: + case EnumType::kRouter: + case EnumType::kLeader: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(Channel::ChannelTypeEnum val) { using EnumType = Channel::ChannelTypeEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 42a54b95ee944f..9dc0cd7335e5ec 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -4309,6 +4309,32 @@ enum class Feature : uint32_t }; } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { + +// Enum for RoutingRoleEnum +enum class RoutingRoleEnum : uint8_t +{ + kUnspecified = 0x00, + kUnassigned = 0x01, + kSleepyEndDevice = 0x02, + kEndDevice = 0x03, + kReed = 0x04, + kRouter = 0x05, + kLeader = 0x06, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 7, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kPANChange = 0x1, +}; +} // namespace ThreadBorderRouterManagement + namespace WakeOnLan {} // namespace WakeOnLan namespace Channel { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 32b62631ed30fd..71ee814ed0298a 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -22865,6 +22865,510 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +namespace Structs { + +namespace ChildTableStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRloc16), rloc16); + encoder.Encode(to_underlying(Fields::kLinkQuality), linkQuality); + encoder.Encode(to_underlying(Fields::kRoutingRole), routingRole); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRloc16)) + { + err = DataModel::Decode(reader, rloc16); + } + else if (__context_tag == to_underlying(Fields::kLinkQuality)) + { + err = DataModel::Decode(reader, linkQuality); + } + else if (__context_tag == to_underlying(Fields::kRoutingRole)) + { + err = DataModel::Decode(reader, routingRole); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace ChildTableStruct + +namespace RouteTableStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRouterId), routerId); + encoder.Encode(to_underlying(Fields::kPathCost), pathCost); + encoder.Encode(to_underlying(Fields::kLQIIn), LQIIn); + encoder.Encode(to_underlying(Fields::kLQIOut), LQIOut); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRouterId)) + { + err = DataModel::Decode(reader, routerId); + } + else if (__context_tag == to_underlying(Fields::kPathCost)) + { + err = DataModel::Decode(reader, pathCost); + } + else if (__context_tag == to_underlying(Fields::kLQIIn)) + { + err = DataModel::Decode(reader, LQIIn); + } + else if (__context_tag == to_underlying(Fields::kLQIOut)) + { + err = DataModel::Decode(reader, LQIOut); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace RouteTableStruct + +namespace ThreadNodeStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kExtAddress), extAddress); + encoder.Encode(to_underlying(Fields::kRloc16), rloc16); + encoder.Encode(to_underlying(Fields::kIPv6s), IPv6s); + encoder.Encode(to_underlying(Fields::kRoutingRole), routingRole); + encoder.Encode(to_underlying(Fields::kRouteTable), routeTable); + encoder.Encode(to_underlying(Fields::kChildTable), childTable); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtAddress)) + { + err = DataModel::Decode(reader, extAddress); + } + else if (__context_tag == to_underlying(Fields::kRloc16)) + { + err = DataModel::Decode(reader, rloc16); + } + else if (__context_tag == to_underlying(Fields::kIPv6s)) + { + err = DataModel::Decode(reader, IPv6s); + } + else if (__context_tag == to_underlying(Fields::kRoutingRole)) + { + err = DataModel::Decode(reader, routingRole); + } + else if (__context_tag == to_underlying(Fields::kRouteTable)) + { + err = DataModel::Decode(reader, routeTable); + } + else if (__context_tag == to_underlying(Fields::kChildTable)) + { + err = DataModel::Decode(reader, childTable); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace ThreadNodeStruct + +namespace NeiborTableStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kExtAddress), extAddress); + encoder.Encode(to_underlying(Fields::kAge), age); + encoder.Encode(to_underlying(Fields::kRloc16), rloc16); + encoder.Encode(to_underlying(Fields::kAverageRssi), averageRssi); + encoder.Encode(to_underlying(Fields::kLastRssi), lastRssi); + encoder.Encode(to_underlying(Fields::kRoutingRole), routingRole); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtAddress)) + { + err = DataModel::Decode(reader, extAddress); + } + else if (__context_tag == to_underlying(Fields::kAge)) + { + err = DataModel::Decode(reader, age); + } + else if (__context_tag == to_underlying(Fields::kRloc16)) + { + err = DataModel::Decode(reader, rloc16); + } + else if (__context_tag == to_underlying(Fields::kAverageRssi)) + { + err = DataModel::Decode(reader, averageRssi); + } + else if (__context_tag == to_underlying(Fields::kLastRssi)) + { + err = DataModel::Decode(reader, lastRssi); + } + else if (__context_tag == to_underlying(Fields::kRoutingRole)) + { + err = DataModel::Decode(reader, routingRole); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace NeiborTableStruct +} // namespace Structs + +namespace Commands { +namespace GetActiveDatasetRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace GetActiveDatasetRequest. +namespace GetPendingDatasetRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace GetPendingDatasetRequest. +namespace DatasetResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kDataset), dataset); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kDataset)) + { + err = DataModel::Decode(reader, dataset); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace DatasetResponse. +namespace SetActiveDatasetRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kActiveDataset), activeDataset); + encoder.Encode(to_underlying(Fields::kBreadcrumb), breadcrumb); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kActiveDataset)) + { + err = DataModel::Decode(reader, activeDataset); + } + else if (__context_tag == to_underlying(Fields::kBreadcrumb)) + { + err = DataModel::Decode(reader, breadcrumb); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SetActiveDatasetRequest. +namespace SetPendingDatasetRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kPendingDataset), pendingDataset); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kPendingDataset)) + { + err = DataModel::Decode(reader, pendingDataset); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SetPendingDatasetRequest. +namespace TopologyRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kCount), count); + encoder.Encode(to_underlying(Fields::kStartIndex), startIndex); + encoder.Encode(to_underlying(Fields::kSnapshot), snapshot); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kCount)) + { + err = DataModel::Decode(reader, count); + } + else if (__context_tag == to_underlying(Fields::kStartIndex)) + { + err = DataModel::Decode(reader, startIndex); + } + else if (__context_tag == to_underlying(Fields::kSnapshot)) + { + err = DataModel::Decode(reader, snapshot); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace TopologyRequest. +namespace TopologyResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kSnapshot), snapshot); + encoder.Encode(to_underlying(Fields::kNumberOfDevices), numberOfDevices); + encoder.Encode(to_underlying(Fields::kThreadTopology), threadTopology); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kSnapshot)) + { + err = DataModel::Decode(reader, snapshot); + } + else if (__context_tag == to_underlying(Fields::kNumberOfDevices)) + { + err = DataModel::Decode(reader, numberOfDevices); + } + else if (__context_tag == to_underlying(Fields::kThreadTopology)) + { + err = DataModel::Decode(reader, threadTopology); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace TopologyResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::BorderRouterName::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, borderRouterName); + case Attributes::BorderAgentId::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, borderAgentId); + case Attributes::ThreadVersion::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, threadVersion); + case Attributes::InterfaceEnabled::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, interfaceEnabled); + case Attributes::ThreadNode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, threadNode); + case Attributes::ActiveDatasetTimestamp::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, activeDatasetTimestamp); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace ThreadBorderRouterManagement namespace WakeOnLan { namespace Commands {} // namespace Commands @@ -30345,6 +30849,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::ThreadBorderRouterManagement::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::Channel::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 89c36f3c6f147d..aa6c87f57db321 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -34846,6 +34846,549 @@ struct TypeInfo }; } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +namespace Structs { +namespace ChildTableStruct { +enum class Fields : uint8_t +{ + kRloc16 = 0, + kLinkQuality = 1, + kRoutingRole = 2, +}; + +struct Type +{ +public: + uint16_t rloc16 = static_cast(0); + uint8_t linkQuality = static_cast(0); + RoutingRoleEnum routingRole = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace ChildTableStruct +namespace RouteTableStruct { +enum class Fields : uint8_t +{ + kRouterId = 0, + kPathCost = 1, + kLQIIn = 2, + kLQIOut = 3, +}; + +struct Type +{ +public: + uint8_t routerId = static_cast(0); + uint8_t pathCost = static_cast(0); + uint8_t LQIIn = static_cast(0); + uint8_t LQIOut = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace RouteTableStruct +namespace ThreadNodeStruct { +enum class Fields : uint8_t +{ + kExtAddress = 0, + kRloc16 = 1, + kIPv6s = 2, + kRoutingRole = 3, + kRouteTable = 4, + kChildTable = 5, +}; + +struct Type +{ +public: + uint64_t extAddress = static_cast(0); + uint16_t rloc16 = static_cast(0); + DataModel::List IPv6s; + RoutingRoleEnum routingRole = static_cast(0); + DataModel::List routeTable; + DataModel::List childTable; + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + uint64_t extAddress = static_cast(0); + uint16_t rloc16 = static_cast(0); + DataModel::DecodableList IPv6s; + RoutingRoleEnum routingRole = static_cast(0); + DataModel::DecodableList routeTable; + DataModel::DecodableList childTable; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; +}; + +} // namespace ThreadNodeStruct +namespace NeiborTableStruct { +enum class Fields : uint8_t +{ + kExtAddress = 0, + kAge = 1, + kRloc16 = 2, + kAverageRssi = 3, + kLastRssi = 4, + kRoutingRole = 5, +}; + +struct Type +{ +public: + uint64_t extAddress = static_cast(0); + uint32_t age = static_cast(0); + uint16_t rloc16 = static_cast(0); + DataModel::Nullable averageRssi; + DataModel::Nullable lastRssi; + RoutingRoleEnum routingRole = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace NeiborTableStruct +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace GetActiveDatasetRequest { +struct Type; +struct DecodableType; +} // namespace GetActiveDatasetRequest + +namespace GetPendingDatasetRequest { +struct Type; +struct DecodableType; +} // namespace GetPendingDatasetRequest + +namespace DatasetResponse { +struct Type; +struct DecodableType; +} // namespace DatasetResponse + +namespace SetActiveDatasetRequest { +struct Type; +struct DecodableType; +} // namespace SetActiveDatasetRequest + +namespace SetPendingDatasetRequest { +struct Type; +struct DecodableType; +} // namespace SetPendingDatasetRequest + +namespace TopologyRequest { +struct Type; +struct DecodableType; +} // namespace TopologyRequest + +namespace TopologyResponse { +struct Type; +struct DecodableType; +} // namespace TopologyResponse + +} // namespace Commands + +namespace Commands { +namespace GetActiveDatasetRequest { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GetActiveDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GetActiveDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GetActiveDatasetRequest +namespace GetPendingDatasetRequest { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GetPendingDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GetPendingDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GetPendingDatasetRequest +namespace DatasetResponse { +enum class Fields : uint8_t +{ + kDataset = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::DatasetResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan dataset; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::DatasetResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan dataset; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace DatasetResponse +namespace SetActiveDatasetRequest { +enum class Fields : uint8_t +{ + kActiveDataset = 0, + kBreadcrumb = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SetActiveDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan activeDataset; + uint64_t breadcrumb = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SetActiveDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan activeDataset; + uint64_t breadcrumb = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SetActiveDatasetRequest +namespace SetPendingDatasetRequest { +enum class Fields : uint8_t +{ + kPendingDataset = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SetPendingDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan pendingDataset; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SetPendingDatasetRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + chip::ByteSpan pendingDataset; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SetPendingDatasetRequest +namespace TopologyRequest { +enum class Fields : uint8_t +{ + kCount = 0, + kStartIndex = 1, + kSnapshot = 2, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::TopologyRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + uint16_t count = static_cast(0); + uint16_t startIndex = static_cast(0); + uint8_t snapshot = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::TopologyRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + uint16_t count = static_cast(0); + uint16_t startIndex = static_cast(0); + uint8_t snapshot = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace TopologyRequest +namespace TopologyResponse { +enum class Fields : uint8_t +{ + kStatus = 0, + kSnapshot = 1, + kNumberOfDevices = 2, + kThreadTopology = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::TopologyResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + uint8_t status = static_cast(0); + uint8_t snapshot = static_cast(0); + uint16_t numberOfDevices = static_cast(0); + DataModel::List threadTopology; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::TopologyResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + uint8_t status = static_cast(0); + uint8_t snapshot = static_cast(0); + uint16_t numberOfDevices = static_cast(0); + DataModel::DecodableList threadTopology; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace TopologyResponse +} // namespace Commands + +namespace Attributes { + +namespace BorderRouterName { +struct TypeInfo +{ + using Type = chip::CharSpan; + using DecodableType = chip::CharSpan; + using DecodableArgType = chip::CharSpan; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::BorderRouterName::Id; } + static constexpr bool MustUseTimedWrite() { return false; } + static constexpr size_t MaxLength() { return 63; } +}; +} // namespace BorderRouterName +namespace BorderAgentId { +struct TypeInfo +{ + using Type = chip::ByteSpan; + using DecodableType = chip::ByteSpan; + using DecodableArgType = chip::ByteSpan; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::BorderAgentId::Id; } + static constexpr bool MustUseTimedWrite() { return false; } + static constexpr size_t MaxLength() { return 16; } +}; +} // namespace BorderAgentId +namespace ThreadVersion { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ThreadVersion::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ThreadVersion +namespace InterfaceEnabled { +struct TypeInfo +{ + using Type = bool; + using DecodableType = bool; + using DecodableArgType = bool; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::InterfaceEnabled::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace InterfaceEnabled +namespace ThreadNode { +struct TypeInfo +{ + using Type = chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::Type; + using DecodableType = chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::DecodableType; + using DecodableArgType = const chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::DecodableType &; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ThreadNode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ThreadNode +namespace ActiveDatasetTimestamp { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ActiveDatasetTimestamp::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ActiveDatasetTimestamp +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::BorderRouterName::TypeInfo::DecodableType borderRouterName; + Attributes::BorderAgentId::TypeInfo::DecodableType borderAgentId; + Attributes::ThreadVersion::TypeInfo::DecodableType threadVersion = static_cast(0); + Attributes::InterfaceEnabled::TypeInfo::DecodableType interfaceEnabled = static_cast(0); + Attributes::ThreadNode::TypeInfo::DecodableType threadNode; + Attributes::ActiveDatasetTimestamp::TypeInfo::DecodableType activeDatasetTimestamp; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace ThreadBorderRouterManagement namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 8ff6313abe5940..246e3b9beae44e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -6583,6 +6583,60 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +namespace Attributes { + +namespace BorderRouterName { +static constexpr AttributeId Id = 0x00000000; +} // namespace BorderRouterName + +namespace BorderAgentId { +static constexpr AttributeId Id = 0x00000001; +} // namespace BorderAgentId + +namespace ThreadVersion { +static constexpr AttributeId Id = 0x00000002; +} // namespace ThreadVersion + +namespace InterfaceEnabled { +static constexpr AttributeId Id = 0x00000003; +} // namespace InterfaceEnabled + +namespace ThreadNode { +static constexpr AttributeId Id = 0x00000004; +} // namespace ThreadNode + +namespace ActiveDatasetTimestamp { +static constexpr AttributeId Id = 0x00000005; +} // namespace ActiveDatasetTimestamp + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadBorderRouterManagement + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index f457887220abad..2d99611551338f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -325,6 +325,9 @@ static constexpr ClusterId Id = 0x0000042E; namespace RadonConcentrationMeasurement { static constexpr ClusterId Id = 0x0000042F; } // namespace RadonConcentrationMeasurement +namespace ThreadBorderRouterManagement { +static constexpr ClusterId Id = 0x00000452; +} // namespace ThreadBorderRouterManagement namespace WakeOnLan { static constexpr ClusterId Id = 0x00000503; } // namespace WakeOnLan diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index da8b04c98c1963..5f84fd5d51f493 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1381,6 +1381,40 @@ static constexpr CommandId Id = 0x0000004C; } // namespace Commands } // namespace ColorControl +namespace ThreadBorderRouterManagement { +namespace Commands { + +namespace GetActiveDatasetRequest { +static constexpr CommandId Id = 0x00000000; +} // namespace GetActiveDatasetRequest + +namespace GetPendingDatasetRequest { +static constexpr CommandId Id = 0x00000001; +} // namespace GetPendingDatasetRequest + +namespace DatasetResponse { +static constexpr CommandId Id = 0x00000002; +} // namespace DatasetResponse + +namespace SetActiveDatasetRequest { +static constexpr CommandId Id = 0x00000003; +} // namespace SetActiveDatasetRequest + +namespace SetPendingDatasetRequest { +static constexpr CommandId Id = 0x00000004; +} // namespace SetPendingDatasetRequest + +namespace TopologyRequest { +static constexpr CommandId Id = 0x00000005; +} // namespace TopologyRequest + +namespace TopologyResponse { +static constexpr CommandId Id = 0x00000006; +} // namespace TopologyResponse + +} // namespace Commands +} // namespace ThreadBorderRouterManagement + namespace Channel { namespace Commands { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 8a3081edc0dc1b..66336d1451232f 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -135,6 +135,7 @@ | Pm10ConcentrationMeasurement | 0x042D | | TotalVolatileOrganicCompoundsConcentrationMeasurement | 0x042E | | RadonConcentrationMeasurement | 0x042F | +| ThreadBorderRouterManagement | 0x0452 | | WakeOnLan | 0x0503 | | Channel | 0x0504 | | TargetNavigator | 0x0505 | @@ -11017,6 +11018,232 @@ class ColorControlStepColorTemperature : public ClusterCommand | Events: | | \*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*\ +| Cluster ThreadBorderRouterManagement | 0x0452 | +|------------------------------------------------------------------------------| +| Commands: | | +| * GetActiveDatasetRequest | 0x00 | +| * GetPendingDatasetRequest | 0x01 | +| * SetActiveDatasetRequest | 0x03 | +| * SetPendingDatasetRequest | 0x04 | +| * TopologyRequest | 0x05 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * BorderRouterName | 0x0000 | +| * BorderAgentId | 0x0001 | +| * ThreadVersion | 0x0002 | +| * InterfaceEnabled | 0x0003 | +| * ThreadNode | 0x0004 | +| * ActiveDatasetTimestamp | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command GetActiveDatasetRequest + */ +class ThreadBorderRouterManagementGetActiveDatasetRequest : public ClusterCommand +{ +public: + ThreadBorderRouterManagementGetActiveDatasetRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("get-active-dataset-request", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Type mRequest; +}; + +/* + * Command GetPendingDatasetRequest + */ +class ThreadBorderRouterManagementGetPendingDatasetRequest : public ClusterCommand +{ +public: + ThreadBorderRouterManagementGetPendingDatasetRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("get-pending-dataset-request", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Type mRequest; +}; + +/* + * Command SetActiveDatasetRequest + */ +class ThreadBorderRouterManagementSetActiveDatasetRequest : public ClusterCommand +{ +public: + ThreadBorderRouterManagementSetActiveDatasetRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("set-active-dataset-request", credsIssuerConfig) + { + AddArgument("ActiveDataset", &mRequest.activeDataset); + AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Type mRequest; +}; + +/* + * Command SetPendingDatasetRequest + */ +class ThreadBorderRouterManagementSetPendingDatasetRequest : public ClusterCommand +{ +public: + ThreadBorderRouterManagementSetPendingDatasetRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("set-pending-dataset-request", credsIssuerConfig) + { + AddArgument("PendingDataset", &mRequest.pendingDataset); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Type mRequest; +}; + +/* + * Command TopologyRequest + */ +class ThreadBorderRouterManagementTopologyRequest : public ClusterCommand +{ +public: + ThreadBorderRouterManagementTopologyRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("topology-request", credsIssuerConfig) + { + AddArgument("Count", 0, UINT16_MAX, &mRequest.count); + AddArgument("StartIndex", 0, UINT16_MAX, &mRequest.startIndex); + AddArgument("Snapshot", 0, UINT8_MAX, &mRequest.snapshot); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster WakeOnLan | 0x0503 | |------------------------------------------------------------------------------| @@ -24507,6 +24734,88 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands, Credentia commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterThreadBorderRouterManagement(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::ThreadBorderRouterManagement; + + const char * clusterName = "ThreadBorderRouterManagement"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "border-router-name", Attributes::BorderRouterName::Id, credsIssuerConfig), // + make_unique(Id, "border-agent-id", Attributes::BorderAgentId::Id, credsIssuerConfig), // + make_unique(Id, "thread-version", Attributes::ThreadVersion::Id, credsIssuerConfig), // + make_unique(Id, "interface-enabled", Attributes::InterfaceEnabled::Id, credsIssuerConfig), // + make_unique(Id, "thread-node", Attributes::ThreadNode::Id, credsIssuerConfig), // + make_unique(Id, "active-dataset-timestamp", Attributes::ActiveDatasetTimestamp::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>(Id, "border-router-name", Attributes::BorderRouterName::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "border-agent-id", Attributes::BorderAgentId::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "thread-version", 0, UINT16_MAX, Attributes::ThreadVersion::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "interface-enabled", 0, 1, Attributes::InterfaceEnabled::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>( + Id, "thread-node", Attributes::ThreadNode::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "active-dataset-timestamp", 0, UINT64_MAX, + Attributes::ActiveDatasetTimestamp::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "border-router-name", Attributes::BorderRouterName::Id, credsIssuerConfig), // + make_unique(Id, "border-agent-id", Attributes::BorderAgentId::Id, credsIssuerConfig), // + make_unique(Id, "thread-version", Attributes::ThreadVersion::Id, credsIssuerConfig), // + make_unique(Id, "interface-enabled", Attributes::InterfaceEnabled::Id, credsIssuerConfig), // + make_unique(Id, "thread-node", Attributes::ThreadNode::Id, credsIssuerConfig), // + make_unique(Id, "active-dataset-timestamp", Attributes::ActiveDatasetTimestamp::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterWakeOnLan(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::WakeOnLan; @@ -26861,6 +27170,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterPm10ConcentrationMeasurement(commands, credsIssuerConfig); registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(commands, credsIssuerConfig); registerClusterRadonConcentrationMeasurement(commands, credsIssuerConfig); + registerClusterThreadBorderRouterManagement(commands, credsIssuerConfig); registerClusterWakeOnLan(commands, credsIssuerConfig); registerClusterChannel(commands, credsIssuerConfig); registerClusterTargetNavigator(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 89f34d0cee3714..e458f2467266a4 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -3986,6 +3986,208 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::W ComplexArgumentParser::Finalize(request.coolSetpoint); } +CHIP_ERROR +ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ChildTableStruct.rloc16", "rloc16", value.isMember("rloc16"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ChildTableStruct.linkQuality", "linkQuality", value.isMember("linkQuality"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ChildTableStruct.routingRole", "routingRole", value.isMember("routingRole"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rloc16"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rloc16, value["rloc16"])); + valueCopy.removeMember("rloc16"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "linkQuality"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.linkQuality, value["linkQuality"])); + valueCopy.removeMember("linkQuality"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routingRole"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routingRole, value["routingRole"])); + valueCopy.removeMember("routingRole"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.rloc16); + ComplexArgumentParser::Finalize(request.linkQuality); + ComplexArgumentParser::Finalize(request.routingRole); +} + +CHIP_ERROR +ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.routerId", "routerId", value.isMember("routerId"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.pathCost", "pathCost", value.isMember("pathCost"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.LQIIn", "LQIIn", value.isMember("LQIIn"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.LQIOut", "LQIOut", value.isMember("LQIOut"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routerId"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routerId, value["routerId"])); + valueCopy.removeMember("routerId"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "pathCost"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.pathCost, value["pathCost"])); + valueCopy.removeMember("pathCost"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "LQIIn"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.LQIIn, value["LQIIn"])); + valueCopy.removeMember("LQIIn"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "LQIOut"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.LQIOut, value["LQIOut"])); + valueCopy.removeMember("LQIOut"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.routerId); + ComplexArgumentParser::Finalize(request.pathCost); + ComplexArgumentParser::Finalize(request.LQIIn); + ComplexArgumentParser::Finalize(request.LQIOut); +} + +CHIP_ERROR +ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.extAddress", "extAddress", value.isMember("extAddress"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.rloc16", "rloc16", value.isMember("rloc16"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.IPv6s", "IPv6s", value.isMember("IPv6s"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.routingRole", "routingRole", value.isMember("routingRole"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.routeTable", "routeTable", value.isMember("routeTable"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNodeStruct.childTable", "childTable", value.isMember("childTable"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extAddress"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extAddress, value["extAddress"])); + valueCopy.removeMember("extAddress"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rloc16"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rloc16, value["rloc16"])); + valueCopy.removeMember("rloc16"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "IPv6s"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.IPv6s, value["IPv6s"])); + valueCopy.removeMember("IPv6s"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routingRole"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routingRole, value["routingRole"])); + valueCopy.removeMember("routingRole"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routeTable"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routeTable, value["routeTable"])); + valueCopy.removeMember("routeTable"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "childTable"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.childTable, value["childTable"])); + valueCopy.removeMember("childTable"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.extAddress); + ComplexArgumentParser::Finalize(request.rloc16); + ComplexArgumentParser::Finalize(request.IPv6s); + ComplexArgumentParser::Finalize(request.routingRole); + ComplexArgumentParser::Finalize(request.routeTable); + ComplexArgumentParser::Finalize(request.childTable); +} + +CHIP_ERROR +ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.extAddress", "extAddress", value.isMember("extAddress"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.age", "age", value.isMember("age"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.rloc16", "rloc16", value.isMember("rloc16"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.averageRssi", "averageRssi", value.isMember("averageRssi"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.lastRssi", "lastRssi", value.isMember("lastRssi"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("NeiborTableStruct.routingRole", "routingRole", value.isMember("routingRole"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extAddress"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extAddress, value["extAddress"])); + valueCopy.removeMember("extAddress"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "age"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.age, value["age"])); + valueCopy.removeMember("age"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rloc16"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rloc16, value["rloc16"])); + valueCopy.removeMember("rloc16"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "averageRssi"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.averageRssi, value["averageRssi"])); + valueCopy.removeMember("averageRssi"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lastRssi"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lastRssi, value["lastRssi"])); + valueCopy.removeMember("lastRssi"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routingRole"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routingRole, value["routingRole"])); + valueCopy.removeMember("routingRole"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.extAddress); + ComplexArgumentParser::Finalize(request.age); + ComplexArgumentParser::Finalize(request.rloc16); + ComplexArgumentParser::Finalize(request.averageRssi); + ComplexArgumentParser::Finalize(request.lastRssi); + ComplexArgumentParser::Finalize(request.routingRole); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::ProgramCastStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index a9ac94c6cecb77..667c2b386fc38f 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -455,6 +455,30 @@ static CHIP_ERROR Setup(const char * label, static void Finalize(chip::app::Clusters::Thermostat::Structs::WeeklyScheduleTransitionStruct::Type & request); +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Channel::Structs::ProgramCastStruct::Type & request, Json::Value & value); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index fde5089bab8a7c..174c38e36e7ab3 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -3528,6 +3528,198 @@ DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Rloc16", indent + 1, value.rloc16); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Rloc16'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LinkQuality", indent + 1, value.linkQuality); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LinkQuality'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("RoutingRole", indent + 1, value.routingRole); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RoutingRole'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("RouterId", indent + 1, value.routerId); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RouterId'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("PathCost", indent + 1, value.pathCost); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'PathCost'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LQIIn", indent + 1, value.LQIIn); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LQIIn'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LQIOut", indent + 1, value.LQIOut); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LQIOut'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("ExtAddress", indent + 1, value.extAddress); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ExtAddress'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Rloc16", indent + 1, value.rloc16); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Rloc16'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("IPv6s", indent + 1, value.IPv6s); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'IPv6s'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("RoutingRole", indent + 1, value.routingRole); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RoutingRole'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("RouteTable", indent + 1, value.routeTable); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RouteTable'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("ChildTable", indent + 1, value.childTable); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ChildTable'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue( + const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("ExtAddress", indent + 1, value.extAddress); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ExtAddress'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Age", indent + 1, value.age); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Age'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Rloc16", indent + 1, value.rloc16); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Rloc16'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("AverageRssi", indent + 1, value.averageRssi); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AverageRssi'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LastRssi", indent + 1, value.lastRssi); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LastRssi'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("RoutingRole", indent + 1, value.routingRole); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RoutingRole'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Structs::ProgramCastStruct::DecodableType & value) { @@ -7719,6 +7911,25 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("dataset", indent + 1, value.dataset)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); + ReturnErrorOnFailure(DataModelLogger::LogValue("snapshot", indent + 1, value.snapshot)); + ReturnErrorOnFailure(DataModelLogger::LogValue("numberOfDevices", indent + 1, value.numberOfDevices)); + ReturnErrorOnFailure(DataModelLogger::LogValue("threadTopology", indent + 1, value.threadTopology)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Channel::Commands::ChangeChannelResponse::DecodableType & value) { @@ -16089,6 +16300,72 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case ThreadBorderRouterManagement::Id: { + switch (path.mAttributeId) + { + case ThreadBorderRouterManagement::Attributes::BorderRouterName::Id: { + chip::CharSpan value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("BorderRouterName", 1, value); + } + case ThreadBorderRouterManagement::Attributes::BorderAgentId::Id: { + chip::ByteSpan value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("BorderAgentId", 1, value); + } + case ThreadBorderRouterManagement::Attributes::ThreadVersion::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ThreadVersion", 1, value); + } + case ThreadBorderRouterManagement::Attributes::InterfaceEnabled::Id: { + bool value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("InterfaceEnabled", 1, value); + } + case ThreadBorderRouterManagement::Attributes::ThreadNode::Id: { + chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ThreadNode", 1, value); + } + case ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ActiveDatasetTimestamp", 1, value); + } + case ThreadBorderRouterManagement::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case ThreadBorderRouterManagement::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case ThreadBorderRouterManagement::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case ThreadBorderRouterManagement::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case ThreadBorderRouterManagement::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case ThreadBorderRouterManagement::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case WakeOnLan::Id: { switch (path.mAttributeId) { @@ -18438,6 +18715,22 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case ThreadBorderRouterManagement::Id: { + switch (path.mCommandId) + { + case ThreadBorderRouterManagement::Commands::DatasetResponse::Id: { + ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("DatasetResponse", 1, value); + } + case ThreadBorderRouterManagement::Commands::TopologyResponse::Id: { + ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TopologyResponse", 1, value); + } + } + break; + } case Channel::Id: { switch (path.mCommandId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 1c790b5e002039..673046ff9b01b7 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -284,6 +284,22 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::WeeklyScheduleTransitionStruct::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::ChildTableStruct::DecodableType & value); + +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::RouteTableStruct::DecodableType & value); + +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::ThreadNodeStruct::DecodableType & value); + +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Structs::NeiborTableStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Structs::ProgramCastStruct::DecodableType & value); @@ -735,6 +751,12 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Commands::GetCredentialStatusResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Commands::ChangeChannelResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index c3034217db9c05..df6a2a2973a9d4 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -137,6 +137,7 @@ | Pm10ConcentrationMeasurement | 0x042D | | TotalVolatileOrganicCompoundsConcentrationMeasurement | 0x042E | | RadonConcentrationMeasurement | 0x042F | +| ThreadBorderRouterManagement | 0x0452 | | WakeOnLan | 0x0503 | | Channel | 0x0504 | | TargetNavigator | 0x0505 | @@ -143040,6 +143041,1343 @@ class SubscribeAttributeRadonConcentrationMeasurementClusterRevision : public Su } }; +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster ThreadBorderRouterManagement | 0x0452 | +|------------------------------------------------------------------------------| +| Commands: | | +| * GetActiveDatasetRequest | 0x00 | +| * GetPendingDatasetRequest | 0x01 | +| * SetActiveDatasetRequest | 0x03 | +| * SetPendingDatasetRequest | 0x04 | +| * TopologyRequest | 0x05 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * BorderRouterName | 0x0000 | +| * BorderAgentId | 0x0001 | +| * ThreadVersion | 0x0002 | +| * InterfaceEnabled | 0x0003 | +| * ThreadNode | 0x0004 | +| * ActiveDatasetTimestamp | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command GetActiveDatasetRequest + */ +class ThreadBorderRouterManagementGetActiveDatasetRequest : public ClusterCommand { +public: + ThreadBorderRouterManagementGetActiveDatasetRequest() + : ClusterCommand("get-active-dataset-request") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadBorderRouterManagementClusterGetActiveDatasetRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster getActiveDatasetRequestWithParams:params completion: + ^(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command GetPendingDatasetRequest + */ +class ThreadBorderRouterManagementGetPendingDatasetRequest : public ClusterCommand { +public: + ThreadBorderRouterManagementGetPendingDatasetRequest() + : ClusterCommand("get-pending-dataset-request") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadBorderRouterManagementClusterGetPendingDatasetRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster getPendingDatasetRequestWithParams:params completion: + ^(MTRThreadBorderRouterManagementClusterDatasetResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::DatasetResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command SetActiveDatasetRequest + */ +class ThreadBorderRouterManagementSetActiveDatasetRequest : public ClusterCommand { +public: + ThreadBorderRouterManagementSetActiveDatasetRequest() + : ClusterCommand("set-active-dataset-request") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("ActiveDataset", &mRequest.activeDataset); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadBorderRouterManagementClusterSetActiveDatasetRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.activeDataset = [NSData dataWithBytes:mRequest.activeDataset.data() length:mRequest.activeDataset.size()]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster setActiveDatasetRequestWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command SetPendingDatasetRequest + */ +class ThreadBorderRouterManagementSetPendingDatasetRequest : public ClusterCommand { +public: + ThreadBorderRouterManagementSetPendingDatasetRequest() + : ClusterCommand("set-pending-dataset-request") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("PendingDataset", &mRequest.pendingDataset); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadBorderRouterManagementClusterSetPendingDatasetRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.pendingDataset = [NSData dataWithBytes:mRequest.pendingDataset.data() length:mRequest.pendingDataset.size()]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster setPendingDatasetRequestWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command TopologyRequest + */ +class ThreadBorderRouterManagementTopologyRequest : public ClusterCommand { +public: + ThreadBorderRouterManagementTopologyRequest() + : ClusterCommand("topology-request") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("Count", 0, UINT16_MAX, &mRequest.count); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("StartIndex", 0, UINT16_MAX, &mRequest.startIndex); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Snapshot", 0, UINT8_MAX, &mRequest.snapshot); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadBorderRouterManagementClusterTopologyRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.count = [NSNumber numberWithUnsignedShort:mRequest.count]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.startIndex = [NSNumber numberWithUnsignedShort:mRequest.startIndex]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.snapshot = [NSNumber numberWithUnsignedChar:mRequest.snapshot]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster topologyRequestWithParams:params completion: + ^(MTRThreadBorderRouterManagementClusterTopologyResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadBorderRouterManagement::Commands::TopologyRequest::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute BorderRouterName + */ +class ReadThreadBorderRouterManagementBorderRouterName : public ReadAttribute { +public: + ReadThreadBorderRouterManagementBorderRouterName() + : ReadAttribute("border-router-name") + { + } + + ~ReadThreadBorderRouterManagementBorderRouterName() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::BorderRouterName::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeBorderRouterNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.BorderRouterName response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement BorderRouterName read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementBorderRouterName : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementBorderRouterName() + : SubscribeAttribute("border-router-name") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementBorderRouterName() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::BorderRouterName::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeBorderRouterNameWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.BorderRouterName response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute BorderAgentId + */ +class ReadThreadBorderRouterManagementBorderAgentId : public ReadAttribute { +public: + ReadThreadBorderRouterManagementBorderAgentId() + : ReadAttribute("border-agent-id") + { + } + + ~ReadThreadBorderRouterManagementBorderAgentId() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::BorderAgentId::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeBorderAgentIdWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.BorderAgentId response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement BorderAgentId read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementBorderAgentId : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementBorderAgentId() + : SubscribeAttribute("border-agent-id") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementBorderAgentId() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::BorderAgentId::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeBorderAgentIdWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.BorderAgentId response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ThreadVersion + */ +class ReadThreadBorderRouterManagementThreadVersion : public ReadAttribute { +public: + ReadThreadBorderRouterManagementThreadVersion() + : ReadAttribute("thread-version") + { + } + + ~ReadThreadBorderRouterManagementThreadVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ThreadVersion::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeThreadVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ThreadVersion response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement ThreadVersion read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementThreadVersion : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementThreadVersion() + : SubscribeAttribute("thread-version") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementThreadVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ThreadVersion::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeThreadVersionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ThreadVersion response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute InterfaceEnabled + */ +class ReadThreadBorderRouterManagementInterfaceEnabled : public ReadAttribute { +public: + ReadThreadBorderRouterManagementInterfaceEnabled() + : ReadAttribute("interface-enabled") + { + } + + ~ReadThreadBorderRouterManagementInterfaceEnabled() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::InterfaceEnabled::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeInterfaceEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.InterfaceEnabled response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement InterfaceEnabled read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementInterfaceEnabled : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementInterfaceEnabled() + : SubscribeAttribute("interface-enabled") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementInterfaceEnabled() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::InterfaceEnabled::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeInterfaceEnabledWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.InterfaceEnabled response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ThreadNode + */ +class ReadThreadBorderRouterManagementThreadNode : public ReadAttribute { +public: + ReadThreadBorderRouterManagementThreadNode() + : ReadAttribute("thread-node") + { + } + + ~ReadThreadBorderRouterManagementThreadNode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ThreadNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeThreadNodeWithCompletion:^(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ThreadNode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement ThreadNode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementThreadNode : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementThreadNode() + : SubscribeAttribute("thread-node") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementThreadNode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ThreadNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeThreadNodeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(MTRThreadBorderRouterManagementClusterThreadNodeStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ThreadNode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ActiveDatasetTimestamp + */ +class ReadThreadBorderRouterManagementActiveDatasetTimestamp : public ReadAttribute { +public: + ReadThreadBorderRouterManagementActiveDatasetTimestamp() + : ReadAttribute("active-dataset-timestamp") + { + } + + ~ReadThreadBorderRouterManagementActiveDatasetTimestamp() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeActiveDatasetTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ActiveDatasetTimestamp response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement ActiveDatasetTimestamp read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementActiveDatasetTimestamp : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementActiveDatasetTimestamp() + : SubscribeAttribute("active-dataset-timestamp") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementActiveDatasetTimestamp() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ActiveDatasetTimestamp::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeActiveDatasetTimestampWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ActiveDatasetTimestamp response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadThreadBorderRouterManagementGeneratedCommandList : public ReadAttribute { +public: + ReadThreadBorderRouterManagementGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadThreadBorderRouterManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadThreadBorderRouterManagementAcceptedCommandList : public ReadAttribute { +public: + ReadThreadBorderRouterManagementAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadThreadBorderRouterManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadThreadBorderRouterManagementEventList : public ReadAttribute { +public: + ReadThreadBorderRouterManagementEventList() + : ReadAttribute("event-list") + { + } + + ~ReadThreadBorderRouterManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementEventList : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadThreadBorderRouterManagementAttributeList : public ReadAttribute { +public: + ReadThreadBorderRouterManagementAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadThreadBorderRouterManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadThreadBorderRouterManagementFeatureMap : public ReadAttribute { +public: + ReadThreadBorderRouterManagementFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadThreadBorderRouterManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadThreadBorderRouterManagementClusterRevision : public ReadAttribute { +public: + ReadThreadBorderRouterManagementClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadThreadBorderRouterManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadBorderRouterManagement ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadBorderRouterManagementClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeThreadBorderRouterManagementClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeThreadBorderRouterManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadBorderRouterManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ | Cluster WakeOnLan | 0x0503 | |------------------------------------------------------------------------------| @@ -187891,6 +189229,86 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterThreadBorderRouterManagement(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::ThreadBorderRouterManagement; + + const char * clusterName = "ThreadBorderRouterManagement"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterWakeOnLan(Commands & commands) { using namespace chip::app::Clusters::WakeOnLan; @@ -189301,6 +190719,7 @@ void registerClusters(Commands & commands) registerClusterPm10ConcentrationMeasurement(commands); registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(commands); registerClusterRadonConcentrationMeasurement(commands); + registerClusterThreadBorderRouterManagement(commands); registerClusterWakeOnLan(commands); registerClusterChannel(commands); registerClusterTargetNavigator(commands);