diff --git a/examples/proximity-ranger-app/esp32/CMakeLists.txt b/examples/proximity-ranger-app/esp32/CMakeLists.txt new file mode 100644 index 00000000000000..258043904bd52d --- /dev/null +++ b/examples/proximity-ranger-app/esp32/CMakeLists.txt @@ -0,0 +1,52 @@ +# +# 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.20) + +set(PROJECT_VER "v1.0") +set(PROJECT_VER_NUMBER 1) + +set(is_debug true CACHE BOOL "Optimization variable") +if(NOT is_debug) + set(SDKCONFIG_DEFAULTS "sdkconfig.optimize.defaults") +endif() + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/cmake/idf_flashing.cmake) + + +set(EXTRA_COMPONENT_DIRS + "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components" + "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/QRCode" +) + +project(chip-proximity-ranger-app) +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) + +# -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) +idf_build_set_property(COMPILE_OPTIONS "-Wno-error=missing-field-initializers" APPEND) + +flashing_script() diff --git a/examples/proximity-ranger-app/esp32/main/BleRssiRangingAdapter.cpp b/examples/proximity-ranger-app/esp32/main/BleRssiRangingAdapter.cpp new file mode 100644 index 00000000000000..8c8bfb95a7871f --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/BleRssiRangingAdapter.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2026 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 "BleRssiRangingAdapter.h" + +ProximityRanging::ResultCodeEnum BleRssiRangingAdapter::StartSession( + uint8_t sessionId, const ProximityRanging::Commands::StartRangingRequest::DecodableType & request, Callback & callback) +{ + // TODO: Implement ESP32 BLE RSSI scanning + return ProximityRanging::ResultCodeEnum::kRejectedInfeasibleRanging; +} + +CHIP_ERROR BleRssiRangingAdapter::StopSession(uint8_t sessionId) +{ + // TODO: Implement ESP32 session stop + return CHIP_ERROR_NOT_IMPLEMENTED; +} diff --git a/examples/proximity-ranger-app/esp32/main/CMakeLists.txt b/examples/proximity-ranger-app/esp32/main/CMakeLists.txt new file mode 100644 index 00000000000000..1e04d9cf5de79f --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/CMakeLists.txt @@ -0,0 +1,84 @@ +# +# 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. +# +# + +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(APP_COMMON_GEN_DIR ${CHIP_ROOT}/zzz_generated/app-common/app-common/zap-generated REALPATH) +get_filename_component(PROX_RANGER_COMMON_DIR ${CHIP_ROOT}/examples/proximity-ranger-app/proximity-ranger-common REALPATH) + +set(PRIV_INCLUDE_DIRS_LIST + "${CMAKE_CURRENT_LIST_DIR}/include" + "${PROX_RANGER_COMMON_DIR}/include" + "${CHIP_ROOT}/examples/platform/esp32" + "${CHIP_ROOT}/examples/providers" +) +set(SRC_DIRS_LIST + "${CMAKE_CURRENT_LIST_DIR}" + "${PROX_RANGER_COMMON_DIR}/src" + "${APP_COMMON_GEN_DIR}/attributes" + "${APP_COMMON_GEN_DIR}" + "${CHIP_ROOT}/examples/providers" + "${CHIP_ROOT}/examples/platform/esp32/ota" + "${CHIP_ROOT}/examples/platform/esp32/common" + "${CHIP_ROOT}/examples/platform/esp32/shell_extension" +) + +if (CONFIG_ENABLE_PW_RPC) +# Append additional directories for RPC build +set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" + "${CHIP_ROOT}/examples/platform/esp32/pw_sys_io/public" + "${CHIP_ROOT}/examples/common" + "${CHIP_ROOT}/examples/common/pigweed" + "${CHIP_ROOT}/examples/common/pigweed/esp32" + "${CHIP_ROOT}/src/lib/support" +) + + +if (${IDF_VERSION_MAJOR} LESS 5) + list(APPEND PRIV_INCLUDE_DIRS_LIST "${IDF_PATH}/components/freertos/include/freertos") +else() + list(APPEND PRIV_INCLUDE_DIRS_LIST "${IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos") +endif() + +set(SRC_DIRS_LIST "${SRC_DIRS_LIST}" + "${CHIP_ROOT}/examples/platform/esp32" + "${CHIP_ROOT}/examples/common/pigweed" + "${CHIP_ROOT}/examples/common/pigweed/esp32" +) +endif (CONFIG_ENABLE_PW_RPC) + +if (CONFIG_CHIP_ENABLE_ESP_DIAGNOSTICS) + list(APPEND PRIV_INCLUDE_DIRS_LIST "${CHIP_ROOT}/examples/platform/esp32/diagnostics") + list(APPEND SRC_DIRS_LIST "${CHIP_ROOT}/examples/platform/esp32/diagnostics") +endif (CONFIG_CHIP_ENABLE_ESP_DIAGNOSTICS) + +idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} + SRC_DIRS ${SRC_DIRS_LIST}) + +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) +chip_configure_data_model(${COMPONENT_LIB} + ZAP_FILE ${CHIP_ROOT}/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.zap +) + +if ((CONFIG_CHIP_ENABLE_ESP_DIAGNOSTICS) AND (CONFIG_ESP_INSIGHTS_ENABLED)) + target_add_binary_data(${COMPONENT_TARGET} "insights_auth_key.txt" TEXT) +endif() + +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/proximity-ranger-app/esp32/main/DeviceCallbacks.cpp b/examples/proximity-ranger-app/esp32/main/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..40d8e38aabac33 --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/DeviceCallbacks.cpp @@ -0,0 +1,41 @@ +/* + * + * 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. + */ + +/** + * @file DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "DeviceCallbacks.h" +#include + +static const char TAG[] = "proximity-ranger-devicecallbacks"; + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; + +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: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT)); +} diff --git a/examples/proximity-ranger-app/esp32/main/Kconfig.projbuild b/examples/proximity-ranger-app/esp32/main/Kconfig.projbuild new file mode 100644 index 00000000000000..ab26c61d79c8d9 --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/Kconfig.projbuild @@ -0,0 +1,56 @@ +# +# 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: +# 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 + + menu "Proximity Ranging Technology" + config PROXIMITY_RANGING_BLE_RSSI + bool "BLE RSSI" + default y + help + Enable BLE RSSI proximity ranging. Requires BLE to remain active + after commissioning (USE_BLE_ONLY_FOR_COMMISSIONING must be disabled). + endmenu + +endmenu diff --git a/examples/proximity-ranger-app/esp32/main/include/BleRssiRangingAdapter.h b/examples/proximity-ranger-app/esp32/main/include/BleRssiRangingAdapter.h new file mode 100644 index 00000000000000..33ce5571c7f066 --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/include/BleRssiRangingAdapter.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include + +using namespace ::chip::app::Clusters; + +class BleRssiRangingAdapter : public ProximityRanging::RangingAdapter +{ +public: + BleRssiRangingAdapter() = default; + ~BleRssiRangingAdapter() override = default; + + ProximityRanging::RangingTechEnum GetTechnology() const override + { + return ProximityRanging::RangingTechEnum::kBLEBeaconRSSIRanging; + } + + ProximityRanging::Structs::RangingCapabilitiesStruct::Type GetCapabilities() const override + { + ProximityRanging::Structs::RangingCapabilitiesStruct::Type capabilities = {}; + capabilities.technology = GetTechnology(); + capabilities.frequencyBand = chip::BitMask(ProximityRanging::RadioBandBitmap::k2g4); + capabilities.periodicRangingSupport = true; + return capabilities; + } + + ProximityRanging::ResultCodeEnum StartSession(uint8_t sessionId, + const ProximityRanging::Commands::StartRangingRequest::DecodableType & request, + Callback & callback) override; + CHIP_ERROR StopSession(uint8_t sessionId) override; +}; diff --git a/examples/proximity-ranger-app/esp32/main/include/CHIPProjectConfig.h b/examples/proximity-ranger-app/esp32/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..d9c7f3ea612a00 --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/include/CHIPProjectConfig.h @@ -0,0 +1,31 @@ +/* + * + * 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. + */ + +#pragma once + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 0 + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE 1 + +#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 0x0152 // Proximity Ranger + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_NAME 1 + +#define CHIP_DEVICE_CONFIG_DEVICE_NAME "Proximity Ranger" diff --git a/examples/proximity-ranger-app/esp32/main/include/DeviceCallbacks.h b/examples/proximity-ranger-app/esp32/main/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..2862e2b87a2fc4 --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/include/DeviceCallbacks.h @@ -0,0 +1,39 @@ +/* + * + * 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. + */ + +/** + * @file DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#ifndef DEVICE_CALLBACKS_H +#define DEVICE_CALLBACKS_H + +#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); +}; + +#endif // DEVICE_CALLBACKS_H diff --git a/examples/proximity-ranger-app/esp32/main/main.cpp b/examples/proximity-ranger-app/esp32/main/main.cpp new file mode 100644 index 00000000000000..328a45dbbad07b --- /dev/null +++ b/examples/proximity-ranger-app/esp32/main/main.cpp @@ -0,0 +1,165 @@ +/* + * + * 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 "DeviceCallbacks.h" + +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs_flash.h" +#include "shell_extension/launch.h" +#include "shell_extension/openthread_cli_register.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if CONFIG_PROXIMITY_RANGING_BLE_RSSI +#include "BleRssiRangingAdapter.h" +#endif + +#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::DeviceManager; +using namespace ::chip::Credentials; +using namespace ::chip::app::Clusters; +using namespace ::chip::app::Clusters::ProximityRanging; + +namespace { +#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider; +#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER + +#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER +chip::DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider; +#else +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER + +constexpr EndpointId kProximityRangingEndpoint = 1; + +RangingTechnologyController sController; +DefaultProximityRangingDriver sDriver(sController); +ProximityRanging::Instance sInstance(kProximityRangingEndpoint, sDriver, + BitMask( +#if CONFIG_PROXIMITY_RANGING_BLE_RSSI + Feature::kBleBeaconRssi) +#endif +); + +#if CONFIG_PROXIMITY_RANGING_BLE_RSSI +BleRssiRangingAdapter sBleRssiAdapter; +#endif +} // namespace + +static const char TAG[] = "proximity-ranger-app"; + +static AppDeviceCallbacks EchoCallbacks; + +static void InitServer(intptr_t context) +{ + Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config + +#if CONFIG_PROXIMITY_RANGING_BLE_RSSI + LogErrorOnFailure(sController.RegisterAdapter(sBleRssiAdapter)); +#endif + + CHIP_ERROR err = sInstance.Init(); + if (err != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "ProximityRanging::Instance::Init() failed: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +extern "C" void app_main() +{ + ESP_LOGI(TAG, "Proximity Ranger!"); + + // 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; + } +#if CONFIG_ENABLE_PW_RPC + chip::rpc::Init(); +#endif + + ESP_LOGI(TAG, "=================================================="); + ESP_LOGI(TAG, "chip-esp32-proximity-ranger-example starting"); + ESP_LOGI(TAG, "=================================================="); + +#if CONFIG_ENABLE_CHIP_SHELL + chip::LaunchShell(); +#endif +#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 + + DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks); + 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 + + error = chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); + if (error != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "PlatformMgr().ScheduleWork() failed, error:%" CHIP_ERROR_FORMAT, error.Format()); + return; + } +} diff --git a/examples/proximity-ranger-app/esp32/partitions.csv b/examples/proximity-ranger-app/esp32/partitions.csv new file mode 100644 index 00000000000000..487ac3e70dd993 --- /dev/null +++ b/examples/proximity-ranger-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, +phy_init, data, phy, , 0x1000, +# Factory partition size about 1.5MB +factory, app, factory, , 1536K, +coredump, data, coredump,, 64K, encrypted diff --git a/examples/proximity-ranger-app/esp32/sdkconfig.defaults b/examples/proximity-ranger-app/esp32/sdkconfig.defaults new file mode 100644 index 00000000000000..495e20be1ddf5a --- /dev/null +++ b/examples/proximity-ranger-app/esp32/sdkconfig.defaults @@ -0,0 +1,62 @@ +# +# Copyright (c) 2025 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. +# + +# Enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +# Disable BT connection reattempt +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +# Enable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" + +# Enable lwIP route hooks +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y + +# Serial Flasher config +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" + +# Disable softap support by default +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + +# Move functions from IRAM to flash +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y + +# Increase LwIP IPv6 address number +CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 + +# Disable Read Client (saves memory) +CONFIG_DISABLE_READ_CLIENT=y + +# Enable CHIP Shell +CONFIG_ENABLE_CHIP_SHELL=y + +# BLE RSSI ranging requires BLE to stay active after commissioning +CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n \ No newline at end of file diff --git a/examples/proximity-ranger-app/esp32/third_party/connectedhomeip b/examples/proximity-ranger-app/esp32/third_party/connectedhomeip new file mode 120000 index 00000000000000..11a54ed360106c --- /dev/null +++ b/examples/proximity-ranger-app/esp32/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/examples/proximity-ranger-app/linux/.gn b/examples/proximity-ranger-app/linux/.gn new file mode 100644 index 00000000000000..ae3a074718ee6a --- /dev/null +++ b/examples/proximity-ranger-app/linux/.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2026 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + import("//args.gni") +} diff --git a/examples/proximity-ranger-app/linux/BUILD.gn b/examples/proximity-ranger-app/linux/BUILD.gn new file mode 100644 index 00000000000000..d5131a2664c770 --- /dev/null +++ b/examples/proximity-ranger-app/linux/BUILD.gn @@ -0,0 +1,57 @@ +# 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. + +import("//build_overrides/chip.gni") + +import("${chip_root}/build/chip/tools.gni") +import("${chip_root}/src/app/common_flags.gni") + +assert(chip_build_tools) + +config("includes") { + include_dirs = [ + ".", + "include", + ] +} + +executable("proximity-ranger-app") { + sources = [ + "${chip_root}/examples/proximity-ranger-app/proximity-ranger-common/src/RangingTechnologyController.cpp", + "BleRssiRangingAdapter.cpp", + "include/CHIPProjectAppConfig.h", + "main.cpp", + ] + + deps = [ + "${chip_root}/examples/platform/linux:app-main", + "${chip_root}/examples/proximity-ranger-app/proximity-ranger-common", + "${chip_root}/src/lib", + ] + + include_dirs = [ + "include", + "${chip_root}/examples/proximity-ranger-app/proximity-ranger-common/include", + ] + + output_dir = root_out_dir +} + +group("linux") { + deps = [ ":proximity-ranger-app" ] +} + +group("default") { + deps = [ ":linux" ] +} diff --git a/examples/proximity-ranger-app/linux/BleRssiRangingAdapter.cpp b/examples/proximity-ranger-app/linux/BleRssiRangingAdapter.cpp new file mode 100644 index 00000000000000..be13395ea0fa91 --- /dev/null +++ b/examples/proximity-ranger-app/linux/BleRssiRangingAdapter.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2026 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 "BleRssiRangingAdapter.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +ResultCodeEnum BleRssiRangingAdapter::StartSession(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request, + Callback & callback) +{ + // TODO: Implement Linux BLE RSSI scanning + return ResultCodeEnum::kRejectedInfeasibleRanging; +} + +CHIP_ERROR BleRssiRangingAdapter::StopSession(uint8_t sessionId) +{ + // TODO: Implement Linux session stop + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/proximity-ranger-app/linux/args.gni b/examples/proximity-ranger-app/linux/args.gni new file mode 100644 index 00000000000000..aa1247c46c36fe --- /dev/null +++ b/examples/proximity-ranger-app/linux/args.gni @@ -0,0 +1,28 @@ +# 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. + +# CHIPProjectConfig.h + +import("//build_overrides/chip.gni") + +import("${chip_root}/config/standalone/args.gni") + +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_system_project_config_include = "" + +chip_project_config_include_dirs = + [ "${chip_root}/examples/proximity-ranger-app/linux/include" ] +chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] +matter_enable_tracing_support = true diff --git a/examples/proximity-ranger-app/linux/build_overrides b/examples/proximity-ranger-app/linux/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/proximity-ranger-app/linux/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/proximity-ranger-app/linux/include/BleRssiRangingAdapter.h b/examples/proximity-ranger-app/linux/include/BleRssiRangingAdapter.h new file mode 100644 index 00000000000000..24365acf3a48b4 --- /dev/null +++ b/examples/proximity-ranger-app/linux/include/BleRssiRangingAdapter.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +class BleRssiRangingAdapter : public RangingAdapter +{ +public: + BleRssiRangingAdapter() = default; + ~BleRssiRangingAdapter() override = default; + + RangingTechEnum GetTechnology() const override { return RangingTechEnum::kBLEBeaconRSSIRanging; } + + Structs::RangingCapabilitiesStruct::Type GetCapabilities() const override + { + Structs::RangingCapabilitiesStruct::Type capabilities = {}; + capabilities.technology = GetTechnology(); + capabilities.frequencyBand = BitMask(RadioBandBitmap::k2g4); + capabilities.periodicRangingSupport = true; + return capabilities; + } + + ResultCodeEnum StartSession(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request, + Callback & callback) override; + CHIP_ERROR StopSession(uint8_t sessionId) override; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/proximity-ranger-app/linux/include/CHIPProjectAppConfig.h b/examples/proximity-ranger-app/linux/include/CHIPProjectAppConfig.h new file mode 100644 index 00000000000000..186745c9cc5cf0 --- /dev/null +++ b/examples/proximity-ranger-app/linux/include/CHIPProjectAppConfig.h @@ -0,0 +1,38 @@ +/* + * + * 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. + */ + +#pragma once + +// include the CHIPProjectConfig from config/standalone +#include + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 0 + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT 1 + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE 1 + +#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 0x0152 // Proximity Ranger + +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_NAME 1 + +#define CHIP_DEVICE_ENABLE_PORT_PARAMS 1 + +#define CHIP_DEVICE_CONFIG_DEVICE_NAME "Proximity Ranger" diff --git a/examples/proximity-ranger-app/linux/main.cpp b/examples/proximity-ranger-app/linux/main.cpp new file mode 100644 index 00000000000000..87a4af02e715dd --- /dev/null +++ b/examples/proximity-ranger-app/linux/main.cpp @@ -0,0 +1,61 @@ +/* + * + * 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. + */ + +#include +#include + +#include +#include + +#include "BleRssiRangingAdapter.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ProximityRanging; + +namespace { + +constexpr EndpointId kProximityRangingEndpoint = 1; + +RangingTechnologyController sController; +DefaultProximityRangingDriver sDriver(sController); +ProximityRanging::Instance sInstance(kProximityRangingEndpoint, sDriver, + BitMask(Feature::kWiFiUsdProximityDetection, Feature::kBleBeaconRssi)); + +BleRssiRangingAdapter sBleRssiAdapter; + +} // namespace + +void ApplicationInit() +{ + LogErrorOnFailure(sController.RegisterAdapter(sBleRssiAdapter)); + VerifyOrDie(sInstance.Init() == CHIP_NO_ERROR); +} + +void ApplicationShutdown() +{ + sInstance.Shutdown(); +} + +int main(int argc, char * argv[]) +{ + VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + ChipLinuxAppMainLoop(); + return 0; +} diff --git a/examples/proximity-ranger-app/linux/third_party/connectedhomeip b/examples/proximity-ranger-app/linux/third_party/connectedhomeip new file mode 120000 index 00000000000000..11a54ed360106c --- /dev/null +++ b/examples/proximity-ranger-app/linux/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/examples/proximity-ranger-app/proximity-ranger-common/BUILD.gn b/examples/proximity-ranger-app/proximity-ranger-common/BUILD.gn new file mode 100644 index 00000000000000..3e95939f31610b --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/BUILD.gn @@ -0,0 +1,25 @@ +# 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/src/app/chip_data_model.gni") + +config("config") { + include_dirs = [ "include" ] +} + +chip_data_model("proximity-ranger-common") { + zap_file = "proximity-ranger-app.zap" + is_server = true +} diff --git a/examples/proximity-ranger-app/proximity-ranger-common/include/DefaultProximityRangingDriver.h b/examples/proximity-ranger-app/proximity-ranger-common/include/DefaultProximityRangingDriver.h new file mode 100644 index 00000000000000..db487eaa0c0d62 --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/include/DefaultProximityRangingDriver.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include + +#include "RangingTechnologyController.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * ProximityRangingDriver implementation that routes ranging operations through + * a RangingTechnologyController and forwards async results back to the cluster. + * + * @code + * static RangingTechnologyController sController; + * static DefaultProximityRangingDriver sDriver(sController); + * static ProximityRanging::Instance sInstance(endpointId, sDriver, features); + * + * void ApplicationInit() { + * sController.RegisterAdapter(sBleAdapter); + * sInstance.Init(); + * } + * @endcode + */ +class DefaultProximityRangingDriver : public ProximityRangingDriver, public RangingTechnologyController::Listener +{ +public: + explicit DefaultProximityRangingDriver(RangingTechnologyController & controller) : mController(controller) {} + + // ProximityRangingDriver implementation + + CHIP_ERROR Init(Callback & callback) override + { + mCallback = &callback; + mController.SetListener(*this); + return CHIP_NO_ERROR; + } + + void Shutdown() override + { + mController.StopAllSessions(); + mCallback = nullptr; + } + + ResultCodeEnum HandleStartRanging(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request) override + { + return mController.StartSession(sessionId, request); + } + + CHIP_ERROR HandleStopRanging(uint8_t sessionId) override { return mController.StopSession(sessionId); } + + CHIP_ERROR GetRangingCapabilities(AttributeValueEncoder & encoder) override + { + return mController.GetRangingCapabilities(encoder); + } + + // RangingTechnologyController::Listener implementation + + void OnSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) override + { + VerifyOrReturn(mCallback != nullptr); + mCallback->OnSessionStopped(sessionId, status); + } + + void OnSessionMeasurement(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) override + { + VerifyOrReturn(mCallback != nullptr); + mCallback->OnMeasurementData(sessionId, measurement); + } + +private: + RangingTechnologyController & mController; + Callback * mCallback = nullptr; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/proximity-ranger-app/proximity-ranger-common/include/RangingAdapter.h b/examples/proximity-ranger-app/proximity-ranger-common/include/RangingAdapter.h new file mode 100644 index 00000000000000..74e9dae1e095aa --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/include/RangingAdapter.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * Interface for a single ranging technology (BLE RSSI, Channel Sounding, Wi-Fi USD, etc.). + * + * Platform-specific adapters implement this and are registered with a + * RangingTechnologyController. Adapters must outlive the controller. + * All methods are called from the Matter main thread. + */ +class RangingAdapter +{ +public: + /** Receives async results from ranging sessions. */ + class Callback + { + public: + virtual ~Callback() = default; + + virtual void OnRangingSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) = 0; + virtual void OnMeasurementData(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) = 0; + }; + + virtual ~RangingAdapter() = default; + + /** + * Returns the ranging technology this adapter implements. + */ + virtual RangingTechEnum GetTechnology() const = 0; + + /** + * Returns the ranging capabilities this adapter supports. + */ + virtual Structs::RangingCapabilitiesStruct::Type GetCapabilities() const = 0; + + /** + * Start a ranging session synchronously. Measurement data and unsolicited + * session stops are still delivered asynchronously via the Callback. + */ + virtual ResultCodeEnum StartSession(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request, + Callback & callback) = 0; + + /** + * Stop an active ranging session synchronously. + */ + virtual CHIP_ERROR StopSession(uint8_t sessionId) = 0; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/proximity-ranger-app/proximity-ranger-common/include/RangingTechnologyController.h b/examples/proximity-ranger-app/proximity-ranger-common/include/RangingTechnologyController.h new file mode 100644 index 00000000000000..fe9fb3a6643871 --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/include/RangingTechnologyController.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include +#include + +#include + +#include "RangingAdapter.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * Maximum number of adapters which the controller allows to register. + * Implementers should ensure this is set to the number of ranging technologies the + * device plans to support. + */ +static constexpr uint8_t kMaxControllerAdapters = 2; + +/** + * Routes ranging sessions to the appropriate technology adapter based on the + * requested technology. Maintains a registry of adapters (one per technology) + * and tracks which adapter owns each active session. + * + * The application creates the controller and adapters. The controller holds + * non-owning references to adapters, which must outlive the controller. + * All methods are called from the Matter main thread. + */ +class RangingTechnologyController : public RangingAdapter::Callback +{ +public: + /** Receives async results from adapters, forwarded to the driver. */ + class Listener + { + public: + virtual ~Listener() = default; + + virtual void OnSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) = 0; + virtual void OnSessionMeasurement(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) = 0; + }; + + RangingTechnologyController() = default; + + /** + * Set the listener that receives async results from adapters. + * Must be called before any sessions are started. + */ + void SetListener(Listener & listener) { mListener = &listener; } + + /** + * Register a technology adapter. Only one adapter per technology is allowed. + * + * @return CHIP_NO_ERROR on success, CHIP_ERROR_NO_MEMORY if full, + * CHIP_ERROR_DUPLICATE_KEY_ID if technology already registered. + */ + CHIP_ERROR RegisterAdapter(RangingAdapter & adapter); + + /** + * Encode the capabilities from all registered adapters. + */ + CHIP_ERROR GetRangingCapabilities(AttributeValueEncoder & encoder); + + /** + * Route a StartRangingRequest to the appropriate adapter based on the + * Technology field. Tracks the session→adapter mapping. + */ + ResultCodeEnum StartSession(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request); + + /** + * Route a StopRangingRequest to the adapter that owns the session. + */ + CHIP_ERROR StopSession(uint8_t sessionId); + + /** + * Stop all active sessions and clear state. + */ + void StopAllSessions(); + + // RangingAdapter::Callback implementation + void OnRangingSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) override; + void OnMeasurementData(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) override; + +private: + RangingAdapter * FindAdapter(RangingTechEnum technology); + + struct SessionEntry + { + uint8_t sessionId = 0; + RangingAdapter * adapter = nullptr; + }; + + RangingAdapter * mAdapters[kMaxControllerAdapters] = {}; + size_t mAdapterCount = 0; + std::vector mSessions; + Listener * mListener = nullptr; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.matter b/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.matter new file mode 100644 index 00000000000000..9123b14b6db67f --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.matter @@ -0,0 +1,2245 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54 [spec_name = "Media/TV Room"]; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; + kToilet = 95; +} + +enum AtomicRequestTypeEnum : enum8 { + kBeginWrite = 0; + kCommitWrite = 1; + kRollbackWrite = 2; +} + +enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; +} + +enum LocationTag : enum8 { + kIndoor = 0; + kOutdoor = 1; + kInside = 2; + kOutside = 3; +} + +enum MeasurementTypeEnum : enum16 { + kUnspecified = 0; + kVoltage = 1; + kActiveCurrent = 2; + kReactiveCurrent = 3; + kApparentCurrent = 4; + kActivePower = 5; + kReactivePower = 6; + kApparentPower = 7; + kRMSVoltage = 8; + kRMSCurrent = 9; + kRMSPower = 10; + kFrequency = 11; + kPowerFactor = 12; + kNeutralCurrent = 13; + kElectricalEnergy = 14; + kReactiveEnergy = 15; + kApparentEnergy = 16; + kSoilMoisture = 17; +} + +enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; +} + +enum PowerThresholdSourceEnum : enum8 { + kContract = 0; + kRegulator = 1; + kEquipment = 2; +} + +enum RelativePositionTag : enum8 { + kUnder = 0; + kNextTo = 1; + kAround = 2; + kOn = 3; + kAbove = 4; + kFrontOf = 5; + kBehind = 6; +} + +enum SoftwareVersionCertificationStatusEnum : enum8 { + kDevTest = 0; + kProvisional = 1; + kCertified = 2; + kRevoked = 3; +} + +enum StreamUsageEnum : enum8 { + kInternal = 0; + kRecording = 1; + kAnalysis = 2; + kLiveView = 3; +} + +enum TariffPriceTypeEnum : enum8 { + kStandard = 0; + kCritical = 1; + kVirtual = 2; + kIncentive = 3; + kIncentiveSignal = 4; +} + +enum TariffUnitEnum : enum8 { + kKWh = 0; + kKVAh = 1; +} + +enum TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +enum ThreeLevelAutoEnum : enum8 { + kAuto = 0; + kLow = 1; + kMedium = 2; + kHigh = 3; +} + +enum WebRTCEndReasonEnum : enum8 { + kICEFailed = 0; + kICETimeout = 1; + kUserHangup = 2; + kUserBusy = 3; + kReplaced = 4; + kNoUserMedia = 5; + kInviteTimeout = 6; + kAnsweredElsewhere = 7; + kOutOfResources = 8; + kMediaTimeout = 9; + kLowPower = 10; + kPrivacyMode = 11; + kUnknownReason = 12; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct CurrencyStruct { + int16u currency = 0; + int8u decimalPoints = 1; +} + +struct PriceStruct { + money amount = 0; + CurrencyStruct currency = 1; +} + +struct MeasurementAccuracyRangeStruct { + int64s rangeMin = 0; + int64s rangeMax = 1; + optional percent100ths percentMax = 2; + optional percent100ths percentMin = 3; + optional percent100ths percentTypical = 4; + optional int64u fixedMax = 5; + optional int64u fixedMin = 6; + optional int64u fixedTypical = 7; +} + +struct MeasurementAccuracyStruct { + MeasurementTypeEnum measurementType = 0; + boolean measured = 1; + int64s minMeasuredValue = 2; + int64s maxMeasuredValue = 3; + MeasurementAccuracyRangeStruct accuracyRanges[] = 4; +} + +struct AtomicAttributeStatusStruct { + attrib_id attributeID = 0; + status statusCode = 1; +} + +struct ICECandidateStruct { + char_string candidate = 0; + nullable char_string SDPMid = 1; + nullable int16u SDPMLineIndex = 2; +} + +struct ICEServerStruct { + char_string URLs[] = 0; + optional long_char_string<508> username = 1; + optional long_char_string<512> credential = 2; + optional int16u caid = 3; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + +struct PowerThresholdStruct { + optional power_mw powerThreshold = 0; + optional power_mva apparentPowerThreshold = 1; + nullable PowerThresholdSourceEnum powerThresholdSource = 2; +} + +struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string<64> label = 3; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct ViewportStruct { + int16u x1 = 0; + int16u y1 = 1; + int16u x2 = 2; + int16u y2 = 3; +} + +fabric_scoped struct WebRTCSessionStruct { + int16u id = 0; + node_id peerNodeID = 1; + endpoint_no peerEndpointID = 2; + StreamUsageEnum streamUsage = 3; + nullable int16u videoStreamID = 4; + nullable int16u audioStreamID = 5; + boolean metadataEnabled = 6; + optional int16u videoStreams[] = 7; + optional int16u audioStreams[] = 8; + fabric_idx fabricIndex = 254; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 6; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** This command starts or stops the receiving device identifying itself. */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** This command allows the support of feedback to the user, such as a certain light effect. */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** 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 3; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + 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 optional char_string<32> endpointUniqueID = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + 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 3; + + enum AccessControlAuxiliaryTypeEnum : enum8 { + kSystem = 0; + kGroupcast = 1; + } + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1 [spec_name = "PASE"]; + kCASE = 2 [spec_name = "CASE"]; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + kAuxiliary = 0x4; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + + 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; + optional fabric_sensitive AccessControlAuxiliaryTypeEnum auxiliaryType = 5; + 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; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { + int64u token = 0; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AuxiliaryAccessUpdated = 3 { + nullable node_id adminNodeID = 0; + 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 optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; + readonly attribute access(read: administer) optional AccessControlEntryStruct auxiliaryACL[] = 7; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; +} + +/** 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 6; + + 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; + optional int16u simultaneousInvocationsSupported = 2; + optional int16u simultaneousWritesSupported = 3; + optional int16u readPathsSupported = 4; + optional int16u subscribePathsSupported = 5; + } + + 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 optional int32u specificationVersion = 21; + readonly attribute optional int16u maxPathsPerInvoke = 22; + attribute access(write: administer) optional nullable LocationDescriptorStruct deviceLocation = 23; + readonly attribute optional int32u configurationVersion = 24; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Provides an interface for providing OTA software updates */ +cluster OtaSoftwareUpdateProvider = 41 { + revision 1; // NOTE: Default/not specifically set + + enum ApplyUpdateActionEnum : enum8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum DownloadProtocolEnum : enum8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHTTPS = 2 [spec_name = "HTTPS"]; + kVendorSpecific = 3; + } + + enum StatusEnum : enum8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorID = 0; + int16u productID = 1; + int32u softwareVersion = 2; + DownloadProtocolEnum protocolsSupported[] = 3; + optional int16u hardwareVersion = 4; + optional char_string<2> location = 5; + optional boolean requestorCanConsent = 6; + optional octet_string<512> metadataForProvider = 7; + } + + response struct QueryImageResponse = 1 { + StatusEnum status = 0; + optional int32u delayedActionTime = 1; + optional char_string<256> imageURI = 2; + optional int32u softwareVersion = 3; + optional char_string<64> softwareVersionString = 4; + optional octet_string<32> updateToken = 5; + optional boolean userConsentNeeded = 6; + optional octet_string<512> metadataForRequestor = 7; + } + + request struct ApplyUpdateRequestRequest { + octet_string<32> updateToken = 0; + int32u newVersion = 1; + } + + response struct ApplyUpdateResponse = 3 { + ApplyUpdateActionEnum action = 0; + int32u delayedActionTime = 1; + } + + request struct NotifyUpdateAppliedRequest { + octet_string<32> updateToken = 0; + int32u softwareVersion = 1; + } + + /** Determine availability of a new Software Image */ + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + /** Determine next action to take for a downloaded Software Image */ + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + /** Notify OTA Provider that an update was applied */ + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +/** Provides an interface for downloading and applying OTA software updates */ +cluster OtaSoftwareUpdateRequestor = 42 { + revision 1; // NOTE: Default/not specifically set + + enum AnnouncementReasonEnum : enum8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum ChangeReasonEnum : enum8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum UpdateStateEnum : enum8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + UpdateStateEnum previousState = 0; + UpdateStateEnum newState = 1; + ChangeReasonEnum reason = 2; + nullable int32u targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + int32u softwareVersion = 0; + int16u productID = 1; + } + + info event DownloadError = 2 { + int32u softwareVersion = 0; + int64u bytesDownloaded = 1; + nullable int8u progressPercent = 2; + nullable int64s platformCode = 3; + } + + attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute UpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOTAProviderRequest { + node_id providerNodeID = 0; + vendor_id vendorID = 1; + AnnouncementReasonEnum announcementReason = 2; + optional octet_string<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + /** Announce the presence of an OTA Provider */ + command access(invoke: administer) AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 2; + + enum CommissioningErrorEnum : enum8 { + kOK = 0 [spec_name = "OK"]; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; + } + + enum NetworkRecoveryReasonEnum : enum8 { + kUnspecified = 0; + kAuth = 1; + kVisibility = 2; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + kNetworkRecovery = 0x2; + } + + 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; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: manage) optional octet_string<8> recoveryIdentifier = 10; + provisional readonly attribute access(read: manage) optional nullable NetworkRecoveryReasonEnum networkRecoveryReason = 11; + provisional readonly attribute optional boolean isCommissioningWithoutPower = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + 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; + } + + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + + /** This command is used to arm or disarm the fail-safe timer. */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** This command is used to set the regulatory configuration for the device. */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** This command is used to indicate that the commissioning process is complete. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command is used to set the user acknowledgements received in the Enhanced Setup Flow Terms & Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 3; + + 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 [spec_name = "2G4"]; + k3G65 = 1 [spec_name = "3G65"]; + k5G = 2 [spec_name = "5G"]; + k6G = 3 [spec_name = "6G"]; + k60G = 4 [spec_name = "60G"]; + k1G = 5 [spec_name = "1G"]; + } + + 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 [spec_name = "WEP"]; + kWPAPersonal = 0x4 [spec_name = "WPA-PERSONAL"]; + kWPA2Personal = 0x8 [spec_name = "WPA2-PERSONAL"]; + kWPA3Personal = 0x10 [spec_name = "WPA3-PERSONAL"]; + kWPA3MatterPDC = 0x20 [spec_name = "WPA3-Matter-PDC"]; + } + + 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 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 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 long_char_string<512> 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 long_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; + } + + /** This command is used to scan for available networks on the network interface associated with the cluster instance. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** This command is used to add or update a Wi-Fi network configuration. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** This command is used to add or update a Thread network configuration. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** This command is used to remove a network configuration on the network interface associated with the cluster instance. */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** This command is used to connect to a network on the network interface associated with the cluster instance. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** This command is used to re-order the network configuration list. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** This command is used to query the identity of a network configuration. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 1 [spec_name = "BDX"]; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string<1024> logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Reception of this command starts the process of retrieving diagnostic logs from a Node. */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** 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 3; + + 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 DeviceLoadStruct { + int16u currentSubscriptions = 0; + int16u currentSubscriptionsForFabric = 1; + int32u totalSubscriptionsEstablished = 2; + int32u totalInteractionModelMessagesSent = 3; + int32u totalInteractionModelMessagesReceived = 4; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string 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 optional DeviceLoadStruct deviceLoadStatus = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + 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 { + long_octet_string<2048> payload = 0; + } + + /** This command SHALL be supported to provide a means for certification tests to trigger some test-plan-specific events, necessary to assist in automation of device interactions for some certification test cases. */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** This command MAY be used by a client to obtain a correlated view of both System Time, and, if currently synchronized and supported, "wall clock time" of the server. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** This command provides a means for certification tests or manufacturer's internal tests to validate particular command handling and encoding constraints by generating a response of a given size. */ + command access(invoke: manage) PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Software 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 SoftwareDiagnostics = 52 { + revision 1; + + bitmap Feature : bitmap32 { + kWatermarks = 0x1; + } + + struct ThreadMetricsStruct { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + int64u id = 0; + optional char_string name = 1; + optional long_octet_string faultRecording = 2; + } + + readonly attribute optional ThreadMetricsStruct threadMetrics[] = 0; + readonly attribute optional int64u currentHeapFree = 1; + readonly attribute optional int64u currentHeapUsed = 2; + readonly attribute optional int64u currentHeapHighWatermark = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** This command is used to reset the high watermarks for heap and stack memory. */ + command access(invoke: manage) ResetWatermarks(): DefaultSuccess = 0; +} + +/** The Wi-Fi 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 WiFiNetworkDiagnostics = 54 { + revision 1; + + enum AssociationFailureCauseEnum : enum8 { + kUnknown = 0; + kAssociationFailed = 1; + kAuthenticationFailed = 2; + kSsidNotFound = 3; + } + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum SecurityTypeEnum : enum8 { + kUnspecified = 0; + kNone = 1; + kWEP = 2 [spec_name = "WEP"]; + kWPA = 3 [spec_name = "WPA"]; + kWPA2 = 4 [spec_name = "WPA2"]; + kWPA3 = 5 [spec_name = "WPA3"]; + } + + enum WiFiVersionEnum : enum8 { + kA = 0; + kB = 1; + kG = 2; + kN = 3; + kAc = 4; + kAx = 5; + kAh = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + info event Disconnection = 0 { + int16u reasonCode = 0; + } + + info event AssociationFailure = 1 { + AssociationFailureCauseEnum associationFailureCause = 0; + int16u status = 1; + } + + info event ConnectionStatus = 2 { + ConnectionStatusEnum connectionStatus = 0; + } + + readonly attribute nullable octet_string<6> bssid = 0; + readonly attribute nullable SecurityTypeEnum securityType = 1; + readonly attribute nullable WiFiVersionEnum wiFiVersion = 2; + readonly attribute nullable int16u channelNumber = 3; + readonly attribute nullable int8s rssi = 4; + readonly attribute optional nullable int32u beaconLostCount = 5; + readonly attribute optional nullable int32u beaconRxCount = 6; + readonly attribute optional nullable int32u packetMulticastRxCount = 7; + readonly attribute optional nullable int32u packetMulticastTxCount = 8; + readonly attribute optional nullable int32u packetUnicastRxCount = 9; + readonly attribute optional nullable int32u packetUnicastTxCount = 10; + readonly attribute optional nullable int64u currentMaxRate = 11; + readonly attribute optional nullable int64u overrunCount = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** This command is used to reset the count attributes. */ + command ResetCounts(): DefaultSuccess = 0; +} + +/** The Ethernet 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 EthernetNetworkDiagnostics = 55 { + revision 1; + + enum PHYRateEnum : enum8 { + kRate10M = 0; + kRate100M = 1; + kRate1G = 2; + kRate25G = 3 [spec_name = "Rate2_5G"]; + kRate5G = 4; + kRate10G = 5; + kRate40G = 6; + kRate100G = 7; + kRate200G = 8; + kRate400G = 9; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + readonly attribute optional nullable PHYRateEnum PHYRate = 0; + readonly attribute optional nullable boolean fullDuplex = 1; + readonly attribute optional int64u packetRxCount = 2; + readonly attribute optional int64u packetTxCount = 3; + readonly attribute optional int64u txErrCount = 4; + readonly attribute optional int64u collisionCount = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute optional nullable boolean carrierDetect = 7; + readonly attribute optional int64u timeSinceReset = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** This command is used to reset the count attributes. */ + 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; + + 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 attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string<97> 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. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command MAY be used by a current Administrator to instruct a Node to go into commissioning mode, if the node supports the Basic Commissioning Method. */ + 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 OpenCommissioningWindow or OpenBasicCommissioningWindow 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 2; + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0 [spec_name = "OK"]; + 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; + optional octet_string<85> VIDVerificationStatement = 6; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + long_octet_string<400> noc = 1; + nullable long_octet_string<400> icac = 2; + optional long_octet_string<400> vvsc = 3; + 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 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 { + long_octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + long_octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + long_octet_string<900> NOCSRElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct AddNOCRequest { + long_octet_string<400> NOCValue = 0; + optional long_octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + long_octet_string<400> NOCValue = 0; + optional long_octet_string<400> 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 { + long_octet_string<400> rootCACertificate = 0; + } + + request struct SetVIDVerificationStatementRequest { + optional vendor_id vendorID = 0; + optional octet_string<85> VIDVerificationStatement = 1; + optional long_octet_string<400> vvsc = 2; + } + + request struct SignVIDVerificationRequestRequest { + fabric_idx fabricIndex = 0; + octet_string<32> clientChallenge = 1; + } + + response struct SignVIDVerificationResponse = 14 { + fabric_idx fabricIndex = 0; + int8u fabricBindingVersion = 1; + octet_string signature = 2; + } + + /** This command is used to perform an attestation request. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** This command is used to request a certificate from the device attestation certificate chain. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** This command is used to perform a CSR request. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** This command is used to add a new NOC to the device. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** This command is used to update an existing NOC on the device. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command is used to set the user-visible fabric label for a given Fabric. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used to remove a Fabric from the device. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command is used to add a trusted root certificate to the device. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; + /** This command is used to manage the VendorID and VIDVerificationStatement fields of the Fabrics attribute, and the VVSC field of an entry in the NOCs attribute. */ + fabric command access(invoke: administer) SetVIDVerificationStatement(SetVIDVerificationStatementRequest): DefaultSuccess = 12; + /** This command is used to authenticate the fabric associated with the FabricIndex. */ + command access(invoke: administer) SignVIDVerificationRequest(SignVIDVerificationRequestRequest): SignVIDVerificationResponse = 13; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 3; + + enum GroupKeyMulticastPolicyEnum : enum8 { + kPerGroupID = 0; + kAllNodes = 1; + } + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + kGroupcast = 0x2; + } + + 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; + GroupKeyMulticastPolicyEnum groupKeyMulticastPolicy = 8; + } + + fabric_scoped struct GroupcastAdoptionStruct { + boolean groupcastAdopted = 0; + fabric_idx fabricIndex = 254; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + attribute access(read: administer, write: administer) optional GroupcastAdoptionStruct groupcastAdoption[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + 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; + } + + /** This command is used by Administrators to set the state of a given Group Key Set, including atomically updating the state of all epoch keys. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** This command is used by Administrators to read the state of a given Group Key Set. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** This command is used by Administrators to remove all state of a given Group Key Set. */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** This command is used by Administrators to query a list of all Group Key Sets associated with the accessing fabric. */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** The User Label Cluster provides a feature to tag an endpoint with zero or more labels. */ +cluster UserLabel = 65 { + revision 1; + + shared 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 attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster enables the configuration of proximity ranging sessions and reporting of proximity ranging data. */ +provisional cluster ProximityRanging = 1075 { + revision 1; + + enum BLTCSModeEnum : enum8 { + kPBROnly = 0; + kRTTOnly = 1; + kBoth = 2; + } + + enum BLTCSSecurityLevelEnum : enum8 { + kBLTCSSecurityLevelUnknown = 0; + kBLTCSSecurityLevelOne = 1; + kBLTCSSecurityLevelTwo = 2; + kBLTCSSecurityLevelThree = 3; + } + + enum NADMEnum : enum16 { + kAttackExtremelyUnlikely = 0; + kAttackVeryUnlikely = 1; + kAttackUnlikely = 2; + kAttackIsPossible = 3; + kAttackIsLikely = 4; + kAttackVeryLikely = 5; + kAttackExtremelyLikely = 6; + kUnknown = 255; + } + + enum RDRReferenceEnum : enum8 { + kDeviceCoordinates = 0; + kEarthCoordinates = 1; + } + + enum RangingRoleEnum : enum8 { + kWiFiSubscriberRole = 0; + kWiFiPublisherRole = 1; + kBLEScanningRole = 2; + kBLEBeaconRole = 3; + kBLTInitiatorRole = 4; + kBLTReflectorRole = 5; + } + + enum RangingSecurityEnum : enum8 { + kSecureRanging = 0; + kOpenRanging = 1; + } + + enum RangingSessionStatusEnum : enum8 { + kSessionEndTimeReached = 0; + kPeerNotFound = 1; + kHardwareError = 2; + } + + enum RangingTechEnum : enum8 { + kBluetoothChannelSounding = 0; + kWiFiRoundTripTimeRanging = 1; + kWiFiNextGenerationRanging = 2; + kBLEBeaconRSSIRanging = 3; + } + + enum ResultCodeEnum : enum8 { + kAccepted = 0; + kRejectedInfeasibleRanging = 1; + kRejectedInfeasibleRangingTriggers = 2; + kBusySessionCapacityReached = 3; + kBusyTryAgainLater = 4; + } + + bitmap Feature : bitmap32 { + kWiFiUSDProximityDetection = 0x1 [spec_name = "Wi-Fi USD Proximity Detection"]; + kBluetoothChannelSounding = 0x2; + kBLEBeaconRSSI = 0x4 [spec_name = "BLE Beacon RSSI"]; + kUWBRanging = 0x8 [spec_name = "UWB Ranging"]; + } + + bitmap RadioBandBitmap : bitmap16 { + k2G4 = 0x1 [spec_name = "2G4"]; + k3G65 = 0x2 [spec_name = "3G65"]; + k5G = 0x4 [spec_name = "5G"]; + k6G = 0x8 [spec_name = "6G"]; + k60G = 0x10 [spec_name = "60G"]; + kS1G = 0x20 [spec_name = "S1G"]; + k45G = 0x40 [spec_name = "45G"]; + } + + bitmap RangingBandwidthBitmap : bitmap32 { + k1MHz = 0x1; + k2MHz = 0x2; + k4MHz = 0x4; + k8MHz = 0x8; + k16MHz = 0x10; + k20MHz = 0x20; + k40MHz = 0x40; + k80MHz = 0x80; + k160MHz = 0x100; + k320MHz = 0x200; + } + + struct RDRStruct { + int16u azimuth = 0; + int16s elevation = 1; + int8u azimuthAccuracy = 2; + int8u elevationAccuracy = 3; + RDRReferenceEnum reference = 4; + } + + struct RangingMeasurementDataStruct { + optional octet_string<16> wiFiDevIK = 0; + optional int64u BLEDeviceID = 1; + optional octet_string BLTDevIK = 2; + optional epoch_s timeOfMeasurement = 3; + optional elapsed_s timeOfMeasurementOffset = 4; + nullable int16u distance = 5; + optional int16u errorMargin = 6; + optional RDRStruct rdr = 7; + optional NADMEnum detectedAttackLevel = 8; + optional nullable int8s rssi = 9; + optional nullable int8s txPower = 10; + } + + struct BLERangingDeviceRoleConfigStruct { + RangingRoleEnum role = 0; + int64u peerBLEDeviceID = 1; + } + + struct BLTChannelSoundingDeviceRoleConfigStruct { + RangingRoleEnum role = 0; + octet_string<16> peerBLTDevIK = 1; + optional BLTCSModeEnum BLTCSMode = 2; + optional BLTCSSecurityLevelEnum BLTCSSecurityLevel = 3; + optional octet_string<16> ltk = 4; + } + + struct RangingCapabilitiesStruct { + RangingTechEnum technology = 0; + RadioBandBitmap frequencyBand = 1; + boolean periodicRangingSupport = 2; + } + + struct RangingTriggerConditionStruct { + elapsed_s startTime = 0; + elapsed_s endTime = 1; + optional elapsed_s rangingInstanceInterval = 2; + } + + struct ReportingConditionStruct { + optional int16u minDistanceCondition = 0; + optional int16u maxDistanceCondition = 1; + optional int16u errorMarginCondition = 2; + } + + struct WiFiRangingDeviceRoleConfigStruct { + RangingRoleEnum role = 0; + octet_string<16> peerWiFiDevIK = 1; + optional octet_string<32> pmk = 2; + } + + info event RangingResult = 0 { + int8u sessionID = 0; + RangingMeasurementDataStruct rangingResultData = 1; + } + + info event RangingSessionStatus = 1 { + int8u sessionID = 0; + RangingSessionStatusEnum status = 1; + } + + readonly attribute RangingCapabilitiesStruct rangingCapabilities[] = 0; + readonly attribute optional octet_string<16> wiFiDevIK = 1; + readonly attribute optional int64u BLEDeviceID = 2; + readonly attribute optional octet_string<16> BLTDevIK = 3; + readonly attribute optional BLTCSSecurityLevelEnum BLTCSSecurityLevel = 4; + readonly attribute optional BLTCSModeEnum BLTCSModeCapability = 5; + readonly attribute nullable int8u sessionIDList[] = 6; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct StartRangingRequestRequest { + RangingTechEnum technology = 0; + optional WiFiRangingDeviceRoleConfigStruct wiFiRangingDeviceRoleConfig = 1; + optional BLERangingDeviceRoleConfigStruct BLERangingDeviceRoleConfig = 2; + optional BLTChannelSoundingDeviceRoleConfigStruct BLTChannelSoundingDeviceRoleConfig = 3; + optional RadioBandBitmap frequencyBand = 4; + optional RangingBandwidthBitmap bandwidth = 5; + RangingSecurityEnum securityMode = 6; + RangingTriggerConditionStruct trigger = 7; + optional ReportingConditionStruct reportingCondition = 8; + } + + response struct StartRangingResponse = 1 { + ResultCodeEnum resultCode = 0; + nullable int8u sessionID = 1; + } + + request struct StopRangingRequestRequest { + int8u sessionID = 0; + } + + /** This command allows the Client to request the start of a ranging session. */ + command StartRangingRequest(StartRangingRequestRequest): StartRangingResponse = 0; + /** Upon receipt of a StopRangingRequest command that contains a SessionID that matches an active ranging session, the Server SHALL terminate the corresponding ranging session. */ + command StopRangingRequest(StopRangingRequestRequest): DefaultSuccess = 2; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 5; + device type ma_otarequestor = 18, version 1; + + binding cluster OtaSoftwareUpdateProvider; + + 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; + callback attribute acl; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + 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; + callback 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; + callback attribute localConfigDisabled; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + callback attribute configurationVersion; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + callback attribute updatePossible; + callback attribute updateState; + callback attribute updateStateProgress; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command AnnounceOTAProvider; + } + + server cluster GeneralCommissioning { + callback attribute breadcrumb; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command ArmFailSafe; + handle command SetRegulatoryConfig; + handle command CommissioningComplete; + } + + server cluster NetworkCommissioning { + callback attribute maxNetworks; + callback attribute networks; + callback attribute scanMaxTimeSeconds; + callback attribute connectMaxTimeSeconds; + callback attribute interfaceEnabled; + callback attribute lastNetworkingStatus; + callback attribute lastNetworkID; + callback attribute lastConnectErrorValue; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command ScanNetworks; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command ConnectNetwork; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + callback attribute featureMap; + callback attribute clusterRevision; + + handle command RetrieveLogsRequest; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute testEventTriggersEnabled default = false; + callback attribute deviceLoadStatus; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + } + + server cluster SoftwareDiagnostics { + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command ResetWatermarks; + } + + server cluster WiFiNetworkDiagnostics { + emits event Disconnection; + emits event AssociationFailure; + emits event ConnectionStatus; + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute beaconLostCount; + callback attribute beaconRxCount; + callback attribute packetMulticastRxCount; + callback attribute packetMulticastTxCount; + callback attribute packetUnicastRxCount; + callback attribute packetUnicastTxCount; + callback attribute currentMaxRate; + callback attribute overrunCount; + ram attribute featureMap default = 3; + callback attribute clusterRevision default = 1; + + handle command ResetCounts; + } + + server cluster EthernetNetworkDiagnostics { + callback attribute PHYRate; + callback attribute fullDuplex; + callback attribute packetRxCount; + callback attribute packetTxCount; + callback attribute txErrCount; + callback attribute collisionCount; + callback attribute overrunCount; + callback attribute carrierDetect; + callback attribute timeSinceReset; + ram attribute featureMap default = 3; + callback attribute clusterRevision; + + handle command ResetCounts; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + + 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; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command AttestationRequest; + handle command CertificateChainRequest; + handle command CSRRequest; + handle command AddNOC; + handle command UpdateNOC; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + handle command SetVIDVerificationStatement; + handle command SignVIDVerificationRequest; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute groupcastAdoption; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + } + + server cluster UserLabel { + callback attribute labelList; + callback attribute featureMap; + callback attribute clusterRevision; + } +} +endpoint 1 { + device type ma_proximityranger = 338, version 1; + + + server cluster Identify { + callback attribute identifyTime; + callback attribute identifyType; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command Identify; + } + + 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 ProximityRanging { + emits event RangingResult; + emits event RangingSessionStatus; + callback attribute rangingCapabilities; + callback attribute wiFiDevIK; + callback attribute BLEDeviceID; + callback attribute sessionIDList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap default = 5; + ram attribute clusterRevision default = 1; + + handle command StartRangingRequest; + handle command StopRangingRequest; + } +} + + diff --git a/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.zap b/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.zap new file mode 100644 index 00000000000000..9c9a2b6f830dad --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/proximity-ranger-app.zap @@ -0,0 +1,3399 @@ +{ + "fileFormat": 2, + "featureLevel": 107, + "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", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice", + "deviceTypeOrder": 0 + }, + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor", + "deviceTypeOrder": 1 + } + ], + "deviceVersions": [ + 5, + 1 + ], + "deviceIdentifiers": [ + 22, + 18 + ], + "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": "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": "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": "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 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": 0, + "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "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": 0, + "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": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConfigurationVersion", + "code": 24, + "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": "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": "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": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOTAProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "DefaultOTAProviders", + "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": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "UpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "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 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DownloadError", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": "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": "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "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": "InterfaceEnabled", + "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": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "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": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "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": "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": "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": "DeviceLoadStatus", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "DeviceLoadStruct", + "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 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetWatermarks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ThreadMetrics", + "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": "CurrentHeapFree", + "code": 1, + "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": "CurrentHeapUsed", + "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": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "Wi-Fi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BSSID", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "SecurityTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "WiFiVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "WiFiVersionEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelNumber", + "code": 3, + "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": "RSSI", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BeaconLostCount", + "code": 5, + "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": "BeaconRxCount", + "code": 6, + "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": "PacketMulticastRxCount", + "code": 7, + "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": "PacketMulticastTxCount", + "code": 8, + "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": "PacketUnicastRxCount", + "code": 9, + "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": "PacketUnicastTxCount", + "code": 10, + "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": "CurrentMaxRate", + "code": 11, + "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": "OverrunCount", + "code": 12, + "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": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "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": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "Disconnection", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AssociationFailure", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ConnectionStatus", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Ethernet Network Diagnostics", + "code": 55, + "mfgCode": null, + "define": "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "PHYRate", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PHYRateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FullDuplex", + "code": 1, + "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": "PacketRxCount", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PacketTxCount", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCount", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CollisionCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CarrierDetect", + "code": 7, + "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": "TimeSinceReset", + "code": 8, + "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": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "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": "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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 + }, + { + "name": "SetVIDVerificationStatement", + "code": 12, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SignVIDVerificationRequest", + "code": 13, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SignVIDVerificationResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "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": "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": "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": 1, + "maxInterval": 65534, + "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": 1, + "maxInterval": 65534, + "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": "GroupcastAdoption", + "code": 4, + "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": "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": "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 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 338, + "profileId": 259, + "label": "MA-proximityranger", + "name": "MA-proximityranger", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 338, + "profileId": 259, + "label": "MA-proximityranger", + "name": "MA-proximityranger", + "deviceTypeOrder": 0 + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 338 + ], + "deviceTypeName": "MA-proximityranger", + "deviceTypeCode": 338, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "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": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "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": "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": "Proximity Ranging", + "code": 1075, + "mfgCode": null, + "define": "PROXIMITY_RANGING_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "StartRangingRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartRangingResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StopRangingRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "RangingCapabilities", + "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": "WiFiDevIK", + "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": "BLEDeviceID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SessionIDList", + "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": "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": "5", + "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 + } + ], + "events": [ + { + "name": "RangingResult", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "RangingSessionStatus", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "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/examples/proximity-ranger-app/proximity-ranger-common/src/RangingTechnologyController.cpp b/examples/proximity-ranger-app/proximity-ranger-common/src/RangingTechnologyController.cpp new file mode 100644 index 00000000000000..4978c25c89bd45 --- /dev/null +++ b/examples/proximity-ranger-app/proximity-ranger-common/src/RangingTechnologyController.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2026 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 "RangingTechnologyController.h" + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +CHIP_ERROR RangingTechnologyController::RegisterAdapter(RangingAdapter & adapter) +{ + for (size_t i = 0; i < mAdapterCount; i++) + { + VerifyOrReturnError(mAdapters[i]->GetTechnology() != adapter.GetTechnology(), CHIP_ERROR_DUPLICATE_KEY_ID); + } + VerifyOrReturnError(mAdapterCount < kMaxControllerAdapters, CHIP_ERROR_NO_MEMORY); + + mAdapters[mAdapterCount++] = &adapter; + return CHIP_NO_ERROR; +} + +CHIP_ERROR RangingTechnologyController::GetRangingCapabilities(AttributeValueEncoder & encoder) +{ + return encoder.EncodeList([this](const auto & listEncoder) -> CHIP_ERROR { + for (size_t i = 0; i < mAdapterCount; i++) + { + ReturnErrorOnFailure(listEncoder.Encode(mAdapters[i]->GetCapabilities())); + } + return CHIP_NO_ERROR; + }); +} + +ResultCodeEnum RangingTechnologyController::StartSession(uint8_t sessionId, + const Commands::StartRangingRequest::DecodableType & request) +{ + RangingAdapter * adapter = FindAdapter(request.technology); + VerifyOrReturnValue(adapter != nullptr, ResultCodeEnum::kRejectedInfeasibleRanging); + + SessionEntry entry; + entry.sessionId = sessionId; + entry.adapter = adapter; + + ResultCodeEnum result = adapter->StartSession(sessionId, request, *this); + if (result == ResultCodeEnum::kAccepted) + { + mSessions.push_back(entry); + } + return result; +} + +CHIP_ERROR RangingTechnologyController::StopSession(uint8_t sessionId) +{ + for (auto it = mSessions.begin(); it != mSessions.end(); ++it) + { + if (it->sessionId == sessionId) + { + CHIP_ERROR err = it->adapter->StopSession(sessionId); + if (err == CHIP_NO_ERROR) + { + mSessions.erase(it); + } + return err; + } + } + return CHIP_ERROR_NOT_FOUND; +} + +void RangingTechnologyController::StopAllSessions() +{ + for (auto & entry : mSessions) + { + // Best-effort during shutdown + [[maybe_unused]] auto err = entry.adapter->StopSession(entry.sessionId); + } + mSessions.clear(); +} + +void RangingTechnologyController::OnRangingSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) +{ + for (auto it = mSessions.begin(); it != mSessions.end(); ++it) + { + if (it->sessionId == sessionId) + { + mSessions.erase(it); + break; + } + } + + VerifyOrReturn(mListener != nullptr); + mListener->OnSessionStopped(sessionId, status); +} + +void RangingTechnologyController::OnMeasurementData(uint8_t sessionId, + const Structs::RangingMeasurementDataStruct::Type & measurement) +{ + VerifyOrReturn(mListener != nullptr); + mListener->OnSessionMeasurement(sessionId, measurement); +} + +RangingAdapter * RangingTechnologyController::FindAdapter(RangingTechEnum technology) +{ + for (size_t i = 0; i < mAdapterCount; i++) + { + if (mAdapters[i]->GetTechnology() == technology) + { + return mAdapters[i]; + } + } + return nullptr; +} + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 85a1defd3559fe..a0572b87f0deba 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -136,6 +136,7 @@ def BuildHostTarget(): TargetPart('chip-cert', app=HostApp.CERT_TOOL), TargetPart('address-resolve-tool', app=HostApp.ADDRESS_RESOLVE), TargetPart('contact-sensor', app=HostApp.CONTACT_SENSOR), + TargetPart('proximity-ranger', app=HostApp.PROXIMITY_RANGER), TargetPart('dishwasher', app=HostApp.DISHWASHER), TargetPart('microwave-oven', app=HostApp.MICROWAVE_OVEN), TargetPart('refrigerator', app=HostApp.REFRIGERATOR), @@ -251,6 +252,7 @@ def BuildEsp32Target(): TargetPart('water-heater', app=Esp32App.WATER_HEATER), TargetPart('ota-provider', app=Esp32App.OTA_PROVIDER), TargetPart('ota-requestor', app=Esp32App.OTA_REQUESTOR), + TargetPart('proximity-ranger', app=Esp32App.PROXIMITY_RANGER), TargetPart('shell', app=Esp32App.SHELL), TargetPart('light', app=Esp32App.LIGHT), TargetPart('lock', app=Esp32App.LOCK), diff --git a/scripts/build/builders/esp32.py b/scripts/build/builders/esp32.py index 9231f2a7f587b4..ea75297ad010f4 100644 --- a/scripts/build/builders/esp32.py +++ b/scripts/build/builders/esp32.py @@ -46,6 +46,7 @@ class Esp32App(Enum): TESTS = auto() OTA_REQUESTOR = auto() OTA_PROVIDER = auto() + PROXIMITY_RANGER = auto() @property def ExamplePath(self): @@ -75,6 +76,8 @@ def ExamplePath(self): return 'examples/ota-requestor-app' if self == Esp32App.OTA_PROVIDER: return 'examples/ota-provider-app' + if self == Esp32App.PROXIMITY_RANGER: + return 'examples/proximity-ranger-app' if self == Esp32App.TESTS: return 'src/test_driver' raise Exception('Unknown app type: %r' % self) @@ -107,6 +110,8 @@ def AppNamePrefix(self): return 'chip-ota-requestor-app' if self == Esp32App.OTA_PROVIDER: return 'chip-ota-provider-app' + if self == Esp32App.PROXIMITY_RANGER: + return 'chip-proximity-ranger-app' if self == Esp32App.TESTS: return None raise Exception('Unknown app type: %r' % self) diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 8efb97c37dbf3c..f09054afb0d822 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -79,6 +79,7 @@ class HostApp(Enum): JAVA_MATTER_CONTROLLER = auto() KOTLIN_MATTER_CONTROLLER = auto() CONTACT_SENSOR = auto() + PROXIMITY_RANGER = auto() DISHWASHER = auto() MICROWAVE_OVEN = auto() REFRIGERATOR = auto() @@ -175,6 +176,8 @@ def ExamplePath(self): return 'kotlin-matter-controller' if self == HostApp.CONTACT_SENSOR: return 'contact-sensor-app/linux' + if self == HostApp.PROXIMITY_RANGER: + return 'proximity-ranger-app/linux' if self == HostApp.DISHWASHER: return 'dishwasher-app/linux' if self == HostApp.MICROWAVE_OVEN: @@ -304,6 +307,9 @@ def OutputNames(self): elif self == HostApp.CONTACT_SENSOR: yield 'contact-sensor-app' yield 'contact-sensor-app.map' + elif self == HostApp.PROXIMITY_RANGER: + yield 'proximity-ranger-app' + yield 'proximity-ranger-app.map' elif self == HostApp.DISHWASHER: yield 'dishwasher-app' yield 'dishwasher-app.map' diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 5e35298900c164..6f72420f6762d3 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -6,10 +6,10 @@ cc32xx-{air-purifier,lock} ti-cc13x4_26x4-{lighting,lock,pump,pump-controller}[-ftd][-mtd] cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw930739m2evb_01,cyw930739m2evb_02}-{light,light-switch,lock,thermostat} efr32-{brd2601b,brd2605a,brd2703a,brd2704b,brd2708a,brd2911a,brd4186a,brd4186c,brd4187a,brd4187c,brd4316a,brd4317a,brd4318a,brd4319a,brd4338a,brd4342a,brd4343a}-{air-quality-sensor-app,closure,evse,light,lock,pump,smoke-co-alarm,switch,thermostat,unit-test,water-heater,window-covering}[-additional-data-advertising][-heap-monitoring][-icd][-ipv4][-low-power][-no-logging][-no-openthread-cli][-no-version][-openthread-mtd][-rpc][-shell][-show-qr-code][-siwx917][-skip-rps-generation][-use-ot-coap-lib][-use-ot-lib][-wf200][-wifi][-with-ota-requestor] -esp32-{c3devkit,devkitc,m5stack,p4functionev,qemu}-{all-clusters,all-clusters-minimal,all-devices,bridge,energy-gateway,evse,light,lock,ota-provider,ota-requestor,ota-requestor,shell,temperature-measurement,tests,water-heater}[-ipv6only][-rpc][-tracing] +esp32-{c3devkit,devkitc,m5stack,p4functionev,qemu}-{all-clusters,all-clusters-minimal,all-devices,bridge,energy-gateway,evse,light,lock,ota-provider,ota-requestor,ota-requestor,proximity-ranger,shell,temperature-measurement,tests,water-heater}[-ipv6only][-rpc][-tracing] genio-lighting-app linux-fake-tests[-asan][-boringssl][-clang][-coverage][-dmalloc][-libfuzzer][-mbedtls][-ossfuzz][-pw-fuzztest][-tsan][-ubsan] -linux-{arm64,x64}-{address-resolve-tool,air-purifier,air-quality-sensor,all-clusters,all-clusters-minimal,all-devices,bridge,camera,camera-controller,chip-cert,chip-tool,closure,contact-sensor,dishwasher,energy-gateway,evse,fabric-admin,fabric-bridge,fabric-sync,java-matter-controller,jf-admin-app,jf-control-app,kotlin-matter-controller,light,light-data-model-no-unique-id,lit-icd,lock,microwave-oven,minmdns,network-manager,ota-provider,ota-requestor,python-bindings,refrigerator,rpc-console,rvc,shell,simulated-app1,simulated-app2,terms-and-conditions,tests,thermostat,tv-app,tv-casting-app,water-heater,water-leak-detector}[-asan][-boringssl][-chip-casting-simplified][-clang][-coverage][-disable-dnssd-tests][-dmalloc][-enable-dnssd-tests][-endpoint-unique-id][-evse-test-event][-googletest][-ipv6only][-libfuzzer][-libnl][-mbedtls][-minmdns-verbose][-nfc-commission][-nlfaultinject][-no-ble][-no-groupcast][-no-interactive][-no-shell][-no-thread][-no-wifi][-no-wifipaf][-nodeps][-openthread-endpoint][-ossfuzz][-platform-mdns][-pw-fuzztest][-rpc][-same-event-loop][-terms-and-conditions][-test][-tsan][-ubsan][-unified][-webrtc][-with-ui] +linux-{arm64,x64}-{address-resolve-tool,air-purifier,air-quality-sensor,all-clusters,all-clusters-minimal,all-devices,bridge,camera,camera-controller,chip-cert,chip-tool,closure,contact-sensor,dishwasher,energy-gateway,evse,fabric-admin,fabric-bridge,fabric-sync,java-matter-controller,jf-admin-app,jf-control-app,kotlin-matter-controller,light,light-data-model-no-unique-id,lit-icd,lock,microwave-oven,minmdns,network-manager,ota-provider,ota-requestor,proximity-ranger,python-bindings,refrigerator,rpc-console,rvc,shell,simulated-app1,simulated-app2,terms-and-conditions,tests,thermostat,tv-app,tv-casting-app,water-heater,water-leak-detector}[-asan][-boringssl][-chip-casting-simplified][-clang][-coverage][-disable-dnssd-tests][-dmalloc][-enable-dnssd-tests][-endpoint-unique-id][-evse-test-event][-googletest][-ipv6only][-libfuzzer][-libnl][-mbedtls][-minmdns-verbose][-nfc-commission][-nlfaultinject][-no-ble][-no-groupcast][-no-interactive][-no-shell][-no-thread][-no-wifi][-no-wifipaf][-nodeps][-openthread-endpoint][-ossfuzz][-platform-mdns][-pw-fuzztest][-rpc][-same-event-loop][-terms-and-conditions][-test][-tsan][-ubsan][-unified][-webrtc][-with-ui] linux-x64-efr32-test-runner[-clang] imx-{all-clusters-app,all-clusters-minimal-app,chip-tool,lighting-app,ota-provider-app,thermostat}[-ele][-release][-trusty] infineon-psoc6-{all-clusters,all-clusters-minimal,light,lock}[-ota][-trustm][-updateimage] diff --git a/src/app/clusters/proximity-ranging-server/BUILD.gn b/src/app/clusters/proximity-ranging-server/BUILD.gn new file mode 100644 index 00000000000000..fd54e172c7f47a --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright (c) 2026 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. +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +source_set("proximity-ranging-server") { + sources = [ + "ProximityRangingCluster.cpp", + "ProximityRangingCluster.h", + "ProximityRangingDriver.h", + ] + + public_deps = [ + "${chip_root}/src/app/data-model-provider", + "${chip_root}/src/app/server", + "${chip_root}/src/app/server-cluster", + "${chip_root}/zzz_generated/app-common/clusters/ProximityRanging", + ] +} diff --git a/src/app/clusters/proximity-ranging-server/CodegenIntegration.cpp b/src/app/clusters/proximity-ranging-server/CodegenIntegration.cpp new file mode 100644 index 00000000000000..a59be3f1849889 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/CodegenIntegration.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2026 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 + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +CHIP_ERROR Instance::Init() +{ + VerifyOrReturnError(!mRegistered, CHIP_ERROR_INCORRECT_STATE); + + CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Register(mCluster.Registration()); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "ProximityRanging: Failed to register cluster on endpoint %u: %" CHIP_ERROR_FORMAT, + mCluster.Cluster().GetPaths()[0].mEndpointId, err.Format()); + return err; + } + + mRegistered = true; + return CHIP_NO_ERROR; +} + +void Instance::Shutdown() +{ + VerifyOrReturn(mRegistered); + + CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Unregister(&mCluster.Cluster()); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "ProximityRanging: Failed to unregister cluster on endpoint %u: %" CHIP_ERROR_FORMAT, + mCluster.Cluster().GetPaths()[0].mEndpointId, err.Format()); + } + + mRegistered = false; +} + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip + +// The application manually creates and registers Instance objects, so these +// codegen callbacks are no-ops. +void MatterProximityRangingClusterInitCallback(chip::EndpointId) {} +void MatterProximityRangingClusterShutdownCallback(chip::EndpointId, MatterClusterShutdownType) {} + +// Legacy callback stubs +void MatterProximityRangingPluginServerInitCallback() {} +void MatterProximityRangingPluginServerShutdownCallback() {} diff --git a/src/app/clusters/proximity-ranging-server/CodegenIntegration.h b/src/app/clusters/proximity-ranging-server/CodegenIntegration.h new file mode 100644 index 00000000000000..ff91576a9acae6 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/CodegenIntegration.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * Application-facing Instance for the Proximity Ranging cluster. + * + * The application creates one Instance per endpoint, providing the driver + * and feature flags. Call Init() to register with the data model provider + * and Shutdown() (or destroy) to unregister. + * + * @code + * static MyProximityRangingDriver sDriver; + * static ProximityRanging::Instance sInstance(endpointId, sDriver, features); + * + * // During application init: + * sInstance.Init(); + * + * // During application shutdown: + * sInstance.Shutdown(); + * @endcode + */ +class Instance +{ +public: + Instance(EndpointId aEndpointId, ProximityRangingDriver & aDriver, BitMask aFeatures = {}) : + mCluster(ProximityRangingCluster::Config(aEndpointId, aDriver, aFeatures)) + {} + + ~Instance() { Shutdown(); } + + /** + * Register the cluster with the data model provider. + */ + CHIP_ERROR Init(); + + /** + * Unregister the cluster from the data model provider. + */ + void Shutdown(); + + /** + * Access the underlying cluster instance. + */ + ProximityRangingCluster & GetCluster() { return mCluster.Cluster(); } + const ProximityRangingCluster & GetCluster() const { return mCluster.Cluster(); } + +private: + RegisteredServerCluster mCluster; + bool mRegistered = false; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.cpp b/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.cpp new file mode 100644 index 00000000000000..c89a461bc9b5bf --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2026 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 + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +namespace { +// Maximum number of active sessions supported by ProximityRanging cluster +static constexpr size_t kMaxActiveSessions = 50; +static constexpr uint8_t kInvalidSessionId = 0; +} // namespace + +CHIP_ERROR ProximityRangingCluster::Startup(ServerClusterContext & context) +{ + ReturnErrorOnFailure(DefaultServerCluster::Startup(context)); + CHIP_ERROR err = mDriver.Init(*this); + if (err != CHIP_NO_ERROR) + { + DefaultServerCluster::Shutdown(ClusterShutdownType::kClusterShutdown); + } + return err; +} + +void ProximityRangingCluster::Shutdown(ClusterShutdownType shutdownType) +{ + DefaultServerCluster::Shutdown(shutdownType); + mDriver.Shutdown(); +} + +DataModel::ActionReturnStatus ProximityRangingCluster::ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) +{ + switch (request.path.mAttributeId) + { + case Attributes::RangingCapabilities::Id: + return mDriver.GetRangingCapabilities(encoder); + + case Attributes::WiFiDevIK::Id: { + VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiUsdProximityDetection), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + uint8_t buf[kDeviceIdentityKeyLen] = { 0 }; + MutableByteSpan span(buf); + CHIP_ERROR err = mDriver.GetWiFiDevIK(span); + VerifyOrReturnError(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + return encoder.Encode(span); + } + + case Attributes::BLEDeviceID::Id: { + VerifyOrReturnError(mFeatureFlags.Has(Feature::kBleBeaconRssi), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + uint64_t bleDeviceId = 0; + CHIP_ERROR err = mDriver.GetBleDeviceId(bleDeviceId); + VerifyOrReturnError(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + return encoder.Encode(bleDeviceId); + } + + case Attributes::BLTDevIK::Id: { + VerifyOrReturnError(mFeatureFlags.Has(Feature::kBluetoothChannelSounding), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + uint8_t buf[kDeviceIdentityKeyLen] = { 0 }; + MutableByteSpan span(buf); + CHIP_ERROR err = mDriver.GetBLTDevIK(span); + VerifyOrReturnError(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + return encoder.Encode(span); + } + + case Attributes::BLTCSSecurityLevel::Id: { + VerifyOrReturnError(mFeatureFlags.Has(Feature::kBluetoothChannelSounding), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + BLTCSSecurityLevelEnum securityLevel; + CHIP_ERROR err = mDriver.GetBLTCSSecurityLevel(securityLevel); + VerifyOrReturnError(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + return encoder.Encode(securityLevel); + } + + case Attributes::BLTCSModeCapability::Id: { + VerifyOrReturnError(mFeatureFlags.Has(Feature::kBluetoothChannelSounding), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + BLTCSModeEnum modeCapability = BLTCSModeEnum::kUnknownEnumValue; + CHIP_ERROR err = mDriver.GetBLTCSModeCapability(modeCapability); + VerifyOrReturnError(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + return encoder.Encode(modeCapability); + } + + case Attributes::SessionIDList::Id: { + uint8_t buf[kMaxActiveSessions] = { 0 }; + Span sessionIds(buf, kMaxActiveSessions); + CHIP_ERROR err = mDriver.GetActiveSessionIds(sessionIds); + VerifyOrReturnError(err == CHIP_NO_ERROR, Protocols::InteractionModel::Status::Failure); + if (sessionIds.empty()) + { + return encoder.EncodeNull(); + } + return encoder.EncodeList([&sessionIds](const auto & listEncoder) -> CHIP_ERROR { + for (size_t i = 0; i < sessionIds.size(); i++) + { + ReturnErrorOnFailure(listEncoder.Encode(sessionIds.data()[i])); + } + return CHIP_NO_ERROR; + }); + } + + case Attributes::FeatureMap::Id: + return encoder.Encode(mFeatureFlags.Raw()); + + case Attributes::ClusterRevision::Id: + return encoder.Encode(ProximityRanging::kRevision); + + default: + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } +} + +CHIP_ERROR ProximityRangingCluster::Attributes(const ConcreteClusterPath & path, + ReadOnlyBufferBuilder & builder) +{ + static constexpr DataModel::AttributeEntry kOptionalAttributesMeta[] = { + ProximityRanging::Attributes::WiFiDevIK::kMetadataEntry, + ProximityRanging::Attributes::BLEDeviceID::kMetadataEntry, + ProximityRanging::Attributes::BLTDevIK::kMetadataEntry, + ProximityRanging::Attributes::BLTCSSecurityLevel::kMetadataEntry, + ProximityRanging::Attributes::BLTCSModeCapability::kMetadataEntry, + }; + + AttributeListBuilder listBuilder(builder); + return listBuilder.Append(Span(ProximityRanging::Attributes::kMandatoryMetadata), + Span(kOptionalAttributesMeta), mOptionalAttributes); +} + +CHIP_ERROR ProximityRangingCluster::AcceptedCommands(const ConcreteClusterPath & path, + ReadOnlyBufferBuilder & builder) +{ + static constexpr DataModel::AcceptedCommandEntry kCommands[] = { + Commands::StartRangingRequest::kMetadataEntry, + Commands::StopRangingRequest::kMetadataEntry, + }; + return builder.ReferenceExisting(kCommands); +} + +CHIP_ERROR ProximityRangingCluster::GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder & builder) +{ + static constexpr CommandId kGenerated[] = { Commands::StartRangingResponse::Id }; + return builder.ReferenceExisting(kGenerated); +} + +std::optional ProximityRangingCluster::InvokeCommand(const DataModel::InvokeRequest & request, + TLV::TLVReader & input_arguments, + CommandHandler * handler) +{ + switch (request.path.mCommandId) + { + case Commands::StartRangingRequest::Id: + return HandleStartRangingRequest(request, input_arguments, handler); + case Commands::StopRangingRequest::Id: + return HandleStopRangingRequest(request, input_arguments, handler); + default: + return CHIP_IM_GLOBAL_STATUS(UnsupportedCommand); + } +} + +std::optional +ProximityRangingCluster::HandleStartRangingRequest(const DataModel::InvokeRequest & request, TLV::TLVReader & reader, + CommandHandler * handler) +{ + Commands::StartRangingRequest::DecodableType commandData; + VerifyOrReturnValue(commandData.Decode(reader) == CHIP_NO_ERROR, CHIP_IM_GLOBAL_STATUS(InvalidCommand)); + + Commands::StartRangingResponse::Type response; + ResultCodeEnum resultCode; + uint8_t sessionId = GenerateSessionId(); + if (sessionId == kInvalidSessionId) + { + // Failed to generate session ID without collision + resultCode = ResultCodeEnum::kBusySessionCapacityReached; + } + else + { + resultCode = mDriver.HandleStartRanging(sessionId, commandData); + response.resultCode = resultCode; + } + + response.resultCode = resultCode; + + if (resultCode == ResultCodeEnum::kAccepted) + { + response.sessionID.SetNonNull(sessionId); + MarkSessionIdListModified(); + } + else + { + response.sessionID.SetNull(); + } + + handler->AddResponse(request.path, response); + return std::nullopt; +} + +std::optional +ProximityRangingCluster::HandleStopRangingRequest(const DataModel::InvokeRequest & request, TLV::TLVReader & reader, + CommandHandler * handler) +{ + Commands::StopRangingRequest::DecodableType commandData; + VerifyOrReturnValue(commandData.Decode(reader) == CHIP_NO_ERROR, Protocols::InteractionModel::Status::InvalidCommand); + + CHIP_ERROR err = mDriver.HandleStopRanging(commandData.sessionID); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_IM_GLOBAL_STATUS(NotFound); + } + if (err != CHIP_NO_ERROR) + { + return CHIP_IM_GLOBAL_STATUS(Failure); + } + + MarkSessionIdListModified(); + return Protocols::InteractionModel::Status::Success; +} + +void ProximityRangingCluster::OnMeasurementData(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) +{ + VerifyOrReturn(mContext != nullptr); + + Events::RangingResult::Type event; + event.sessionID = sessionId; + event.rangingResultData = measurement; + mContext->interactionContext.eventsGenerator.GenerateEvent(event, mPath.mEndpointId); +} + +void ProximityRangingCluster::OnSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) +{ + MarkSessionIdListModified(); + + if (mContext != nullptr) + { + Events::RangingSessionStatus::Type event; + event.sessionID = sessionId; + event.status = status; + mContext->interactionContext.eventsGenerator.GenerateEvent(event, mPath.mEndpointId); + } +} + +uint8_t ProximityRangingCluster::GenerateSessionId() +{ + uint8_t buf[kMaxActiveSessions]; + Span activeSessions(buf); + if (mDriver.GetActiveSessionIds(activeSessions) != CHIP_NO_ERROR) + { + return kInvalidSessionId; + } + + for (uint8_t attempt = 0; attempt <= kMaxActiveSessions; attempt++) + { + uint8_t candidate = mNextSessionId++; + // Specification defines SessionID as non-zero (1-255) + if (candidate == kInvalidSessionId) + { + candidate = mNextSessionId++; + } + bool collision = false; + for (size_t i = 0; i < activeSessions.size(); i++) + { + if (activeSessions.data()[i] == candidate) + { + collision = true; + break; + } + } + if (!collision) + { + return candidate; + } + } + return kInvalidSessionId; +} + +void ProximityRangingCluster::MarkSessionIdListModified() +{ + NotifyAttributeChanged(Attributes::SessionIDList::Id); +} + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.h b/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.h new file mode 100644 index 00000000000000..73009a2dbfc0f6 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/ProximityRangingCluster.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * Proximity Ranging Cluster server implementation. + * + * Combined DefaultServerCluster implementation. Delegates technology-specific + * operations to a ProximityRangingDriver provided at construction. + * All methods must be called from the Matter main thread. + */ +class ProximityRangingCluster : public DefaultServerCluster, public ProximityRangingDriver::Callback +{ +public: + /// Maximum Device Identity Key length for Wi-Fi USD and BTCS + static constexpr size_t kDeviceIdentityKeyLen = 16; + + using OptionalAttributes = + OptionalAttributeSet; + + struct Config + { + EndpointId endpointId; + ProximityRangingDriver & driver; + BitMask featureFlags; + + Config(EndpointId aEndpointId, ProximityRangingDriver & aDriver, BitMask aFeatures = {}) : + endpointId(aEndpointId), driver(aDriver), featureFlags(aFeatures) + {} + }; + + ProximityRangingCluster() = delete; + + ProximityRangingCluster(const Config & config) : + DefaultServerCluster({ config.endpointId, ProximityRanging::Id }), mDriver(config.driver), + mFeatureFlags(config.featureFlags), mOptionalAttributes([&config]() -> OptionalAttributes { + AttributeSet attrs; + if (config.featureFlags.Has(Feature::kWiFiUsdProximityDetection)) + attrs.ForceSet(); + if (config.featureFlags.Has(Feature::kBleBeaconRssi)) + attrs.ForceSet(); + if (config.featureFlags.Has(Feature::kBluetoothChannelSounding)) + { + attrs.ForceSet(); + attrs.ForceSet(); + attrs.ForceSet(); + } + return OptionalAttributes(attrs); + }()) + {} + + ProximityRangingDriver & GetDriver() const { return mDriver; } + const BitMask & GetFeatures() const { return mFeatureFlags; } + + // DefaultServerCluster implementation + CHIP_ERROR Startup(ServerClusterContext & context) override; + void Shutdown(ClusterShutdownType shutdownType) override; + + DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) override; + std::optional InvokeCommand(const DataModel::InvokeRequest & request, + TLV::TLVReader & input_arguments, CommandHandler * handler) override; + + CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder & builder) override; + CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path, + ReadOnlyBufferBuilder & builder) override; + CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder & builder) override; + + // ProximityRangingDriver::Callback implementation + void OnMeasurementData(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) override; + void OnSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) override; + +private: + // Command handlers + std::optional HandleStartRangingRequest(const DataModel::InvokeRequest & request, + TLV::TLVReader & reader, CommandHandler * handler); + std::optional HandleStopRangingRequest(const DataModel::InvokeRequest & request, + TLV::TLVReader & reader, CommandHandler * handler); + + void MarkSessionIdListModified(); + + // Session ID generation + uint8_t GenerateSessionId(); + + // Members + ProximityRangingDriver & mDriver; + BitMask mFeatureFlags; + const OptionalAttributes mOptionalAttributes; + + uint8_t mNextSessionId = 0; +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/proximity-ranging-server/ProximityRangingDriver.h b/src/app/clusters/proximity-ranging-server/ProximityRangingDriver.h new file mode 100644 index 00000000000000..3cc33cf379d68e --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/ProximityRangingDriver.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2026 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. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ProximityRanging { + +/** + * Driver interface for the Proximity Ranging cluster. + * + * The cluster dispatches decoded commands to the driver synchronously. + * Async events (measurements, unsolicited session stops) are delivered + * back to the cluster through the Callback interface. + * + * The driver is owned by the application and must outlive the cluster. + * All methods are called from the Matter main thread. + */ +class ProximityRangingDriver +{ +public: + /** + * Callback for async events from the driver back to the cluster. + * The cluster implements this and registers itself during Startup(). + */ + class Callback + { + public: + virtual ~Callback() = default; + + virtual void OnMeasurementData(uint8_t sessionId, const Structs::RangingMeasurementDataStruct::Type & measurement) = 0; + virtual void OnSessionStopped(uint8_t sessionId, RangingSessionStatusEnum status) = 0; + }; + + virtual ~ProximityRangingDriver() = default; + + /** + * Called during cluster Startup(). The callback pointer remains valid + * until Shutdown() is called. + */ + virtual CHIP_ERROR Init(Callback & callback) = 0; + + /** + * Called when the cluster is shutting down. The driver should stop all + * active ranging sessions and release resources. The application may safely destroy the + * driver object after this method returns. + */ + virtual void Shutdown() = 0; + + /** + * Start a ranging session synchronously. + * + * @return ResultCodeEnum indicating whether the session was accepted. + */ + virtual ResultCodeEnum HandleStartRanging(uint8_t sessionId, const Commands::StartRangingRequest::DecodableType & request) = 0; + + /** + * Stop an active ranging session synchronously. + */ + virtual CHIP_ERROR HandleStopRanging(uint8_t sessionId) = 0; + + /** + * Get the ranging capabilities supported by this driver. + */ + virtual CHIP_ERROR GetRangingCapabilities(AttributeValueEncoder & encoder) = 0; + + /** + * Collect active session IDs across all ranging technologies. + */ + virtual CHIP_ERROR GetActiveSessionIds(Span & sessionIds) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } + + /** + * Get the BLE Device ID. Override if the BLERBC feature is supported. + */ + virtual CHIP_ERROR GetBleDeviceId(uint64_t & bleDeviceId) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } + + /** + * Get the WiFi Device Identity Key (16 bytes). Override if WFUSDPD is supported. + */ + virtual CHIP_ERROR GetWiFiDevIK(MutableByteSpan & wifiDevIK) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } + + /** + * Get the BLT Device Identity Key (16 bytes). Override if BLTCS is supported. + */ + virtual CHIP_ERROR GetBLTDevIK(MutableByteSpan & bltDevIK) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } + + /** + * Get the BLTCS Security Level. Override if BLTCS is supported. + */ + virtual CHIP_ERROR GetBLTCSSecurityLevel(BLTCSSecurityLevelEnum & securityLevel) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } + + /** + * Get the BLTCS Mode Capability. Override if BLTCS is supported. + */ + virtual CHIP_ERROR GetBLTCSModeCapability(BLTCSModeEnum & modeCapability) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } +}; + +} // namespace ProximityRanging +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/proximity-ranging-server/README.md b/src/app/clusters/proximity-ranging-server/README.md new file mode 100644 index 00000000000000..84e28ce57a06b4 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/README.md @@ -0,0 +1,193 @@ +# Proximity Ranging Cluster + +The Proximity Ranging cluster enables the configuration of proximity ranging +sessions and reporting of proximity ranging data between Matter devices using +various technologies (BLE Beacon RSSI, Bluetooth Channel Sounding, Wi-Fi USD, +UWB). + +## Overview + +This directory contains a code-driven C++ implementation of the Matter Proximity +Ranging cluster server (cluster ID `0x0433`). The implementation follows the +combined `DefaultServerCluster` pattern and delegates all technology-specific +operations to a `ProximityRangingDriver` provided by the application. + +The cluster handles: + +- Matter protocol interactions (attribute reads, command dispatch) +- Session ID allocation and tracking +- Event emission for ranging results and session status changes + +The application is responsible for: + +- Implementing the `ProximityRangingDriver` interface +- Owning and persisting device identity attributes +- Performing actual ranging operations via technology adapters + +## Features + +The cluster supports the following optional features: + +- **Wi-Fi USD Proximity Detection (WFUSDPD)**: Ranging based on Wi-Fi USD. +- **Bluetooth Channel Sounding (BLTCS)**: Ranging based on Bluetooth Channel + Sounding. +- **BLE Beacon RSSI (BLERBC)**: Ranging based on BLE Beacon RSSI. Enables the + `BLEDeviceId` attribute. + +At least one feature must be enabled. + +## Usage + +### 1. Implement the Driver + +Create a class that inherits from +`chip::app::Clusters::ProximityRanging::ProximityRangingDriver` and implement +its virtual methods. The driver handles all technology-specific logic and owns +device identity attributes. + +The driver also receives a `Callback` reference during `Init()` for delivering +async events (measurement data and unsolicited session stops) back to the +cluster. + +### 2. Configure Cluster Conformance + +Set the feature flags based on which ranging technologies your device supports. + +```cpp +using chip::app::Clusters::ProximityRanging::Feature; + +chip::BitMask features(Feature::kBleBeaconRssi); +// Add more: features.Set(Feature::kBluetoothChannelSounding); +``` + +### 3. Instantiate and Register the Cluster + +The application creates and owns all required objects. Use the `Instance` class +from `CodegenIntegration.h` which wraps `RegisteredServerCluster` and handles +registration with the data model provider. + +```cpp +#include + +// Global objects - must outlive the Matter stack +static DefaultProximityRangingDriver sDriver; +static chip::app::Clusters::ProximityRanging::Instance sInstance( + kEndpointId, sDriver, features); +``` + +### 4. Initialize During Application Startup + +Register the cluster **before** the Matter server starts. This ensures the +cluster is available when the data model is queried during commissioning. + +```cpp +void ApplicationInit() +{ + // 1. Application-specific init (load persisted state, init adapters, etc.) + + // 2. Register the Proximity Ranging cluster + CHIP_ERROR err = sInstance.Init(); + VerifyOrDie(err == CHIP_NO_ERROR); + + // 3. Start the Matter server (happens later in the startup sequence) + // chip::Server::GetInstance().Init(...) +} +``` + +### 5. Shutdown + +The `Instance` automatically removes the cluster on deletion. For explicit +shutdown: + +```cpp +void ApplicationShutdown() +{ + sInstance.Shutdown(); +} +``` + +## Initialization Sequence + +``` +ApplicationInit() + │ + ├─ Initialize platform (BLE stack, Wi-Fi, etc.) + ├─ Load persisted driver state (BLEDeviceId, etc.) + ├─ Create driver and Instance (static globals) + ├─ sInstance.Init() ← Registers with CodegenDataModelProvider + │ + ├─ chip::Server::GetInstance().Init(...) ← Matter stack starts + │ └─ Cluster::Startup() called ← Driver::Init(callback) called here + │ + └─ Application ready +``` + +Key points: + +- `Instance::Init()` registers the cluster with the data model provider. This + can happen before the Matter server starts. +- `Cluster::Startup()` is called by the framework when the endpoint is + activated. This is when `Driver::Init()` is called, passing the cluster as + the `Callback` for async events. +- The driver must be able to respond to `GetBleDeviceId()` and other attribute + queries as soon as `Init()` returns. + +## Command Flow + +`StartRangingRequest` and `StopRangingRequest` are handled synchronously. The +driver returns the result immediately and the cluster responds to the client in +the same call: + +``` +Client Cluster Driver + │ │ │ + ├─ StartRangingRequest ──►│ │ + │ ├─ HandleStartRanging() ───►│ + │ │◄── ResultCodeEnum ────────┤ + │◄─ StartRangingResponse ─┤ │ + │ │ │ +``` + +Measurement data and unsolicited session stops (e.g., remote disconnect) are +delivered asynchronously from the driver to the cluster via the +`ProximityRangingDriver::Callback` interface. + +## Sharing a Driver Across Endpoints + +A single driver instance can be shared across multiple endpoints. This is useful +when the same BLE Device ID should be reported on all endpoints: + +```cpp +static DefaultProximityRangingDriver sSharedDriver; + +static chip::app::Clusters::ProximityRanging::Instance sInstance1( + endpoint1, sSharedDriver, features); +static chip::app::Clusters::ProximityRanging::Instance sInstance2( + endpoint2, sSharedDriver, features); +``` + +Each endpoint gets its own cluster instance with independent session tracking, +but they share the same driver and device identities. + +## Driver Methods + +| Method | Description | +| -------------------------- | --------------------------------------------------------------------------------- | +| `Init(callback)` | Initialize driver, store callback for async events | +| `Shutdown()` | Stop all sessions, release resources. Driver may be destroyed after this returns. | +| `HandleStartRanging()` | Start a ranging session (synchronous) | +| `HandleStopRanging()` | Stop a ranging session (synchronous) | +| `GetRangingCapabilities()` | Encode the list of supported capabilities | +| `GetBleDeviceId()` | Return persisted BLE Device ID | +| `GetWiFiDevIK()` | Return Wi-Fi Device Identity Key (16 bytes) | +| `GetBLTDevIK()` | Return BLT Device Identity Key (16 bytes) | + +## Events + +The cluster emits the following events: + +- **RangingResult**: Emitted when measurement data is available. Delivered via + `Callback::OnMeasurementData()`. +- **RangingSessionStatus**: Emitted when a session ends. Triggered by + `StopRangingRequest` or delivered asynchronously via + `Callback::OnSessionStopped()` for unsolicited stops. diff --git a/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.cmake b/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.cmake new file mode 100644 index 00000000000000..7027334254aa67 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.cmake @@ -0,0 +1,30 @@ +# Copyright (c) 2026 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. + +# This is the equivalent to app_config_dependent_sources.gni +TARGET_SOURCES( + ${APP_TARGET} + PRIVATE + "${CLUSTER_DIR}/CodegenIntegration.cpp" + "${CLUSTER_DIR}/CodegenIntegration.h" +) + +# These are the things that BUILD.gn dependencies would pull +TARGET_SOURCES( + ${APP_TARGET} + PRIVATE + "${CLUSTER_DIR}/ProximityRangingCluster.cpp" + "${CLUSTER_DIR}/ProximityRangingCluster.h" + "${CLUSTER_DIR}/ProximityRangingDriver.h" +) diff --git a/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.gni b/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.gni new file mode 100644 index 00000000000000..7ddc0b7a10bf42 --- /dev/null +++ b/src/app/clusters/proximity-ranging-server/app_config_dependent_sources.gni @@ -0,0 +1,17 @@ +# Copyright (c) 2026 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. +app_config_dependent_sources = [ + "CodegenIntegration.cpp", + "CodegenIntegration.h", +] diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 93597240502797..87d302ad881ee6 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -37,6 +37,7 @@ CommandHandlerInterfaceOnlyClusters: - Operational State - Oven Cavity Operational State - Oven Mode + - Proximity Ranging - RVC Clean Mode - RVC Operational State - RVC Run Mode @@ -147,6 +148,7 @@ CodeDrivenClusters: - Occupancy Sensing - Operational Credentials - Power Topology + - Proximity Ranging - Push AV Stream Transport - Relative Humidity Measurement - Scenes Management diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 34914c0f58de1c..034cc12304350c 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -274,7 +274,7 @@ "NITROGEN_DIOXIDE_CONCENTRATION_MEASUREMENT_CLUSTER": [ "concentration-measurement-server" ], - "PROXIMITY_RANGING_CLUSTER": [], + "PROXIMITY_RANGING_CLUSTER": ["proximity-ranging-server"], "PUSH_AV_STREAM_TRANSPORT_CLUSTER": ["push-av-stream-transport-server"], "SAMPLE_MEI_CLUSTER": ["sample-mei-server"], "OCCUPANCY_SENSING_CLUSTER": ["occupancy-sensor-server"], 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 2433ffa1afa0da..6a63c6755d7752 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 @@ -26791,31 +26791,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::MutableByteSp return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ProximityRanging::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - } // namespace WiFiDevIK namespace BLEDeviceID { @@ -26836,33 +26811,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, uint64_t * value) return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint64_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(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT64U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint64_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::ProximityRanging::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE); -} - } // namespace BLEDeviceID namespace BLTDevIK { @@ -26885,31 +26833,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::MutableByteSp return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ProximityRanging::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - } // namespace BLTDevIK namespace BLTCSSecurityLevel { @@ -26930,34 +26853,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::app::Clusters return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSSecurityLevelEnum 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(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(writable, ZCL_ENUM8_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSSecurityLevelEnum 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::ProximityRanging::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); -} - } // namespace BLTCSSecurityLevel namespace BLTCSModeCapability { @@ -26978,34 +26873,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::app::Clusters return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSModeEnum 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(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(writable, ZCL_ENUM8_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSModeEnum 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::ProximityRanging::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); -} - } // namespace BLTCSModeCapability namespace FeatureMap { @@ -27026,33 +26893,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_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(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(writable, ZCL_BITMAP32_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_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::ProximityRanging::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); -} - } // namespace FeatureMap namespace ClusterRevision { @@ -27073,33 +26913,6 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) return status; } -Protocols::InteractionModel::Status Set(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(ConcreteAttributePath(endpoint, Clusters::ProximityRanging::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(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::ProximityRanging::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - } // namespace ClusterRevision } // 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 a4e4cb5f2dbdd6..2a8cc6ea736eef 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 @@ -4291,48 +4291,32 @@ namespace Attributes { namespace WiFiDevIK { Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::MutableByteSpan & value); // octet_string -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty); } // namespace WiFiDevIK namespace BLEDeviceID { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint64_t * value); // int64u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint64_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty); } // namespace BLEDeviceID namespace BLTDevIK { Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::MutableByteSpan & value); // octet_string -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty); } // namespace BLTDevIK namespace BLTCSSecurityLevel { Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSSecurityLevelEnum * value); // BLTCSSecurityLevelEnum -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSSecurityLevelEnum value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSSecurityLevelEnum value, - MarkAttributeDirty markDirty); } // namespace BLTCSSecurityLevel namespace BLTCSModeCapability { Protocols::InteractionModel::Status Get(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSModeEnum * value); // BLTCSModeEnum -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSModeEnum value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters::ProximityRanging::BLTCSModeEnum value, - MarkAttributeDirty markDirty); } // namespace BLTCSModeCapability namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // bitmap32 -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); } // namespace FeatureMap namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); } // namespace ClusterRevision } // 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 54a62526e5cca6..69bdb6d2fb1633 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -7642,18 +7642,6 @@ bool emberAfColorControlClusterMoveColorTemperatureCallback( bool emberAfColorControlClusterStepColorTemperatureCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ColorControl::Commands::StepColorTemperature::DecodableType & commandData); -/** - * @brief Proximity Ranging Cluster StartRangingRequest Command callback (from client) - */ -bool emberAfProximityRangingClusterStartRangingRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ProximityRanging::Commands::StartRangingRequest::DecodableType & commandData); -/** - * @brief Proximity Ranging Cluster StopRangingRequest Command callback (from client) - */ -bool emberAfProximityRangingClusterStopRangingRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ProximityRanging::Commands::StopRangingRequest::DecodableType & commandData); /** * @brief Channel Cluster ChangeChannel Command callback (from client) */