From b1f09f7c551e9ec9826cdc6964731769e6dfbb0e Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:46:00 +0200 Subject: [PATCH 01/18] [NXP] Update ot-nxp submodule Signed-off-by: Martin Girardot --- third_party/openthread/ot-nxp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index 0a3248f5c8ec5a..0a480829128901 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit 0a3248f5c8ec5a9fd05541974872323f26d5182f +Subproject commit 0a4808291289019d0930a6a63afd87c2983353f5 From c566b8a176a6b6652649bfecda9a713d8a42114f Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:46:51 +0200 Subject: [PATCH 02/18] [NXP][third_party] Enable lwip and ephemeral key CLI addons Signed-off-by: Martin Girardot --- third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index 6d4854f53a9160..efa2cd16575f26 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -34,6 +34,9 @@ config("openthread_rw61x_config") { "${openthread_nxp_root}/third_party/mbedtls/configs", "${openthread_root}/third_party/mbedtls", "${openthread_root}/examples/platforms", + "${openthread_nxp_root}/examples/utils/cli_addons", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip", ] if (spinel_interface_rpmsg) { include_dirs += [ "${openthread_nxp_root}/src/common/spinel" ] @@ -55,7 +58,10 @@ config("openthread_rw61x_config") { "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", "OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF=0", "OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", "OT_APP_BR_LWIP_HOOKS_EN=1", + "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", + "OT_APP_CLI_LWIP_ADDON=1" ] } @@ -88,6 +94,9 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/common/br/mdns_socket.c", "${openthread_nxp_root}/src/common/br/udp_plat.c", "${openthread_nxp_root}/src/common/br/utils.c", + "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", ] deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] } From 579a7e62a4c0cd2ac010f685db35e753832a2091 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:48:16 +0200 Subject: [PATCH 03/18] [NXP][examples] Add support for TBR management cluster and secondary nwk, Updated common app to work with SNI and TBRM Signed-off-by: Martin Girardot --- .../all-clusters-app/nxp/rt/rw61x/README.md | 26 +- .../nxp/common/app_task/include/AppTaskBase.h | 11 + .../common/app_task/source/AppTaskBase.cpp | 49 +- .../include/CommonDeviceCallbacks.h | 2 +- .../source/CommonDeviceCallbacks.cpp | 23 +- examples/thermostat/nxp/rt/rw61x/BUILD.gn | 7 +- examples/thermostat/nxp/zap/BUILD.gn | 5 +- .../nxp/zap/thermostat_matter_br.matter | 2783 ++++++++ .../nxp/zap/thermostat_matter_br.zap | 5592 +++++++++++++++++ 9 files changed, 8480 insertions(+), 18 deletions(-) create mode 100644 examples/thermostat/nxp/zap/thermostat_matter_br.matter create mode 100644 examples/thermostat/nxp/zap/thermostat_matter_br.zap diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index 9356e4b8fe3617..543e1c7cc37622 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -16,6 +16,7 @@ commissioning and different cluster control. - [Testing the example](#testing-the-example) - [Matter Shell](#testing-the-all-clusters-application-with-matter-cli-enabled) - [OTA Software Update](#ota-software-update) +- [Thread Border Router overwiew](#thread-border-router-overwiew)
@@ -124,8 +125,10 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x #### Building with Matter over Wifi + OpenThread Border Router configuration on RW612 -This configuration requires enabling the Matter CLI in order to control the -Thread network on the Border Router. +This configuration supports the Thread Border Router management cluster to provision the Thread credentials. Enabling the Matter CLI in order to control the +Thread network on the Border Router is optional but recommended for other features like the Thread credential sharing. + +Note that the Thread Border Router management cluster is only supported on the thermostat application for now. - Build Matter with Border Router configuration with BLE commissioning (ble-wifi) : @@ -142,6 +145,9 @@ out/debug/chip-rw61x-all-cluster-example. Optional GN options that can be added when building an application: +- To enable the + [secondary network commissioning interface](../../../../../docs/guides/nxp/nxp_otbr_guide.md#using-the-secondary-network-commissioning-interface), + the arguments `chip_enable_secondary_nwk_if=true` and `chip_device_config_thread_network_endpoint_id=2` must be added to the _gn gen_ command. Note that this is only supported when building the Matter over Wifi + OpenThread Border Router configuration. Note that is only supported on the on the thermostat application for now. - To enable the [matter CLI](README.md#testing-the-all-clusters-application-with-matter-cli-enabled), the argument `chip_enable_matter_cli=true` must be added to the _gn gen_ @@ -265,11 +271,12 @@ The "ble-thread" pairing method can be used in order to commission the device. #### Matter over wifi with openthread border router configuration : -In order to create or join a Thread network on the Matter Border Router, the -`otcli` commands from the matter CLI can be used. For more information about -using the matter shell, follow instructions from +In order to create or join a Thread network on the Matter Border Router, the TBR management cluster or the +`otcli` commands from the matter CLI can be used. For more information about using the TBR management cluster follow instructions from ['Using the TBR management cluster'](../../../../../docs/guides/nxp/nxp_otbr_guide.md#using-the-thread-border-router-management-cluster). +For more information about using the matter shell, follow instructions from ['Testing the all-clusters application with Matter CLI'](#testing-the-all-clusters-application-with-matter-cli-enabled). + In this configuration, the device can be commissioned over Wi-Fi with the 'ble-wifi' pairing method. @@ -384,7 +391,6 @@ Done leader Done ``` - ## OTA Software Update @@ -393,3 +399,11 @@ Over-The-Air software updates are supported with the RW61x all-clusters example. The process to follow in order to perform a software update is described in the dedicated guide ['Matter Over-The-Air Software Update with NXP RW61x example applications'](../../../../../docs/guides/nxp/nxp_rw61x_ota_software_update.md). + + + +## Thread Border Router overwiew + +To enable Thread Border Router support see the [build](README.md#building) section. + +The complete Border Router guide is located [here](../../../../../docs/guides/nxp/nxp_otbr_guide.md). diff --git a/examples/platform/nxp/common/app_task/include/AppTaskBase.h b/examples/platform/nxp/common/app_task/include/AppTaskBase.h index 38770fa0e5ec26..ab29af27c29561 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskBase.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskBase.h @@ -169,6 +169,17 @@ class AppTaskBase */ static void InitServer(intptr_t arg); +#if CHIP_DEVICE_CONFIG_ENABLE_TBR + /** + * \brief Initialize the Thread Border Router management cluster. + * + * Called when the border router function is up and running. This cluster stays disabled + * when the application is used as a Matter over Thread device. + * + */ + void EnableTbrManagementCluster(); +#endif + /** * Commissioning handlers * Generic implementation is provided within this class diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp index c62be98d22c9b1..37d363490bb76f 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -30,6 +30,7 @@ #include #include + #include #include "lib/core/ErrorStr.h" @@ -56,8 +57,8 @@ #include #endif -#if CONFIG_CHIP_TCP_DOWNLOAD -#include "TcpDownload.h" +#if CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT +#include "WifiConnect.h" #endif #if CONFIG_OPERATIONAL_KEYSTORE @@ -97,6 +98,11 @@ #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_TBR +#include "platform/OpenThread/GenericThreadBorderRouterDelegate.h" +#include +#endif + #ifndef CONFIG_THREAD_DEVICE_TYPE #define CONFIG_THREAD_DEVICE_TYPE kThreadDeviceType_Router #endif @@ -120,12 +126,23 @@ app::Clusters::NetworkCommissioning::Instance sNetworkCommissioningInstance(0, chip::NXP::App::GetAppTask().GetEthernetDriverInstance()); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_TBR +static constexpr EndpointId kThreadBRMgmtEndpoint = 2; +static CharSpan sBrName("NXP-BR", strlen("NXP-BR")); +#endif + #if CHIP_CONFIG_ENABLE_ICD_SERVER || (CONFIG_CHIP_TEST_EVENT && CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; #endif +#ifdef SMOKE_CO_ALARM +static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff }; +#endif + #if CONFIG_NET_L2_OPENTHREAD void LockOpenThreadTask(void) { @@ -197,6 +214,14 @@ void chip::NXP::App::AppTaskBase::InitServer(intptr_t arg) #if CONFIG_CHIP_OTA_PROVIDER InitOTAServer(); #endif + +#if CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT + WifiConnectAtboot(); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_TBR + GetAppTask().EnableTbrManagementCluster(); +#endif } CHIP_ERROR chip::NXP::App::AppTaskBase::Init() @@ -326,10 +351,6 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() } #endif -#if CONFIG_CHIP_TCP_DOWNLOAD - EnableTcpDownloadComponent(); -#endif - exit: return err; } @@ -443,3 +464,19 @@ void chip::NXP::App::AppTaskBase::PrintCurrentVersion() ChipLogProgress(DeviceLayer, "Current Software Version: %s, %d", currentSoftwareVer, static_cast(currentVersion)); } + +#if CHIP_DEVICE_CONFIG_ENABLE_TBR +void chip::NXP::App::AppTaskBase::EnableTbrManagementCluster() +{ + auto * persistentStorage = &Server::GetInstance().GetPersistentStorage(); + + static ThreadBorderRouterManagement::GenericOpenThreadBorderRouterDelegate sThreadBRDelegate(persistentStorage); + static ThreadBorderRouterManagement::ServerInstance sThreadBRMgmtInstance(kThreadBRMgmtEndpoint, &sThreadBRDelegate, + Server::GetInstance().GetFailSafeContext()); + + // Initialize TBR name + sThreadBRDelegate.SetThreadBorderRouterName(sBrName); + // Initialize TBR cluster + sThreadBRMgmtInstance.Init(); +} +#endif diff --git a/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h b/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h index 4cbd5028ce58b3..fc8b2ed1774b93 100644 --- a/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h +++ b/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h @@ -40,7 +40,7 @@ class CommonDeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallb virtual void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); virtual void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event); virtual void OnInterfaceIpAddressChanged(const chip::DeviceLayer::ChipDeviceEvent * event); -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#if CHIP_ENABLE_OPENTHREAD virtual void OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event); #endif }; diff --git a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp index 2e40fdefb2e119..1bab4b09f58eda 100644 --- a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp +++ b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp @@ -23,7 +23,9 @@ * **/ #include "CommonDeviceCallbacks.h" +#include "AppTaskBase.h" +#include #include #include #include @@ -73,7 +75,7 @@ void chip::NXP::App::CommonDeviceCallbacks::DeviceEventCallback(const ChipDevice OnInterfaceIpAddressChanged(event); break; -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#if CHIP_ENABLE_OPENTHREAD case DeviceEventType::kCommissioningComplete: CommonDeviceCallbacks::OnComissioningComplete(event); break; @@ -153,9 +155,25 @@ void chip::NXP::App::CommonDeviceCallbacks::OnSessionEstablished(chip::DeviceLay /* Empty */ } -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#if CHIP_ENABLE_OPENTHREAD void chip::NXP::App::CommonDeviceCallbacks::OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event) { +#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + if (ConnectivityMgr().IsWiFiStationConnected()) + { + // Disable thr nwk commissioining cluster + app::Clusters::NetworkCommissioning::Attributes::InterfaceEnabled::Set(CHIP_DEVICE_CONFIG_THREAD_NETWORK_ENDPOINT_ID, 0); + } + else if (ConnectivityMgr().IsThreadProvisioned()) + { + // Set WIFI cluster interface attribute to disable. + app::Clusters::NetworkCommissioning::Attributes::InterfaceEnabled::Set(0, 0); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA +#endif // _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ + +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED /* * If a transceiver supporting a multiprotocol scenario is used, a check of the provisioning state is required, * so that we can inform the transceiver to stop BLE to give the priority to another protocol. @@ -171,5 +189,6 @@ void chip::NXP::App::CommonDeviceCallbacks::OnComissioningComplete(const chip::D PlatformMgrImpl().StopBLEConnectivity(); ThreadStackMgrImpl().UnlockThreadStack(); } +#endif } #endif diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 30af1be0e99a38..389f143a3939bd 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -107,9 +107,12 @@ rt_sdk("sdk") { # Indicate the default path to OpenThreadConfig.h include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] - # For matter with BR feature, increase FreeRTOS heap size + # For matter with BR feature, increase FreeRTOS heap size and enable TBR cluster if (chip_enable_wifi && chip_enable_openthread) { - defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] + defines += [ + "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)", + "CHIP_DEVICE_CONFIG_ENABLE_TBR=1", + ] } } diff --git a/examples/thermostat/nxp/zap/BUILD.gn b/examples/thermostat/nxp/zap/BUILD.gn index c3a3df7bd6729e..f3c652493dd3fb 100644 --- a/examples/thermostat/nxp/zap/BUILD.gn +++ b/examples/thermostat/nxp/zap/BUILD.gn @@ -20,7 +20,10 @@ import("${chip_root}/src/app/chip_data_model.gni") import("${chip_root}/src/platform/device.gni") chip_data_model("zap") { - if (chip_enable_wifi) { + if (chip_enable_wifi && chip_enable_openthread) { + # zap config for matter-over-wifi with BR + zap_file = "thermostat_matter_br.zap" + } else if (chip_enable_wifi) { # zap config for matter-over-wifi zap_file = "thermostat_matter_wifi.zap" } else { diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.matter b/examples/thermostat/nxp/zap/thermostat_matter_br.matter new file mode 100644 index 00000000000000..13ec76f293969a --- /dev/null +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter @@ -0,0 +1,2783 @@ +// 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; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + 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; + kRestroom = 73; + 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; +} + +enum AtomicRequestTypeEnum : enum8 { + kBeginWrite = 0; + kCommitWrite = 1; + kRollbackWrite = 2; +} + +enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; +} + +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 PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; +} + +enum RelativePositionTag : enum8 { + kUnder = 0; + kNextTo = 1; + kAround = 2; + kOn = 3; + kAbove = 4; + kFrontOf = 5; + kBehind = 6; +} + +enum TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + +struct AtomicAttributeStatusStruct { + attrib_id attributeID = 0; + status statusCode = 1; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + 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 event_id eventList[] = 65530; + 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; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + 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 event_id eventList[] = 65530; + 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; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** Attributes and commands for group configuration and manipulation. */ +cluster Groups = 4 { + revision 4; + + bitmap Feature : bitmap32 { + kGroupNames = 0x1; + } + + bitmap NameSupportBitmap : bitmap8 { + kGroupNames = 0x80; + } + + readonly attribute NameSupportBitmap nameSupport = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddGroupRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + response struct AddGroupResponse = 0 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct ViewGroupRequest { + group_id groupID = 0; + } + + response struct ViewGroupResponse = 1 { + enum8 status = 0; + group_id groupID = 1; + char_string<16> groupName = 2; + } + + request struct GetGroupMembershipRequest { + group_id groupList[] = 0; + } + + response struct GetGroupMembershipResponse = 2 { + nullable int8u capacity = 0; + group_id groupList[] = 1; + } + + request struct RemoveGroupRequest { + group_id groupID = 0; + } + + response struct RemoveGroupResponse = 3 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct AddGroupIfIdentifyingRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + /** Command description for AddGroup */ + fabric command access(invoke: manage) AddGroup(AddGroupRequest): AddGroupResponse = 0; + /** Command description for ViewGroup */ + fabric command ViewGroup(ViewGroupRequest): ViewGroupResponse = 1; + /** Command description for GetGroupMembership */ + fabric command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; + /** Command description for RemoveGroup */ + fabric command access(invoke: manage) RemoveGroup(RemoveGroupRequest): RemoveGroupResponse = 3; + /** Command description for RemoveAllGroups */ + fabric command access(invoke: manage) RemoveAllGroups(): DefaultSuccess = 4; + /** Command description for AddGroupIfIdentifying */ + fabric command access(invoke: manage) AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. */ +cluster Binding = 30 { + revision 1; // NOTE: Default/not specifically set + + fabric_scoped struct TargetStruct { + optional node_id node = 1; + optional group_id group = 2; + optional endpoint_no endpoint = 3; + optional cluster_id cluster = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(write: manage) TargetStruct binding[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The 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 2; + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + 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; + } + + 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; + 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) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + 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 command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct 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): DefaultSuccess = 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 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** 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; + 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 event_id eventList[] = 65530; + 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 event_id eventList[] = 65530; + 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 AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing common languages, units of measurements, and numerical formatting + standards. As such, Nodes that visually or audibly convey information need a mechanism by which + they can be configured to use a user’s preferred language, units, etc */ +cluster LocalizationConfiguration = 43 { + revision 1; // NOTE: Default/not specifically set + + attribute access(write: manage) char_string<35> activeLocale = 0; + readonly attribute char_string supportedLocales[] = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing preferences for how dates and times are conveyed. As such, Nodes that visually + or audibly convey time information need a mechanism by which they can be configured to use a + user’s preferred format. */ +cluster TimeFormatLocalization = 44 { + revision 1; // NOTE: Default/not specifically set + + enum CalendarTypeEnum : enum8 { + kBuddhist = 0; + kChinese = 1; + kCoptic = 2; + kEthiopian = 3; + kGregorian = 4; + kHebrew = 5; + kIndian = 6; + kIslamic = 7; + kJapanese = 8; + kKorean = 9; + kPersian = 10; + kTaiwanese = 11; + kUseActiveLocale = 255; + } + + enum HourFormatEnum : enum8 { + k12hr = 0; + k24hr = 1; + kUseActiveLocale = 255; + } + + bitmap Feature : bitmap32 { + kCalendarFormat = 0x1; + } + + attribute access(write: manage) HourFormatEnum hourFormat = 0; + attribute access(write: manage) optional CalendarTypeEnum activeCalendarType = 1; + readonly attribute optional CalendarTypeEnum supportedCalendarTypes[] = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing preferences for the units in which values are conveyed in communication to a + user. As such, Nodes that visually or audibly convey measurable values to the user need a + mechanism by which they can be configured to use a user’s preferred unit. */ +cluster UnitLocalization = 45 { + revision 1; + + enum TempUnitEnum : enum8 { + kFahrenheit = 0; + kCelsius = 1; + kKelvin = 2; + } + + bitmap Feature : bitmap32 { + kTemperatureUnit = 0x1; + } + + attribute access(write: manage) optional TempUnitEnum temperatureUnit = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + + 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; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and 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 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + provisional readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + provisional readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + provisional readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + 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; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** 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 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ +cluster ThreadNetworkDiagnostics = 53 { + revision 2; + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** 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; // NOTE: Default/not specifically set + + 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; + kWPA = 3; + kWPA2 = 4; + kWPA3 = 5; + } + + 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 event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the Breacon and Packet related count attributes to 0 */ + command ResetCounts(): DefaultSuccess = 0; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only +labels. */ +cluster FixedLabel = 64 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + readonly attribute LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The User Label Cluster provides a feature to tag an endpoint with zero or more labels. */ +cluster UserLabel = 65 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + attribute access(write: manage) LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** An interface for configuring and controlling the functionality of a thermostat. */ +cluster Thermostat = 513 { + revision 7; + + enum ACCapacityFormatEnum : enum8 { + kBTUh = 0; + } + + enum ACCompressorTypeEnum : enum8 { + kUnknown = 0; + kT1 = 1; + kT2 = 2; + kT3 = 3; + } + + enum ACLouverPositionEnum : enum8 { + kClosed = 1; + kOpen = 2; + kQuarter = 3; + kHalf = 4; + kThreeQuarters = 5; + } + + enum ACRefrigerantTypeEnum : enum8 { + kUnknown = 0; + kR22 = 1; + kR410a = 2; + kR407c = 3; + } + + enum ACTypeEnum : enum8 { + kUnknown = 0; + kCoolingFixed = 1; + kHeatPumpFixed = 2; + kCoolingInverter = 3; + kHeatPumpInverter = 4; + } + + enum ControlSequenceOfOperationEnum : enum8 { + kCoolingOnly = 0; + kCoolingWithReheat = 1; + kHeatingOnly = 2; + kHeatingWithReheat = 3; + kCoolingAndHeating = 4; + kCoolingAndHeatingWithReheat = 5; + } + + enum PresetScenarioEnum : enum8 { + kOccupied = 1; + kUnoccupied = 2; + kSleep = 3; + kWake = 4; + kVacation = 5; + kGoingToSleep = 6; + kUserDefined = 254; + } + + enum SetpointChangeSourceEnum : enum8 { + kManual = 0; + kSchedule = 1; + kExternal = 2; + } + + enum SetpointRaiseLowerModeEnum : enum8 { + kHeat = 0; + kCool = 1; + kBoth = 2; + } + + enum StartOfWeekEnum : enum8 { + kSunday = 0; + kMonday = 1; + kTuesday = 2; + kWednesday = 3; + kThursday = 4; + kFriday = 5; + kSaturday = 6; + } + + enum SystemModeEnum : enum8 { + kOff = 0; + kAuto = 1; + kCool = 3; + kHeat = 4; + kEmergencyHeat = 5; + kPrecooling = 6; + kFanOnly = 7; + kDry = 8; + kSleep = 9; + } + + enum TemperatureSetpointHoldEnum : enum8 { + kSetpointHoldOff = 0; + kSetpointHoldOn = 1; + } + + enum ThermostatRunningModeEnum : enum8 { + kOff = 0; + kCool = 3; + kHeat = 4; + } + + bitmap ACErrorCodeBitmap : bitmap32 { + kCompressorFail = 0x1; + kRoomSensorFail = 0x2; + kOutdoorSensorFail = 0x4; + kCoilSensorFail = 0x8; + kFanFail = 0x10; + } + + bitmap Feature : bitmap32 { + kHeating = 0x1; + kCooling = 0x2; + kOccupancy = 0x4; + kScheduleConfiguration = 0x8; + kSetback = 0x10; + kAutoMode = 0x20; + kLocalTemperatureNotExposed = 0x40; + kMatterScheduleConfiguration = 0x80; + kPresets = 0x100; + } + + bitmap HVACSystemTypeBitmap : bitmap8 { + kCoolingStage = 0x3; + kHeatingStage = 0xC; + kHeatingIsHeatPump = 0x10; + kHeatingUsesFuel = 0x20; + } + + bitmap OccupancyBitmap : bitmap8 { + kOccupied = 0x1; + } + + bitmap PresetTypeFeaturesBitmap : bitmap16 { + kAutomatic = 0x1; + kSupportsNames = 0x2; + } + + bitmap ProgrammingOperationModeBitmap : bitmap8 { + kScheduleActive = 0x1; + kAutoRecovery = 0x2; + kEconomy = 0x4; + } + + bitmap RelayStateBitmap : bitmap16 { + kHeat = 0x1; + kCool = 0x2; + kFan = 0x4; + kHeatStage2 = 0x8; + kCoolStage2 = 0x10; + kFanStage2 = 0x20; + kFanStage3 = 0x40; + } + + bitmap RemoteSensingBitmap : bitmap8 { + kLocalTemperature = 0x1; + kOutdoorTemperature = 0x2; + kOccupancy = 0x4; + } + + bitmap ScheduleDayOfWeekBitmap : bitmap8 { + kSunday = 0x1; + kMonday = 0x2; + kTuesday = 0x4; + kWednesday = 0x8; + kThursday = 0x10; + kFriday = 0x20; + kSaturday = 0x40; + kAway = 0x80; + } + + bitmap ScheduleModeBitmap : bitmap8 { + kHeatSetpointPresent = 0x1; + kCoolSetpointPresent = 0x2; + } + + bitmap ScheduleTypeFeaturesBitmap : bitmap16 { + kSupportsPresets = 0x1; + kSupportsSetpoints = 0x2; + kSupportsNames = 0x4; + kSupportsOff = 0x8; + } + + struct ScheduleTransitionStruct { + ScheduleDayOfWeekBitmap dayOfWeek = 0; + int16u transitionTime = 1; + optional octet_string<16> presetHandle = 2; + optional SystemModeEnum systemMode = 3; + optional temperature coolingSetpoint = 4; + optional temperature heatingSetpoint = 5; + } + + struct ScheduleStruct { + nullable octet_string<16> scheduleHandle = 0; + SystemModeEnum systemMode = 1; + optional char_string<64> name = 2; + optional octet_string<16> presetHandle = 3; + ScheduleTransitionStruct transitions[] = 4; + nullable boolean builtIn = 5; + } + + struct PresetStruct { + nullable octet_string<16> presetHandle = 0; + PresetScenarioEnum presetScenario = 1; + optional nullable char_string<64> name = 2; + optional temperature coolingSetpoint = 3; + optional temperature heatingSetpoint = 4; + nullable boolean builtIn = 5; + } + + struct PresetTypeStruct { + PresetScenarioEnum presetScenario = 0; + int8u numberOfPresets = 1; + PresetTypeFeaturesBitmap presetTypeFeatures = 2; + } + + struct ScheduleTypeStruct { + SystemModeEnum systemMode = 0; + int8u numberOfSchedules = 1; + ScheduleTypeFeaturesBitmap scheduleTypeFeatures = 2; + } + + struct WeeklyScheduleTransitionStruct { + int16u transitionTime = 0; + nullable temperature heatSetpoint = 1; + nullable temperature coolSetpoint = 2; + } + + readonly attribute nullable temperature localTemperature = 0; + readonly attribute optional nullable temperature outdoorTemperature = 1; + readonly attribute optional OccupancyBitmap occupancy = 2; + readonly attribute optional temperature absMinHeatSetpointLimit = 3; + readonly attribute optional temperature absMaxHeatSetpointLimit = 4; + readonly attribute optional temperature absMinCoolSetpointLimit = 5; + readonly attribute optional temperature absMaxCoolSetpointLimit = 6; + readonly attribute optional int8u PICoolingDemand = 7; + readonly attribute optional int8u PIHeatingDemand = 8; + attribute access(write: manage) optional HVACSystemTypeBitmap HVACSystemTypeConfiguration = 9; + attribute access(write: manage) optional int8s localTemperatureCalibration = 16; + attribute optional temperature occupiedCoolingSetpoint = 17; + attribute optional temperature occupiedHeatingSetpoint = 18; + attribute optional temperature unoccupiedCoolingSetpoint = 19; + attribute optional temperature unoccupiedHeatingSetpoint = 20; + attribute access(write: manage) optional temperature minHeatSetpointLimit = 21; + attribute access(write: manage) optional temperature maxHeatSetpointLimit = 22; + attribute access(write: manage) optional temperature minCoolSetpointLimit = 23; + attribute access(write: manage) optional temperature maxCoolSetpointLimit = 24; + attribute access(write: manage) optional int8s minSetpointDeadBand = 25; + attribute access(write: manage) optional RemoteSensingBitmap remoteSensing = 26; + attribute access(write: manage) ControlSequenceOfOperationEnum controlSequenceOfOperation = 27; + attribute access(write: manage) SystemModeEnum systemMode = 28; + readonly attribute optional ThermostatRunningModeEnum thermostatRunningMode = 30; + readonly attribute optional StartOfWeekEnum startOfWeek = 32; + readonly attribute optional int8u numberOfWeeklyTransitions = 33; + readonly attribute optional int8u numberOfDailyTransitions = 34; + attribute access(write: manage) optional TemperatureSetpointHoldEnum temperatureSetpointHold = 35; + attribute access(write: manage) optional nullable int16u temperatureSetpointHoldDuration = 36; + attribute access(write: manage) optional ProgrammingOperationModeBitmap thermostatProgrammingOperationMode = 37; + readonly attribute optional RelayStateBitmap thermostatRunningState = 41; + readonly attribute optional SetpointChangeSourceEnum setpointChangeSource = 48; + readonly attribute optional nullable int16s setpointChangeAmount = 49; + readonly attribute optional epoch_s setpointChangeSourceTimestamp = 50; + attribute access(write: manage) optional nullable int8u occupiedSetback = 52; + readonly attribute optional nullable int8u occupiedSetbackMin = 53; + readonly attribute optional nullable int8u occupiedSetbackMax = 54; + attribute access(write: manage) optional nullable int8u unoccupiedSetback = 55; + readonly attribute optional nullable int8u unoccupiedSetbackMin = 56; + readonly attribute optional nullable int8u unoccupiedSetbackMax = 57; + attribute access(write: manage) optional int8u emergencyHeatDelta = 58; + attribute access(write: manage) optional ACTypeEnum ACType = 64; + attribute access(write: manage) optional int16u ACCapacity = 65; + attribute access(write: manage) optional ACRefrigerantTypeEnum ACRefrigerantType = 66; + attribute access(write: manage) optional ACCompressorTypeEnum ACCompressorType = 67; + attribute access(write: manage) optional ACErrorCodeBitmap ACErrorCode = 68; + attribute access(write: manage) optional ACLouverPositionEnum ACLouverPosition = 69; + readonly attribute optional nullable temperature ACCoilTemperature = 70; + attribute access(write: manage) optional ACCapacityFormatEnum ACCapacityformat = 71; + readonly attribute optional PresetTypeStruct presetTypes[] = 72; + readonly attribute optional ScheduleTypeStruct scheduleTypes[] = 73; + readonly attribute optional int8u numberOfPresets = 74; + readonly attribute optional int8u numberOfSchedules = 75; + readonly attribute optional int8u numberOfScheduleTransitions = 76; + readonly attribute optional nullable int8u numberOfScheduleTransitionPerDay = 77; + readonly attribute optional nullable octet_string<16> activePresetHandle = 78; + readonly attribute optional nullable octet_string<16> activeScheduleHandle = 79; + attribute access(write: manage) optional PresetStruct presets[] = 80; + attribute access(write: manage) optional ScheduleStruct schedules[] = 81; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 82; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SetpointRaiseLowerRequest { + SetpointRaiseLowerModeEnum mode = 0; + int8s amount = 1; + } + + response struct GetWeeklyScheduleResponse = 0 { + int8u numberOfTransitionsForSequence = 0; + ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1; + ScheduleModeBitmap modeForSequence = 2; + WeeklyScheduleTransitionStruct transitions[] = 3; + } + + request struct SetWeeklyScheduleRequest { + int8u numberOfTransitionsForSequence = 0; + ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1; + ScheduleModeBitmap modeForSequence = 2; + WeeklyScheduleTransitionStruct transitions[] = 3; + } + + request struct GetWeeklyScheduleRequest { + ScheduleDayOfWeekBitmap daysToReturn = 0; + ScheduleModeBitmap modeToReturn = 1; + } + + request struct SetActiveScheduleRequestRequest { + octet_string<16> scheduleHandle = 0; + } + + request struct SetActivePresetRequestRequest { + octet_string<16> presetHandle = 0; + } + + response struct AtomicResponse = 253 { + status statusCode = 0; + AtomicAttributeStatusStruct attributeStatus[] = 1; + optional int16u timeout = 2; + } + + request struct AtomicRequestRequest { + AtomicRequestTypeEnum requestType = 0; + attrib_id attributeRequests[] = 1; + optional int16u timeout = 2; + } + + /** Upon receipt, the attributes for the indicated setpoint(s) SHALL have the amount specified in the Amount field added to them. */ + command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; + /** This command is used to update the thermostat weekly setpoint schedule from a management system. */ + command access(invoke: manage) SetWeeklySchedule(SetWeeklyScheduleRequest): DefaultSuccess = 1; + /** The Current Weekly Schedule Command is sent from the server in response to the Get Weekly Schedule Command. */ + command GetWeeklySchedule(GetWeeklyScheduleRequest): GetWeeklyScheduleResponse = 2; + /** This command is used to clear the weekly schedule. */ + command access(invoke: manage) ClearWeeklySchedule(): DefaultSuccess = 3; + /** Upon receipt, if the Schedules attribute contains a ScheduleStruct whose ScheduleHandle field matches the value of the ScheduleHandle field, the server SHALL set the thermostat's ActiveScheduleHandle attribute to the value of the ScheduleHandle field. */ + command SetActiveScheduleRequest(SetActiveScheduleRequestRequest): DefaultSuccess = 5; + /** ID */ + command SetActivePresetRequest(SetActivePresetRequestRequest): DefaultSuccess = 6; + /** Begins, Commits or Cancels an atomic write */ + command access(invoke: manage) AtomicRequest(AtomicRequestRequest): AtomicResponse = 254; +} + +/** Manage the Thread network of Thread Border Router */ +provisional cluster ThreadBorderRouterManagement = 1106 { + revision 1; + + bitmap Feature : bitmap32 { + kPANChange = 0x1; + } + + provisional readonly attribute char_string<63> borderRouterName = 0; + provisional readonly attribute octet_string<254> borderAgentID = 1; + provisional readonly attribute int16u threadVersion = 2; + provisional readonly attribute boolean interfaceEnabled = 3; + provisional readonly attribute nullable int64u activeDatasetTimestamp = 4; + provisional readonly attribute nullable int64u pendingDatasetTimestamp = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + response struct DatasetResponse = 2 { + octet_string<254> dataset = 0; + } + + request struct SetActiveDatasetRequestRequest { + octet_string<254> activeDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct SetPendingDatasetRequestRequest { + octet_string<254> pendingDataset = 0; + } + + /** Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetActiveDatasetRequest(): DatasetResponse = 0; + /** Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; + /** Command to set or update the active Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; + /** Command set or update the pending Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + binding cluster OtaSoftwareUpdateProvider; + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + ram attribute updatePossible default = 1; + ram attribute updateState default = 0; + ram attribute updateStateProgress default = 0; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + + server cluster LocalizationConfiguration { + persist attribute activeLocale default = "en-US"; + callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster TimeFormatLocalization { + persist attribute hourFormat default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UnitLocalization { + ram attribute temperatureUnit; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x1; + ram attribute clusterRevision default = 1; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + callback attribute supportedWiFiBands; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + handle command RetrieveLogsResponse; + } + + 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 generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster WiFiNetworkDiagnostics { + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute currentMaxRate; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } +} +endpoint 1 { + device type ma_thermostat = 769, version 1; + + binding cluster Identify; + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Groups { + ram attribute nameSupport; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command AddGroup; + handle command AddGroupResponse; + handle command ViewGroup; + handle command ViewGroupResponse; + handle command GetGroupMembership; + handle command GetGroupMembershipResponse; + handle command RemoveGroup; + handle command RemoveGroupResponse; + handle command RemoveAllGroups; + handle command AddGroupIfIdentifying; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Binding { + callback attribute binding; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster FixedLabel { + callback attribute labelList; + callback attribute eventList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UserLabel { + callback attribute labelList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster Thermostat { + ram attribute localTemperature; + ram attribute absMinHeatSetpointLimit default = 700; + ram attribute absMaxHeatSetpointLimit default = 3000; + ram attribute absMinCoolSetpointLimit default = 1600; + ram attribute absMaxCoolSetpointLimit default = 3200; + persist attribute occupiedCoolingSetpoint default = 0x0A28; + persist attribute occupiedHeatingSetpoint default = 0x07D0; + ram attribute minHeatSetpointLimit default = 700; + ram attribute maxHeatSetpointLimit default = 3000; + ram attribute minCoolSetpointLimit default = 1600; + ram attribute maxCoolSetpointLimit default = 3200; + ram attribute controlSequenceOfOperation default = 0x04; + persist attribute systemMode default = 0x01; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0x3; + ram attribute clusterRevision default = 7; + + handle command SetpointRaiseLower; + } +} +endpoint 2 { + device type ma_thread_border_router = 145, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + } + + server cluster ThreadBorderRouterManagement { + callback attribute borderRouterName; + callback attribute borderAgentID; + callback attribute threadVersion; + callback attribute interfaceEnabled; + callback attribute activeDatasetTimestamp; + callback attribute pendingDatasetTimestamp; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command GetActiveDatasetRequest; + handle command GetPendingDatasetRequest; + handle command DatasetResponse; + handle command SetActiveDatasetRequest; + handle command SetPendingDatasetRequest; + } +} +endpoint 3 { + device type ma_secondary_network_interface = 25, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute supportedThreadFeatures; + ram attribute threadVersion; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } +} + + diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.zap b/examples/thermostat/nxp/zap/thermostat_matter_br.zap new file mode 100644 index 00000000000000..f766783c3cbf75 --- /dev/null +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.zap @@ -0,0 +1,5592 @@ +{ + "fileFormat": 2, + "featureLevel": 103, + "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" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "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": "EventList", + "code": 65530, + "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": "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": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 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": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "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 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "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": 1, + "maxInterval": 65534, + "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": 1, + "maxInterval": 65534, + "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": 1, + "maxInterval": 65534, + "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": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "en-US", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "HourFormat", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "HourFormatEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Unit Localization", + "code": 45, + "mfgCode": null, + "define": "UNIT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "TemperatureUnit", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "TempUnitEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": 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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedWiFiBands", + "code": 8, + "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "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": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General 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": "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": "EventList", + "code": 65530, + "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": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Wi-Fi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 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": "CurrentMaxRate", + "code": 11, + "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": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "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": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 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 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "MA-thermostat", + "deviceTypeRef": { + "code": 769, + "profileId": 259, + "label": "MA-thermostat", + "name": "MA-thermostat" + }, + "deviceTypes": [ + { + "code": 769, + "profileId": 259, + "label": "MA-thermostat", + "name": "MA-thermostat" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 769 + ], + "deviceTypeName": "MA-thermostat", + "deviceTypeCode": 769, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "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 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "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": "EventList", + "code": 65530, + "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": "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": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NameSupport", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "NameSupportBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 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": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "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": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Thermostat", + "code": 513, + "mfgCode": null, + "define": "THERMOSTAT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetpointRaiseLower", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "LocalTemperature", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AbsMinHeatSetpointLimit", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "700", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AbsMaxHeatSetpointLimit", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AbsMinCoolSetpointLimit", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1600", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AbsMaxCoolSetpointLimit", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3200", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OccupiedCoolingSetpoint", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0A28", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OccupiedHeatingSetpoint", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x07D0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MinHeatSetpointLimit", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "700", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MaxHeatSetpointLimit", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MinCoolSetpointLimit", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1600", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MaxCoolSetpointLimit", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3200", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ControlSequenceOfOperation", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "ControlSequenceOfOperationEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x04", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SystemMode", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "SystemModeEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "7", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 3, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 145, + "profileId": 259, + "label": "MA-thread-border-router", + "name": "MA-thread-border-router" + }, + "deviceTypes": [ + { + "code": 145, + "profileId": 259, + "label": "MA-thread-border-router", + "name": "MA-thread-border-router" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 145 + ], + "deviceTypeName": "MA-thread-border-router", + "deviceTypeCode": 145, + "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": "EventList", + "code": 65530, + "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": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": 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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Border Router Management", + "code": 1106, + "mfgCode": null, + "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "GetActiveDatasetRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetPendingDatasetRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DatasetResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetActiveDatasetRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetPendingDatasetRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BorderRouterName", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BorderAgentID", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveDatasetTimestamp", + "code": 4, + "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": "PendingDatasetTimestamp", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": 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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 4, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 25, + "profileId": 259, + "label": "MA-secondary-network-interface", + "name": "MA-secondary-network-interface" + }, + "deviceTypes": [ + { + "code": 25, + "profileId": 259, + "label": "MA-secondary-network-interface", + "name": "MA-secondary-network-interface" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 25 + ], + "deviceTypeName": "MA-secondary-network-interface", + "deviceTypeCode": 25, + "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": "EventList", + "code": 65530, + "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": "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": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": 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": "EventList", + "code": 65530, + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "MA-thermostat", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 2, + "profileId": 259, + "endpointId": 2, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 3, + "profileId": 259, + "endpointId": 3, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file From cc631e9988be476bf4e9e8d858fda2c86f51eed9 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:49:07 +0200 Subject: [PATCH 04/18] [NXP][src] Add support for TBR management cluster and secondary nwk, Updated common app to work with SNI and TBRM Signed-off-by: Martin Girardot --- .../nxp/common/ConnectivityManagerImpl.cpp | 9 +- src/platform/nxp/common/DnssdImpl.cpp | 897 +---------------- src/platform/nxp/common/DnssdImplBr.cpp | 939 ++++++++++++++++++ src/platform/nxp/common/DnssdImplBr.h | 46 + src/platform/nxp/rt/rw61x/BUILD.gn | 27 +- .../nxp/rt/rw61x/PlatformManagerImpl.cpp | 1 + src/platform/nxp/rt/rw61x/args.gni | 2 + 7 files changed, 1061 insertions(+), 860 deletions(-) create mode 100644 src/platform/nxp/common/DnssdImplBr.cpp create mode 100644 src/platform/nxp/common/DnssdImplBr.h diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index 09d716ac6ea77f..3473fc7515e640 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -95,10 +95,6 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() GenericConnectivityManagerImpl_Thread::_Init(); #endif -#if CHIP_DEVICE_CONFIG_ENABLE_WPA - StartWiFiManagement(); -#endif - SuccessOrExit(err); exit: @@ -614,6 +610,11 @@ CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, uint VerifyOrExit(ssidLen <= IEEEtypes_SSID_SIZE, ret = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(mWiFiStationState != kWiFiStationState_Connecting, ret = CHIP_ERROR_BUSY); + // Need to enable the WIFI interface here when Thread is enabled as a secondary network interface. We don't want to enable + // WIFI from the init phase anymore and we will only do it in case the commissioner is provisioning the device with + // the WIFI credentials. + StartWiFiManagement(); + memset(pNetworkData, 0, sizeof(struct wlan_network)); if (ssidLen < WLAN_NETWORK_NAME_MAX_LENGTH) diff --git a/src/platform/nxp/common/DnssdImpl.cpp b/src/platform/nxp/common/DnssdImpl.cpp index d0069cebcf1c4a..439327017897b2 100644 --- a/src/platform/nxp/common/DnssdImpl.cpp +++ b/src/platform/nxp/common/DnssdImpl.cpp @@ -1,6 +1,7 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2024 Project CHIP Authors + * Copyright 2024 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,922 +17,118 @@ */ #include "lib/dnssd/platform/Dnssd.h" -#include -#include -#include -#include -#include +#include "platform/CHIPDeviceLayer.h" -#include +#include +#include +#include -#include -#include +#include +#include using namespace ::chip::DeviceLayer; -using namespace chip::DeviceLayer::Internal; namespace chip { namespace Dnssd { -#define USE_MDNS_NEXT_SERVICE_API 1 - -// Support both operational and commissionable discovery, so buffers sizes must be worst case. -static constexpr uint8_t kMaxMdnsServiceTxtEntriesNumber = - std::max(Dnssd::CommissionAdvertisingParameters::kTxtMaxNumber, Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber); -static constexpr size_t kTotalMdnsServiceTxtValueSize = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalValueSize, - Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize); -static constexpr size_t kTotalMdnsServiceTxtKeySize = - std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalKeySize, Dnssd::OperationalAdvertisingParameters::kTxtTotalKeySize); - -static constexpr size_t kTotalMdnsServiceTxtBufferSize = - kTotalMdnsServiceTxtKeySize + kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtValueSize; - -// For each fabric we can register one _matter._tcp and one _matterc._udp service -static constexpr uint32_t kServiceListSize = CHIP_CONFIG_MAX_FABRICS * 2; - -static const char * GetProtocolString(DnssdServiceProtocol protocol) -{ - return protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp"; -} - -struct DnsServiceTxtEntries -{ - uint8_t mBuffer[kTotalMdnsServiceTxtBufferSize]; - Dnssd::TextEntry mTxtEntries[kMaxMdnsServiceTxtEntriesNumber]; -}; - -struct mDnsQueryCtx -{ - void * matterCtx; - chip::Dnssd::DnssdService mMdnsService; - DnsServiceTxtEntries mServiceTxtEntry; - char mServiceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1]; - CHIP_ERROR error; - union - { - otMdnsBrowser mBrowseInfo; - otMdnsSrvResolver mSrvInfo; - otMdnsTxtResolver mTxtInfo; - otMdnsAddressResolver mAddrInfo; - }; - union - { - DnsBrowseCallback mDnsBrowseCallback; - DnsResolveCallback mDnsResolveCallback; - }; - - mDnsQueryCtx(void * context, DnsBrowseCallback aBrowseCallback) - { - matterCtx = context; - mDnsBrowseCallback = aBrowseCallback; - error = CHIP_NO_ERROR; - } - mDnsQueryCtx(void * context, DnsResolveCallback aResolveCallback) - { - matterCtx = context; - mDnsResolveCallback = aResolveCallback; - error = CHIP_NO_ERROR; - } -}; - -enum ResolveStep : uint8_t -{ - kResolveStepSrv = 0, - kResolveStepTxt, - kResolveStepIpAddr, -}; - -static const char * GetProtocolString(DnssdServiceProtocol protocol); - -static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult); -static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult); -static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult); -static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult); - -static void DispatchBrowseEmpty(intptr_t context); -static void DispatchBrowse(intptr_t context); - -static void DispatchTxtResolve(intptr_t context); -static void DispatchAddressResolve(intptr_t context); -static void DispatchResolve(intptr_t context); -static void DispatchResolveError(intptr_t context); - -static void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType); - -static CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq); -static CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context); -static CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, - const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, - DnsServiceTxtEntries & serviceTxtEntries); - -static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType); - -static bool bBrowseInProgress = false; -// ID 0 is reserved for host -static uint32_t mRegisterServiceId = 1; -static uint8_t mNetifIndex = 0; - -// Matter currently only supports one browse and resolve operation at a time so there is no need to create a list -// If the Matter implementation evolves in the future this functionality can be extended to a list. -static mDnsQueryCtx * mBrowseContext = nullptr; -static mDnsQueryCtx * mResolveContext = nullptr; - -#if USE_MDNS_NEXT_SERVICE_API -static otMdnsService * mServiceList[kServiceListSize]; -static uint32_t mServiceListFreeIndex; -#endif - CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) { - CHIP_ERROR error = CHIP_NO_ERROR; - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - struct netif * extNetif = (ConnectivityManagerImpl().GetExternalInterface()).GetPlatformInterface(); + NxpChipDnssdInit(initCallback, errorCallback, context); + OpenThreadDnssdInit(initCallback, errorCallback, context); - // Don't try to do anything until the mDNS server is started - VerifyOrExit(otMdnsIsEnabled(thrInstancePtr), error = CHIP_ERROR_INCORRECT_STATE); - - mNetifIndex = netif_get_index(extNetif); - -exit: - initCallback(context, error); - return error; + return CHIP_NO_ERROR; } void ChipDnssdShutdown() { - otMdnsSetEnabled(ThreadStackMgrImpl().OTInstance(), false, 0); + NxpChipDnssdShutdown(); } -#if USE_MDNS_NEXT_SERVICE_API -CHIP_ERROR ChipDnssdRemoveServices() -{ - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otMdnsService otServiceData = { 0 }; - otMdnsIterator * iterator = nullptr; - ChipError error = CHIP_NO_ERROR; - otError otError = OT_ERROR_NONE; - otMdnsEntryState state; - - const char * hostName = ConnectivityManagerImpl().GetHostName(); - - iterator = otMdnsAllocateIterator(thrInstancePtr); - VerifyOrExit(iterator != nullptr, error = CHIP_ERROR_NO_MEMORY); - - mServiceListFreeIndex = 0; - - while (mServiceListFreeIndex <= kServiceListSize) - { - // allocate memory for new entry if the entry is not allready allocated from previous iteration - if (mServiceList[mServiceListFreeIndex] == nullptr) - { - mServiceList[mServiceListFreeIndex] = static_cast(Platform::MemoryAlloc(sizeof(otMdnsService))); - VerifyOrExit(mServiceList[mServiceListFreeIndex] != nullptr, error = CHIP_ERROR_NO_MEMORY); - } - - otError = otMdnsGetNextService(thrInstancePtr, iterator, mServiceList[mServiceListFreeIndex], &state); - if (otError == OT_ERROR_NOT_FOUND) - { - Platform::MemoryFree(mServiceList[mServiceListFreeIndex]); - mServiceList[mServiceListFreeIndex] = nullptr; - break; - } - - if ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mHostName, hostName)) && - ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matter._tcp")) || - (0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matterc._udp")))) - { - mServiceListFreeIndex++; - } - } - -exit: - if (iterator != nullptr) - { - otMdnsFreeIterator(thrInstancePtr, iterator); - } - return error; -} -#else -CHIP_ERROR ChipDnssdRemoveServices() -{ - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otMdnsService otServiceData = { 0 }; - - otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); - - otServiceData.mServiceType = "_matter._tcp"; - otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); - otServiceData.mServiceType = "_matterc._udp"; - otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); - - return CHIP_NO_ERROR; -} -#endif CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) { - ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - uint32_t txtBufferOffset = 0; - otError otErr = OT_ERROR_NONE; - otMdnsService otServiceData = { 0 }; - -#if USE_MDNS_NEXT_SERVICE_API - bool bRegisterService = true; -#endif - - char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1] = ""; - snprintf(serviceType, sizeof(serviceType), "%s.%s", service->mType, GetProtocolString(service->mProtocol)); - - // secure space for the raw TXT data in the worst-case scenario relevant for Matter: - // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data - uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize] = { 0 }; - - // Don't try to do anything until the mDNS server is started - VerifyOrReturnValue(otMdnsIsEnabled(thrInstancePtr), CHIP_NO_ERROR); - - // Create TXT Data as one string from multiple key entries - for (uint32_t i = 0; i < service->mTextEntrySize; i++) + if (ConnectivityMgr().IsWiFiStationConnected()) { - uint32_t keySize = strlen(service->mTextEntries[i].mKey); - // add TXT entry len, + 1 is for '=' - *(txtBuffer + txtBufferOffset++) = keySize + service->mTextEntries[i].mDataSize + 1; - - // add TXT entry key - memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mKey, keySize); - txtBufferOffset += keySize; - - // add TXT entry value if pointer is not null, if pointer is null it means we have bool value - if (service->mTextEntries[i].mData) - { - *(txtBuffer + txtBufferOffset++) = '='; - memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mData, service->mTextEntries[i].mDataSize); - txtBufferOffset += service->mTextEntries[i].mDataSize; - } - } - -#if USE_MDNS_NEXT_SERVICE_API - for (uint32_t i = 0; i < mServiceListFreeIndex; i++) - { - if ((0 == strcmp(mServiceList[i]->mHostName, service->mHostName)) && - (0 == strcmp(mServiceList[i]->mServiceInstance, service->mName)) && - (0 == strcmp(mServiceList[i]->mServiceType, serviceType))) - { - if ((mServiceList[i]->mTxtDataLength == txtBufferOffset) && - (0 == memcmp(txtBuffer, mServiceList[i]->mTxtData, txtBufferOffset))) - { - // In this case the service is - bRegisterService = false; - } - Platform::MemoryFree(mServiceList[i]); - if (i < --mServiceListFreeIndex) - { - // move last element in place of the removed one - mServiceList[i] = mServiceList[mServiceListFreeIndex]; - mServiceList[mServiceListFreeIndex] = nullptr; - } - else - { - mServiceList[i] = nullptr; - } - break; - } - } -#endif - if (bRegisterService) - { - if (strcmp(service->mHostName, "") != 0) - { - otServiceData.mHostName = service->mHostName; - } - - otServiceData.mServiceInstance = service->mName; - otServiceData.mServiceType = serviceType; - otServiceData.mSubTypeLabels = service->mSubTypes; - otServiceData.mSubTypeLabelsLength = service->mSubTypeSize; - otServiceData.mPort = service->mPort; - otServiceData.mTtl = service->mTtlSeconds; - otServiceData.mTxtData = txtBuffer; - otServiceData.mTxtDataLength = txtBufferOffset; - - otErr = otMdnsRegisterService(thrInstancePtr, &otServiceData, mRegisterServiceId++, NULL); + ReturnErrorOnFailure(NxpChipDnssdPublishService(service, callback, context)); } - - return MapOpenThreadError(otErr); -} - -#if USE_MDNS_NEXT_SERVICE_API -CHIP_ERROR ChipDnssdFinalizeServiceUpdate() -{ - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - - for (uint32_t i = 0; i < mServiceListFreeIndex; i++) + else if (ConnectivityMgr().IsThreadProvisioned()) { - if (mServiceList[i] != nullptr) - { - otMdnsUnregisterService(thrInstancePtr, mServiceList[i]); - Platform::MemoryFree(mServiceList[i]); - mServiceList[i] = nullptr; - } + ReturnErrorOnFailure(OpenThreadDnssdPublishService(service, callback, context)); } - mServiceListFreeIndex = 0; return CHIP_NO_ERROR; } -#else -CHIP_ERROR ChipDnssdFinalizeServiceUpdate() -{ - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otMdnsService otServiceData = { 0 }; - - otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); - - otServiceData.mServiceType = "_matter._tcp"; - otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); - otServiceData.mServiceType = "_matterc._udp"; - otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); - - return CHIP_NO_ERROR; -} -#endif - -CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, - Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier) -{ - *browseIdentifier = reinterpret_cast(nullptr); - CHIP_ERROR error = CHIP_NO_ERROR; - CHIP_ERROR srpBrowseError = CHIP_NO_ERROR; - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - - if (type == nullptr || callback == nullptr) - return CHIP_ERROR_INVALID_ARGUMENT; - - mBrowseContext = Platform::New(context, callback); - VerifyOrReturnError(mBrowseContext != nullptr, CHIP_ERROR_NO_MEMORY); - - // First try to browse the service in the SRP cache - snprintf(mBrowseContext->mServiceType, sizeof(mBrowseContext->mServiceType), "%s.%s", type, GetProtocolString(protocol)); - // After browsing in the SRP cache we will continue with regular mDNS browse - srpBrowseError = BrowseBySrp(thrInstancePtr, mBrowseContext->mServiceType, mBrowseContext); - - // Proceed to generate a mDNS query - mBrowseContext->mBrowseInfo.mServiceType = mBrowseContext->mServiceType; - mBrowseContext->mBrowseInfo.mSubTypeLabel = nullptr; - mBrowseContext->mBrowseInfo.mInfraIfIndex = mNetifIndex; - mBrowseContext->mBrowseInfo.mCallback = OtBrowseCallback; - - error = MapOpenThreadError(otMdnsStartBrowser(thrInstancePtr, &mBrowseContext->mBrowseInfo)); - - if (CHIP_NO_ERROR == error) - { - bBrowseInProgress = true; - *browseIdentifier = reinterpret_cast(mBrowseContext); - } - else - { - if (srpBrowseError == CHIP_NO_ERROR) - { - // In this case, we need to send a final browse indication to signal the Matter App that there are no more - // browse results coming - mBrowseContext->error = error; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(mBrowseContext)); - } - else - { - Platform::Delete(mBrowseContext); - mBrowseContext = nullptr; - } - } - return error; -} - -CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) -{ - mDnsQueryCtx * browseContext = reinterpret_cast(browseIdentifier); - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otError error = OT_ERROR_INVALID_ARGS; - - // browseContext is only valid when bBrowseInProgress is true. The Matter stack can call this function even with a browseContext - // that has been freed in DispatchBrowseEmpty. - if ((true == bBrowseInProgress) && (browseContext)) - { - browseContext->error = MapOpenThreadError(otMdnsStopBrowser(thrInstancePtr, &browseContext->mBrowseInfo)); - - // browse context will be freed in DispatchBrowseEmpty - DispatchBrowseEmpty(reinterpret_cast(browseContext)); - } - return MapOpenThreadError(error); -} - -CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) -{ - ChipError error = CHIP_ERROR_NOT_FOUND; - - if (browseResult == nullptr || callback == nullptr) - return CHIP_ERROR_INVALID_ARGUMENT; - - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - - mResolveContext = Platform::New(context, callback); - VerifyOrReturnError(mResolveContext != nullptr, CHIP_ERROR_NO_MEMORY); - - // First try to find the service in the SRP cache, use default.service.arpa as domain name - snprintf(mResolveContext->mServiceType, sizeof(mResolveContext->mServiceType), "%s.%s", browseResult->mType, - GetProtocolString(browseResult->mProtocol)); - - error = ResolveBySrp(thrInstancePtr, mResolveContext->mServiceType, mResolveContext, browseResult); - // If the SRP cache returns not found, proceed to generate a MDNS query - if (CHIP_ERROR_NOT_FOUND == error) - { - // The otMdnsSrvResolver structure contains only pointers to instance name and service type strings - // Use the memory from mMdnsService.mName to store the instance name string we are looking for - Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), browseResult->mName); - - mResolveContext->mSrvInfo.mInfraIfIndex = mNetifIndex; - mResolveContext->mSrvInfo.mCallback = OtServiceCallback; - mResolveContext->mSrvInfo.mServiceInstance = mResolveContext->mMdnsService.mName; - mResolveContext->mSrvInfo.mServiceType = mResolveContext->mServiceType; - - return MapOpenThreadError(otMdnsStartSrvResolver(thrInstancePtr, &mResolveContext->mSrvInfo)); - } - else - { - return error; - } -} -void ChipDnssdResolveNoLongerNeeded(const char * instanceName) -{ - if (mResolveContext != nullptr) - { - if (strcmp(instanceName, mResolveContext->mMdnsService.mName) == 0) - { - otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &mResolveContext->mSrvInfo); - - Platform::Delete(mResolveContext); - mResolveContext = nullptr; - } - } -} - -CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface) -{ - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context) -{ - const otSrpServerHost * host = nullptr; - const otSrpServerService * service = nullptr; - CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; - - while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) - { - while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) - { - if ((false == otSrpServerServiceIsDeleted(service)) && - (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName)))) - { - mDnsQueryCtx * serviceContext = Platform::New(context->matterCtx, context->mDnsBrowseCallback); - if (serviceContext != nullptr) - { - if (CHIP_NO_ERROR == - FromSrpCacheToMdnsData(service, host, nullptr, serviceContext->mMdnsService, - serviceContext->mServiceTxtEntry)) - { - // Set error to CHIP_NO_ERROR to signal that there was at least one service found in the cache - error = CHIP_NO_ERROR; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(serviceContext)); - } - else - { - Platform::Delete(serviceContext); - } - } - } - } - } - return error; -} - -CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq) -{ - const otSrpServerHost * host = nullptr; - const otSrpServerService * service = nullptr; - CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; - - while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) - { - while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) - { - if ((false == otSrpServerServiceIsDeleted(service)) && - (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName))) && - (0 == strncmp(otSrpServerServiceGetInstanceName(service), mdnsReq->mName, strlen(mdnsReq->mName)))) - { - error = FromSrpCacheToMdnsData(service, host, mdnsReq, context->mMdnsService, context->mServiceTxtEntry); - if (error == CHIP_NO_ERROR) - { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(context)); - } - break; - } - } - - if (error == CHIP_NO_ERROR) - { - break; - } - } - - return error; -} - -CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, - const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, - DnsServiceTxtEntries & serviceTxtEntries) +CHIP_ERROR ChipDnssdRemoveServices() { - const char * tmpName; - const uint8_t * txtStringPtr; - size_t substringSize; - uint8_t addrNum = 0; - uint16_t txtDataLen; - const otIp6Address * ip6AddrPtr = otSrpServerHostGetAddresses(host, &addrNum); - - if (mdnsQueryReq != nullptr) - { - Platform::CopyString(mdnsService.mName, sizeof(mdnsService.mName), mdnsQueryReq->mName); - Platform::CopyString(mdnsService.mType, sizeof(mdnsService.mType), mdnsQueryReq->mType); - mdnsService.mProtocol = mdnsQueryReq->mProtocol; - } - else + if (ConnectivityMgr().IsWiFiStationConnected()) { - tmpName = otSrpServerServiceGetInstanceName(service); - // Extract from the .... the part - size_t substringSize = strchr(tmpName, '.') - tmpName; - if (substringSize >= ArraySize(mdnsService.mName)) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - Platform::CopyString(mdnsService.mName, substringSize + 1, tmpName); - - // Extract from the .... the part. - tmpName = tmpName + substringSize + 1; - substringSize = strchr(tmpName, '.') - tmpName; - if (substringSize >= ArraySize(mdnsService.mType)) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - Platform::CopyString(mdnsService.mType, substringSize + 1, tmpName); - - // Extract from the .... the part. - tmpName = tmpName + substringSize + 1; - substringSize = strchr(tmpName, '.') - tmpName; - if (substringSize >= (chip::Dnssd::kDnssdProtocolTextMaxSize + 1)) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - if (strncmp(tmpName, "_udp", substringSize) == 0) - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; - } - else if (strncmp(tmpName, "_tcp", substringSize) == 0) - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; - } - else - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; - } + ReturnErrorOnFailure(NxpChipDnssdRemoveServices()); } - - // Extract from the .. the part. - tmpName = otSrpServerHostGetFullName(host); - substringSize = strchr(tmpName, '.') - tmpName; - if (substringSize >= ArraySize(mdnsService.mHostName)) + else if (ConnectivityMgr().IsThreadProvisioned()) { - return CHIP_ERROR_INVALID_ARGUMENT; + ReturnErrorOnFailure(OpenThreadDnssdRemoveServices()); } - Platform::CopyString(mdnsService.mHostName, substringSize + 1, tmpName); - mdnsService.mPort = otSrpServerServiceGetPort(service); - - // All SRP cache hits come from the Thread Netif - mdnsService.mInterface = ConnectivityManagerImpl().GetThreadInterface(); - - mdnsService.mAddressType = Inet::IPAddressType::kIPv6; - mdnsService.mAddress = std::optional(ToIPAddress(*ip6AddrPtr)); - - // Extract TXT record SRP service - txtStringPtr = otSrpServerServiceGetTxtData(service, &txtDataLen); - if (txtDataLen != 0) - { - otDnsTxtEntryIterator iterator; - otDnsInitTxtEntryIterator(&iterator, txtStringPtr, txtDataLen); - - otDnsTxtEntry txtEntry; - chip::FixedBufferAllocator alloc(serviceTxtEntries.mBuffer); - - uint8_t entryIndex = 0; - while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) - { - if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) - continue; - - serviceTxtEntries.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); - serviceTxtEntries.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); - serviceTxtEntries.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; - entryIndex++; - } - - ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); - - mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; - mdnsService.mTextEntrySize = entryIndex; - } - else - { - mdnsService.mTextEntrySize = 0; - } - - mdnsService.mSubTypes = nullptr; - mdnsService.mSubTypeSize = 0; return CHIP_NO_ERROR; } -static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType) +CHIP_ERROR ChipDnssdFinalizeServiceUpdate() { - char protocol[chip::Dnssd::kDnssdProtocolTextMaxSize + 1]; - const char * protocolSubstringStart; - size_t substringSize; - - // Extract from the . the part. - substringSize = strchr(aServiceType, '.') - aServiceType; - if (substringSize >= ArraySize(mdnsService.mType)) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - Platform::CopyString(mdnsService.mType, ArraySize(mdnsService.mType), aServiceType); - - // Extract from the .. the . part. - protocolSubstringStart = aServiceType + substringSize; - - // Check that the protocolSubstringStart starts wit a '.' to be sure we are in the right place - if (strchr(protocolSubstringStart, '.') == nullptr) + if (ConnectivityMgr().IsWiFiStationConnected()) { - return CHIP_ERROR_INVALID_ARGUMENT; + ReturnErrorOnFailure(NxpChipDnssdFinalizeServiceUpdate()); } - - // Jump over '.' in protocolSubstringStart and substract the string terminator from the size - substringSize = strlen(++protocolSubstringStart) - 1; - if (substringSize >= ArraySize(protocol)) + else if (ConnectivityMgr().IsThreadProvisioned()) { - return CHIP_ERROR_INVALID_ARGUMENT; + ReturnErrorOnFailure(OpenThreadDnssdFinalizeServiceUpdate()); } - Platform::CopyString(protocol, ArraySize(protocol), protocolSubstringStart); - - if (strncmp(protocol, "_udp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; - } - else if (strncmp(protocol, "_tcp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; - } - else - { - mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; - } - return CHIP_NO_ERROR; } -static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult) +CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { - CHIP_ERROR error; - - // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache - VerifyOrReturn(aResult->mTtl > 0); - - mDnsQueryCtx * tmpContext = Platform::New(mBrowseContext->matterCtx, mBrowseContext->mDnsBrowseCallback); - VerifyOrReturn(tmpContext != nullptr); - - Platform::CopyString(tmpContext->mMdnsService.mName, sizeof(tmpContext->mMdnsService.mName), aResult->mServiceInstance); - error = FromServiceTypeToMdnsData(tmpContext->mMdnsService, aResult->mServiceType); - - if (CHIP_NO_ERROR == error) + if (ConnectivityMgr().IsWiFiStationConnected()) //|| ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey)) { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(tmpContext)); + ReturnErrorOnFailure(NxpChipDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier)); } - else + else if (ConnectivityMgr().IsThreadProvisioned()) { - Platform::Delete(tmpContext); + ReturnErrorOnFailure(OpenThreadDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier)); } -} - -static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult) -{ - CHIP_ERROR error; - - // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache - VerifyOrReturn(aResult->mTtl > 0); - VerifyOrReturn(mResolveContext != nullptr); - - error = FromServiceTypeToMdnsData(mResolveContext->mMdnsService, aResult->mServiceType); - mResolveContext->error = error; - - if (CHIP_NO_ERROR == error) - { - Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), - aResult->mServiceInstance); - Platform::CopyString(mResolveContext->mMdnsService.mHostName, sizeof(mResolveContext->mMdnsService.mHostName), - aResult->mHostName); - - mResolveContext->mMdnsService.mPort = aResult->mPort; - mResolveContext->mMdnsService.mTtlSeconds = aResult->mTtl; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchTxtResolve, reinterpret_cast(mResolveContext)); - } - else - { - HandleResolveCleanup(*mResolveContext, kResolveStepSrv); - } -} - -static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult) -{ - bool bSendDispatch = true; - - // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache - VerifyOrReturn(aResult->mTtl > 0); - - VerifyOrReturn(mResolveContext != nullptr); - - // Check if TXT record was included in the response. - if (aResult->mTxtDataLength != 0) - { - otDnsTxtEntryIterator iterator; - otDnsInitTxtEntryIterator(&iterator, aResult->mTxtData, aResult->mTxtDataLength); - - otDnsTxtEntry txtEntry; - chip::FixedBufferAllocator alloc(mResolveContext->mServiceTxtEntry.mBuffer); - - uint8_t entryIndex = 0; - while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) - { - if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) - continue; - - mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); - mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); - mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; - entryIndex++; - } - - if (alloc.AnyAllocFailed()) - { - bSendDispatch = false; - } - else - { - mResolveContext->mMdnsService.mTextEntries = mResolveContext->mServiceTxtEntry.mTxtEntries; - mResolveContext->mMdnsService.mTextEntrySize = entryIndex; - } - } - else - { - mResolveContext->mMdnsService.mTextEntrySize = 0; - } - - if (bSendDispatch) - { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchAddressResolve, reinterpret_cast(mResolveContext)); - } - else - { - HandleResolveCleanup(*mResolveContext, kResolveStepTxt); - } -} - -static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult) -{ - // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache - VerifyOrReturn((aResult->mAddressesLength > 0) && (aResult->mAddresses[0].mTtl > 0)); - - VerifyOrReturn(mResolveContext != nullptr); - - mResolveContext->mMdnsService.mAddressType = Inet::IPAddressType::kIPv6; - mResolveContext->mMdnsService.mAddress = std::optional(ToIPAddress(aResult->mAddresses[0].mAddress)); - - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(mResolveContext)); -} - -static void DispatchBrowseEmpty(intptr_t context) -{ - auto * browseContext = reinterpret_cast(context); - browseContext->mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error); - Platform::Delete(browseContext); - mBrowseContext = nullptr; - bBrowseInProgress = false; + return CHIP_NO_ERROR; } -static void DispatchBrowse(intptr_t context) +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) { - auto * browseContext = reinterpret_cast(context); - browseContext->mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error); - Platform::Delete(browseContext); + return NxpChipDnssdStopBrowse(browseIdentifier); } -static void DispatchTxtResolve(intptr_t context) +CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context) { - mDnsQueryCtx * resolveContext = reinterpret_cast(context); - otError error; - - // Stop SRV resolver before starting TXT one, ignore error as it will only happen if mMDS module is not initialized - otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mSrvInfo); - - resolveContext->mTxtInfo.mServiceInstance = resolveContext->mMdnsService.mName; - resolveContext->mTxtInfo.mServiceType = resolveContext->mServiceType; - resolveContext->mTxtInfo.mCallback = OtTxtCallback; - resolveContext->mTxtInfo.mInfraIfIndex = mNetifIndex; - - error = otMdnsStartTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); - if (error != OT_ERROR_NONE) + if (ConnectivityMgr().IsWiFiStationConnected()) //|| ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey)) { - resolveContext->error = MapOpenThreadError(error); - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); + ReturnErrorOnFailure(NxpChipDnssdResolve(service, interface, callback, context)); } -} - -static void DispatchAddressResolve(intptr_t context) -{ - otError error; - mDnsQueryCtx * resolveContext = reinterpret_cast(context); - // Stop TXT resolver before starting address one, ignore error as it will only happen if mMDS module is not initialized - otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); - - resolveContext->mAddrInfo.mCallback = OtAddressCallback; - resolveContext->mAddrInfo.mHostName = resolveContext->mMdnsService.mHostName; - resolveContext->mAddrInfo.mInfraIfIndex = mNetifIndex; - - error = otMdnsStartIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); - if (error != OT_ERROR_NONE) + else if (ConnectivityMgr().IsThreadProvisioned()) { - resolveContext->error = MapOpenThreadError(error); - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); + ReturnErrorOnFailure(OpenThreadDnssdResolve(service, interface, callback, context)); } -} -static void DispatchResolve(intptr_t context) -{ - mDnsQueryCtx * resolveContext = reinterpret_cast(context); - Dnssd::DnssdService & service = resolveContext->mMdnsService; - Span ipAddrs; - - // Stop Address resolver, we have finished resolving the service - otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); - - if (service.mAddress.has_value()) - { - ipAddrs = Span(&*service.mAddress, 1); - } - - // Signal that the context will be freed and that the resolve operation is stopped because Matter will - // try do stop it again on the mDnsResolveCallback - mResolveContext = nullptr; - - resolveContext->mDnsResolveCallback(resolveContext->matterCtx, &service, ipAddrs, resolveContext->error); - Platform::Delete(resolveContext); + return CHIP_NO_ERROR; } -static void DispatchResolveError(intptr_t context) +void ChipDnssdResolveNoLongerNeeded(const char * instanceName) { - mDnsQueryCtx * resolveContext = reinterpret_cast(context); - Span ipAddrs; - - // Signal that the context will be freed and that the resolve operation is stopped because Matter will - // try do stop it again on the mDnsResolveCallback - mResolveContext = nullptr; - - resolveContext->mDnsResolveCallback(resolveContext->matterCtx, nullptr, ipAddrs, resolveContext->error); - Platform::Delete(resolveContext); + NxpChipDnssdResolveNoLongerNeeded(instanceName); } -void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType) +CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface) { - switch (stepType) - { - case kResolveStepSrv: - otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mSrvInfo); - break; - case kResolveStepTxt: - otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mTxtInfo); - break; - case kResolveStepIpAddr: - otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mAddrInfo); - break; - } - - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(&resolveContext)); + return CHIP_ERROR_NOT_IMPLEMENTED; } } // namespace Dnssd diff --git a/src/platform/nxp/common/DnssdImplBr.cpp b/src/platform/nxp/common/DnssdImplBr.cpp new file mode 100644 index 00000000000000..6b84f1f258d8be --- /dev/null +++ b/src/platform/nxp/common/DnssdImplBr.cpp @@ -0,0 +1,939 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright 2024 NXP + * + * 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 "lib/dnssd/platform/Dnssd.h" +#include +#include +#include +#include +#include + +#include + +#include +#include + +using namespace ::chip::DeviceLayer; +using namespace chip::DeviceLayer::Internal; + +namespace chip { +namespace Dnssd { + +#define USE_MDNS_NEXT_SERVICE_API 1 + +// Support both operational and commissionable discovery, so buffers sizes must be worst case. +static constexpr uint8_t kMaxMdnsServiceTxtEntriesNumber = + std::max(Dnssd::CommissionAdvertisingParameters::kTxtMaxNumber, Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber); +static constexpr size_t kTotalMdnsServiceTxtValueSize = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalValueSize, + Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize); +static constexpr size_t kTotalMdnsServiceTxtKeySize = + std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalKeySize, Dnssd::OperationalAdvertisingParameters::kTxtTotalKeySize); + +static constexpr size_t kTotalMdnsServiceTxtBufferSize = + kTotalMdnsServiceTxtKeySize + kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtValueSize; + +// For each fabric we can register one _matter._tcp and one _matterc._udp service +static constexpr uint32_t kServiceListSize = CHIP_CONFIG_MAX_FABRICS * 2; + +static const char * GetProtocolString(DnssdServiceProtocol protocol) +{ + return protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp"; +} + +struct DnsServiceTxtEntries +{ + uint8_t mBuffer[kTotalMdnsServiceTxtBufferSize]; + Dnssd::TextEntry mTxtEntries[kMaxMdnsServiceTxtEntriesNumber]; +}; + +struct mDnsQueryCtx +{ + void * matterCtx; + chip::Dnssd::DnssdService mMdnsService; + DnsServiceTxtEntries mServiceTxtEntry; + char mServiceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1]; + CHIP_ERROR error; + union + { + otMdnsBrowser mBrowseInfo; + otMdnsSrvResolver mSrvInfo; + otMdnsTxtResolver mTxtInfo; + otMdnsAddressResolver mAddrInfo; + }; + union + { + DnsBrowseCallback mDnsBrowseCallback; + DnsResolveCallback mDnsResolveCallback; + }; + + mDnsQueryCtx(void * context, DnsBrowseCallback aBrowseCallback) + { + matterCtx = context; + mDnsBrowseCallback = aBrowseCallback; + error = CHIP_NO_ERROR; + } + mDnsQueryCtx(void * context, DnsResolveCallback aResolveCallback) + { + matterCtx = context; + mDnsResolveCallback = aResolveCallback; + error = CHIP_NO_ERROR; + } +}; + +enum ResolveStep : uint8_t +{ + kResolveStepSrv = 0, + kResolveStepTxt, + kResolveStepIpAddr, +}; + +static const char * GetProtocolString(DnssdServiceProtocol protocol); + +static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult); +static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult); +static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult); +static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult); + +static void DispatchBrowseEmpty(intptr_t context); +static void DispatchBrowse(intptr_t context); + +static void DispatchTxtResolve(intptr_t context); +static void DispatchAddressResolve(intptr_t context); +static void DispatchResolve(intptr_t context); +static void DispatchResolveError(intptr_t context); + +static void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType); + +static CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq); +static CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context); +static CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, + const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, + DnsServiceTxtEntries & serviceTxtEntries); + +static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType); + +static bool bBrowseInProgress = false; +// ID 0 is reserved for host +static uint32_t mRegisterServiceId = 1; +static uint8_t mNetifIndex = 0; + +// Matter currently only supports one browse and resolve operation at a time so there is no need to create a list +// If the Matter implementation evolves in the future this functionality can be extended to a list. +static mDnsQueryCtx * mBrowseContext = nullptr; +static mDnsQueryCtx * mResolveContext = nullptr; + +#if USE_MDNS_NEXT_SERVICE_API +static otMdnsService * mServiceList[kServiceListSize]; +static uint32_t mServiceListFreeIndex; +#endif + +CHIP_ERROR NxpChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + struct netif * extNetif = (ConnectivityManagerImpl().GetExternalInterface()).GetPlatformInterface(); + + // Don't try to do anything until the mDNS server is started + VerifyOrExit(otMdnsIsEnabled(thrInstancePtr), error = CHIP_ERROR_INCORRECT_STATE); + + mNetifIndex = netif_get_index(extNetif); + +exit: + initCallback(context, error); + return error; +} + +void NxpChipDnssdShutdown() +{ + otMdnsSetEnabled(ThreadStackMgrImpl().OTInstance(), false, 0); +} +#if USE_MDNS_NEXT_SERVICE_API +CHIP_ERROR NxpChipDnssdRemoveServices() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + otMdnsIterator * iterator = nullptr; + ChipError error = CHIP_NO_ERROR; + otError otError = OT_ERROR_NONE; + otMdnsEntryState state; + + const char * hostName = ConnectivityManagerImpl().GetHostName(); + + iterator = otMdnsAllocateIterator(thrInstancePtr); + VerifyOrExit(iterator != nullptr, error = CHIP_ERROR_NO_MEMORY); + + mServiceListFreeIndex = 0; + + while (mServiceListFreeIndex <= kServiceListSize) + { + // allocate memory for new entry if the entry is not allready allocated from previous iteration + if (mServiceList[mServiceListFreeIndex] == nullptr) + { + mServiceList[mServiceListFreeIndex] = static_cast(Platform::MemoryAlloc(sizeof(otMdnsService))); + VerifyOrExit(mServiceList[mServiceListFreeIndex] != nullptr, error = CHIP_ERROR_NO_MEMORY); + } + + otError = otMdnsGetNextService(thrInstancePtr, iterator, mServiceList[mServiceListFreeIndex], &state); + if (otError == OT_ERROR_NOT_FOUND) + { + Platform::MemoryFree(mServiceList[mServiceListFreeIndex]); + mServiceList[mServiceListFreeIndex] = nullptr; + break; + } + + if ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mHostName, hostName)) && + ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matter._tcp")) || + (0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matterc._udp")))) + { + mServiceListFreeIndex++; + } + } + +exit: + if (iterator != nullptr) + { + otMdnsFreeIterator(thrInstancePtr, iterator); + } + return error; +} +#else +CHIP_ERROR NxpChipDnssdRemoveServices() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + + otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); + + otServiceData.mServiceType = "_matter._tcp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); + otServiceData.mServiceType = "_matterc._udp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); + + return CHIP_NO_ERROR; +} +#endif + +CHIP_ERROR NxpChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) +{ + ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + uint32_t txtBufferOffset = 0; + otError otErr = OT_ERROR_NONE; + otMdnsService otServiceData = { 0 }; + +#if USE_MDNS_NEXT_SERVICE_API + bool bRegisterService = true; +#endif + + char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1] = ""; + snprintf(serviceType, sizeof(serviceType), "%s.%s", service->mType, GetProtocolString(service->mProtocol)); + + // secure space for the raw TXT data in the worst-case scenario relevant for Matter: + // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data + uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize] = { 0 }; + + // Don't try to do anything until the mDNS server is started + VerifyOrReturnValue(otMdnsIsEnabled(thrInstancePtr), CHIP_NO_ERROR); + + // Create TXT Data as one string from multiple key entries + for (uint32_t i = 0; i < service->mTextEntrySize; i++) + { + uint32_t keySize = strlen(service->mTextEntries[i].mKey); + // add TXT entry len, + 1 is for '=' + *(txtBuffer + txtBufferOffset++) = keySize + service->mTextEntries[i].mDataSize + 1; + + // add TXT entry key + memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mKey, keySize); + txtBufferOffset += keySize; + + // add TXT entry value if pointer is not null, if pointer is null it means we have bool value + if (service->mTextEntries[i].mData) + { + *(txtBuffer + txtBufferOffset++) = '='; + memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mData, service->mTextEntries[i].mDataSize); + txtBufferOffset += service->mTextEntries[i].mDataSize; + } + } + +#if USE_MDNS_NEXT_SERVICE_API + for (uint32_t i = 0; i < mServiceListFreeIndex; i++) + { + if ((0 == strcmp(mServiceList[i]->mHostName, service->mHostName)) && + (0 == strcmp(mServiceList[i]->mServiceInstance, service->mName)) && + (0 == strcmp(mServiceList[i]->mServiceType, serviceType))) + { + if ((mServiceList[i]->mTxtDataLength == txtBufferOffset) && + (0 == memcmp(txtBuffer, mServiceList[i]->mTxtData, txtBufferOffset))) + { + // In this case the service is + bRegisterService = false; + } + Platform::MemoryFree(mServiceList[i]); + if (i < --mServiceListFreeIndex) + { + // move last element in place of the removed one + mServiceList[i] = mServiceList[mServiceListFreeIndex]; + mServiceList[mServiceListFreeIndex] = nullptr; + } + else + { + mServiceList[i] = nullptr; + } + break; + } + } +#endif + if (bRegisterService) + { + if (strcmp(service->mHostName, "") != 0) + { + otServiceData.mHostName = service->mHostName; + } + + otServiceData.mServiceInstance = service->mName; + otServiceData.mServiceType = serviceType; + otServiceData.mSubTypeLabels = service->mSubTypes; + otServiceData.mSubTypeLabelsLength = service->mSubTypeSize; + otServiceData.mPort = service->mPort; + otServiceData.mTtl = service->mTtlSeconds; + otServiceData.mTxtData = txtBuffer; + otServiceData.mTxtDataLength = txtBufferOffset; + + otErr = otMdnsRegisterService(thrInstancePtr, &otServiceData, mRegisterServiceId++, NULL); + } + + return MapOpenThreadError(otErr); +} + +#if USE_MDNS_NEXT_SERVICE_API +CHIP_ERROR NxpChipDnssdFinalizeServiceUpdate() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + for (uint32_t i = 0; i < mServiceListFreeIndex; i++) + { + if (mServiceList[i] != nullptr) + { + otMdnsUnregisterService(thrInstancePtr, mServiceList[i]); + Platform::MemoryFree(mServiceList[i]); + mServiceList[i] = nullptr; + } + } + + mServiceListFreeIndex = 0; + return CHIP_NO_ERROR; +} + +#else +CHIP_ERROR NxpChipDnssdFinalizeServiceUpdate() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + + otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); + + otServiceData.mServiceType = "_matter._tcp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); + otServiceData.mServiceType = "_matterc._udp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); + + return CHIP_NO_ERROR; +} +#endif + +CHIP_ERROR NxpChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, + Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) +{ + *browseIdentifier = reinterpret_cast(nullptr); + CHIP_ERROR error = CHIP_NO_ERROR; + CHIP_ERROR srpBrowseError = CHIP_NO_ERROR; + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + if (type == nullptr || callback == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + mBrowseContext = Platform::New(context, callback); + VerifyOrReturnError(mBrowseContext != nullptr, CHIP_ERROR_NO_MEMORY); + + // First try to browse the service in the SRP cache + snprintf(mBrowseContext->mServiceType, sizeof(mBrowseContext->mServiceType), "%s.%s", type, GetProtocolString(protocol)); + // After browsing in the SRP cache we will continue with regular mDNS browse + srpBrowseError = BrowseBySrp(thrInstancePtr, mBrowseContext->mServiceType, mBrowseContext); + + // Proceed to generate a mDNS query + mBrowseContext->mBrowseInfo.mServiceType = mBrowseContext->mServiceType; + mBrowseContext->mBrowseInfo.mSubTypeLabel = nullptr; + mBrowseContext->mBrowseInfo.mInfraIfIndex = mNetifIndex; + mBrowseContext->mBrowseInfo.mCallback = OtBrowseCallback; + + error = MapOpenThreadError(otMdnsStartBrowser(thrInstancePtr, &mBrowseContext->mBrowseInfo)); + + if (CHIP_NO_ERROR == error) + { + bBrowseInProgress = true; + *browseIdentifier = reinterpret_cast(mBrowseContext); + } + else + { + if (srpBrowseError == CHIP_NO_ERROR) + { + // In this case, we need to send a final browse indication to signal the Matter App that there are no more + // browse results coming + mBrowseContext->error = error; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(mBrowseContext)); + } + else + { + Platform::Delete(mBrowseContext); + mBrowseContext = nullptr; + } + } + return error; +} + +CHIP_ERROR NxpChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + mDnsQueryCtx * browseContext = reinterpret_cast(browseIdentifier); + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otError error = OT_ERROR_INVALID_ARGS; + + // browseContext is only valid when bBrowseInProgress is true. The Matter stack can call this function even with a browseContext + // that has been freed in DispatchBrowseEmpty. + if ((true == bBrowseInProgress) && (browseContext)) + { + browseContext->error = MapOpenThreadError(otMdnsStopBrowser(thrInstancePtr, &browseContext->mBrowseInfo)); + + // browse context will be freed in DispatchBrowseEmpty + DispatchBrowseEmpty(reinterpret_cast(browseContext)); + } + return MapOpenThreadError(error); +} + +CHIP_ERROR NxpChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context) +{ + ChipError error = CHIP_ERROR_NOT_FOUND; + + if (browseResult == nullptr || callback == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + mResolveContext = Platform::New(context, callback); + VerifyOrReturnError(mResolveContext != nullptr, CHIP_ERROR_NO_MEMORY); + + // First try to find the service in the SRP cache, use default.service.arpa as domain name + snprintf(mResolveContext->mServiceType, sizeof(mResolveContext->mServiceType), "%s.%s", browseResult->mType, + GetProtocolString(browseResult->mProtocol)); + + error = ResolveBySrp(thrInstancePtr, mResolveContext->mServiceType, mResolveContext, browseResult); + // If the SRP cache returns not found, proceed to generate a MDNS query + if (CHIP_ERROR_NOT_FOUND == error) + { + // The otMdnsSrvResolver structure contains only pointers to instance name and service type strings + // Use the memory from mMdnsService.mName to store the instance name string we are looking for + Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), browseResult->mName); + + mResolveContext->mSrvInfo.mInfraIfIndex = mNetifIndex; + mResolveContext->mSrvInfo.mCallback = OtServiceCallback; + mResolveContext->mSrvInfo.mServiceInstance = mResolveContext->mMdnsService.mName; + mResolveContext->mSrvInfo.mServiceType = mResolveContext->mServiceType; + + return MapOpenThreadError(otMdnsStartSrvResolver(thrInstancePtr, &mResolveContext->mSrvInfo)); + } + else + { + return error; + } +} +void NxpChipDnssdResolveNoLongerNeeded(const char * instanceName) +{ + if (mResolveContext != nullptr) + { + if (strcmp(instanceName, mResolveContext->mMdnsService.mName) == 0) + { + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &mResolveContext->mSrvInfo); + + Platform::Delete(mResolveContext); + mResolveContext = nullptr; + } + } +} + +CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context) +{ + const otSrpServerHost * host = nullptr; + const otSrpServerService * service = nullptr; + CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; + + while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) + { + while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) + { + if ((false == otSrpServerServiceIsDeleted(service)) && + (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName)))) + { + mDnsQueryCtx * serviceContext = Platform::New(context->matterCtx, context->mDnsBrowseCallback); + if (serviceContext != nullptr) + { + if (CHIP_NO_ERROR == + FromSrpCacheToMdnsData(service, host, nullptr, serviceContext->mMdnsService, + serviceContext->mServiceTxtEntry)) + { + // Set error to CHIP_NO_ERROR to signal that there was at least one service found in the cache + error = CHIP_NO_ERROR; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(serviceContext)); + } + else + { + Platform::Delete(serviceContext); + } + } + } + } + } + return error; +} + +CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq) +{ + const otSrpServerHost * host = nullptr; + const otSrpServerService * service = nullptr; + CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; + + while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) + { + while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) + { + if ((false == otSrpServerServiceIsDeleted(service)) && + (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName))) && + (0 == strncmp(otSrpServerServiceGetInstanceName(service), mdnsReq->mName, strlen(mdnsReq->mName)))) + { + error = FromSrpCacheToMdnsData(service, host, mdnsReq, context->mMdnsService, context->mServiceTxtEntry); + if (error == CHIP_NO_ERROR) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(context)); + } + break; + } + } + + if (error == CHIP_NO_ERROR) + { + break; + } + } + + return error; +} + +CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, + const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, + DnsServiceTxtEntries & serviceTxtEntries) +{ + const char * tmpName; + const uint8_t * txtStringPtr; + size_t substringSize; + uint8_t addrNum = 0; + uint16_t txtDataLen; + const otIp6Address * ip6AddrPtr = otSrpServerHostGetAddresses(host, &addrNum); + + if (mdnsQueryReq != nullptr) + { + Platform::CopyString(mdnsService.mName, sizeof(mdnsService.mName), mdnsQueryReq->mName); + Platform::CopyString(mdnsService.mType, sizeof(mdnsService.mType), mdnsQueryReq->mType); + mdnsService.mProtocol = mdnsQueryReq->mProtocol; + } + else + { + tmpName = otSrpServerServiceGetInstanceName(service); + // Extract from the .... the part + size_t substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mName)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mName, substringSize + 1, tmpName); + + // Extract from the .... the part. + tmpName = tmpName + substringSize + 1; + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mType)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mType, substringSize + 1, tmpName); + + // Extract from the .... the part. + tmpName = tmpName + substringSize + 1; + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= (chip::Dnssd::kDnssdProtocolTextMaxSize + 1)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (strncmp(tmpName, "_udp", substringSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; + } + else if (strncmp(tmpName, "_tcp", substringSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; + } + else + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; + } + } + + // Extract from the .. the part. + tmpName = otSrpServerHostGetFullName(host); + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mHostName)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mHostName, substringSize + 1, tmpName); + mdnsService.mPort = otSrpServerServiceGetPort(service); + + // All SRP cache hits come from the Thread Netif + mdnsService.mInterface = ConnectivityManagerImpl().GetThreadInterface(); + + mdnsService.mAddressType = Inet::IPAddressType::kIPv6; + mdnsService.mAddress = std::optional(ToIPAddress(*ip6AddrPtr)); + + // Extract TXT record SRP service + txtStringPtr = otSrpServerServiceGetTxtData(service, &txtDataLen); + if (txtDataLen != 0) + { + otDnsTxtEntryIterator iterator; + otDnsInitTxtEntryIterator(&iterator, txtStringPtr, txtDataLen); + + otDnsTxtEntry txtEntry; + chip::FixedBufferAllocator alloc(serviceTxtEntries.mBuffer); + + uint8_t entryIndex = 0; + while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) + { + if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) + continue; + + serviceTxtEntries.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); + serviceTxtEntries.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); + serviceTxtEntries.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; + entryIndex++; + } + + ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); + + mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; + mdnsService.mTextEntrySize = entryIndex; + } + else + { + mdnsService.mTextEntrySize = 0; + } + + mdnsService.mSubTypes = nullptr; + mdnsService.mSubTypeSize = 0; + + return CHIP_NO_ERROR; +} + +static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType) +{ + char protocol[chip::Dnssd::kDnssdProtocolTextMaxSize + 1]; + const char * protocolSubstringStart; + size_t substringSize; + + // Extract from the . the part. + substringSize = strchr(aServiceType, '.') - aServiceType; + if (substringSize >= ArraySize(mdnsService.mType)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mType, ArraySize(mdnsService.mType), aServiceType); + + // Extract from the .. the . part. + protocolSubstringStart = aServiceType + substringSize; + + // Check that the protocolSubstringStart starts wit a '.' to be sure we are in the right place + if (strchr(protocolSubstringStart, '.') == nullptr) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Jump over '.' in protocolSubstringStart and substract the string terminator from the size + substringSize = strlen(++protocolSubstringStart) - 1; + if (substringSize >= ArraySize(protocol)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(protocol, ArraySize(protocol), protocolSubstringStart); + + if (strncmp(protocol, "_udp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; + } + else if (strncmp(protocol, "_tcp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; + } + else + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; + } + + // All mDNS replies come from the External Netif + mdnsService.mInterface = ConnectivityManagerImpl().GetExternalInterface(); + + return CHIP_NO_ERROR; +} + +static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult) +{ + CHIP_ERROR error; + + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); + + mDnsQueryCtx * tmpContext = Platform::New(mBrowseContext->matterCtx, mBrowseContext->mDnsBrowseCallback); + VerifyOrReturn(tmpContext != nullptr); + + Platform::CopyString(tmpContext->mMdnsService.mName, sizeof(tmpContext->mMdnsService.mName), aResult->mServiceInstance); + error = FromServiceTypeToMdnsData(tmpContext->mMdnsService, aResult->mServiceType); + + if (CHIP_NO_ERROR == error) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(tmpContext)); + } + else + { + Platform::Delete(tmpContext); + } +} + +static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult) +{ + CHIP_ERROR error; + + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); + + VerifyOrReturn(mResolveContext != nullptr); + + error = FromServiceTypeToMdnsData(mResolveContext->mMdnsService, aResult->mServiceType); + mResolveContext->error = error; + + if (CHIP_NO_ERROR == error) + { + Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), + aResult->mServiceInstance); + Platform::CopyString(mResolveContext->mMdnsService.mHostName, sizeof(mResolveContext->mMdnsService.mHostName), + aResult->mHostName); + + mResolveContext->mMdnsService.mPort = aResult->mPort; + mResolveContext->mMdnsService.mTtlSeconds = aResult->mTtl; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchTxtResolve, reinterpret_cast(mResolveContext)); + } + else + { + HandleResolveCleanup(*mResolveContext, kResolveStepSrv); + } +} + +static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult) +{ + bool bSendDispatch = true; + + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); + + VerifyOrReturn(mResolveContext != nullptr); + + // Check if TXT record was included in the response. + if (aResult->mTxtDataLength != 0) + { + otDnsTxtEntryIterator iterator; + otDnsInitTxtEntryIterator(&iterator, aResult->mTxtData, aResult->mTxtDataLength); + + otDnsTxtEntry txtEntry; + chip::FixedBufferAllocator alloc(mResolveContext->mServiceTxtEntry.mBuffer); + + uint8_t entryIndex = 0; + while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) + { + if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) + continue; + + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; + entryIndex++; + } + + if (alloc.AnyAllocFailed()) + { + bSendDispatch = false; + } + else + { + mResolveContext->mMdnsService.mTextEntries = mResolveContext->mServiceTxtEntry.mTxtEntries; + mResolveContext->mMdnsService.mTextEntrySize = entryIndex; + } + } + else + { + mResolveContext->mMdnsService.mTextEntrySize = 0; + } + + if (bSendDispatch) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchAddressResolve, reinterpret_cast(mResolveContext)); + } + else + { + HandleResolveCleanup(*mResolveContext, kResolveStepTxt); + } +} + +static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult) +{ + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn((aResult->mAddressesLength > 0) && (aResult->mAddresses[0].mTtl > 0)); + + VerifyOrReturn(mResolveContext != nullptr); + + mResolveContext->mMdnsService.mAddressType = Inet::IPAddressType::kIPv6; + mResolveContext->mMdnsService.mAddress = std::optional(ToIPAddress(aResult->mAddresses[0].mAddress)); + + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(mResolveContext)); +} + +static void DispatchBrowseEmpty(intptr_t context) +{ + auto * browseContext = reinterpret_cast(context); + browseContext->mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error); + Platform::Delete(browseContext); + mBrowseContext = nullptr; + bBrowseInProgress = false; +} + +static void DispatchBrowse(intptr_t context) +{ + auto * browseContext = reinterpret_cast(context); + browseContext->mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error); + Platform::Delete(browseContext); +} + +static void DispatchTxtResolve(intptr_t context) +{ + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + otError error; + + // Stop SRV resolver before starting TXT one, ignore error as it will only happen if mMDS module is not initialized + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mSrvInfo); + + resolveContext->mTxtInfo.mServiceInstance = resolveContext->mMdnsService.mName; + resolveContext->mTxtInfo.mServiceType = resolveContext->mServiceType; + resolveContext->mTxtInfo.mCallback = OtTxtCallback; + resolveContext->mTxtInfo.mInfraIfIndex = mNetifIndex; + + error = otMdnsStartTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); + if (error != OT_ERROR_NONE) + { + resolveContext->error = MapOpenThreadError(error); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); + } +} + +static void DispatchAddressResolve(intptr_t context) +{ + otError error; + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + // Stop TXT resolver before starting address one, ignore error as it will only happen if mMDS module is not initialized + otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); + + resolveContext->mAddrInfo.mCallback = OtAddressCallback; + resolveContext->mAddrInfo.mHostName = resolveContext->mMdnsService.mHostName; + resolveContext->mAddrInfo.mInfraIfIndex = mNetifIndex; + + error = otMdnsStartIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); + if (error != OT_ERROR_NONE) + { + resolveContext->error = MapOpenThreadError(error); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); + } +} + +static void DispatchResolve(intptr_t context) +{ + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + Dnssd::DnssdService & service = resolveContext->mMdnsService; + Span ipAddrs; + + // Stop Address resolver, we have finished resolving the service + otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); + + if (service.mAddress.has_value()) + { + ipAddrs = Span(&*service.mAddress, 1); + } + + // Signal that the context will be freed and that the resolve operation is stopped because Matter will + // try do stop it again on the mDnsResolveCallback + mResolveContext = nullptr; + + resolveContext->mDnsResolveCallback(resolveContext->matterCtx, &service, ipAddrs, resolveContext->error); + Platform::Delete(resolveContext); +} + +static void DispatchResolveError(intptr_t context) +{ + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + Span ipAddrs; + + // Signal that the context will be freed and that the resolve operation is stopped because Matter will + // try do stop it again on the mDnsResolveCallback + mResolveContext = nullptr; + + resolveContext->mDnsResolveCallback(resolveContext->matterCtx, nullptr, ipAddrs, resolveContext->error); + Platform::Delete(resolveContext); +} + +void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType) +{ + switch (stepType) + { + case kResolveStepSrv: + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mSrvInfo); + break; + case kResolveStepTxt: + otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mTxtInfo); + break; + case kResolveStepIpAddr: + otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mAddrInfo); + break; + } + + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(&resolveContext)); +} + +} // namespace Dnssd +} // namespace chip diff --git a/src/platform/nxp/common/DnssdImplBr.h b/src/platform/nxp/common/DnssdImplBr.h new file mode 100644 index 00000000000000..970a2c675752b6 --- /dev/null +++ b/src/platform/nxp/common/DnssdImplBr.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright 2024 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * 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 Dnssd { + +CHIP_ERROR NxpChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context); + +void NxpChipDnssdShutdown(); + +CHIP_ERROR NxpChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context); + +CHIP_ERROR NxpChipDnssdRemoveServices(); + +CHIP_ERROR NxpChipDnssdFinalizeServiceUpdate(); + +CHIP_ERROR NxpChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier); + +CHIP_ERROR NxpChipDnssdStopBrowse(intptr_t browseIdentifier); + +CHIP_ERROR NxpChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context); + +void NxpChipDnssdResolveNoLongerNeeded(const char * instanceName); + +} // namespace Dnssd +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 447ef2905bb300..b17f22391c2a11 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -63,8 +63,8 @@ config("nxp_platform_config") { defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] } } - if (chip_enable_wifi && chip_enable_openthread) { - # Disable thread nwk commissioning instance on endpoint 0, when OTBR is enabled + # When OTBR is enabled Thread network commissioning cluster is enabled using chip_enable_secondary_nwk_if + if (chip_enable_wifi && chip_enable_openthread && !chip_enable_secondary_nwk_if) { defines += [ "_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" ] } } @@ -157,14 +157,29 @@ static_library("nxp_platform") { "../../../OpenThread/OpenThreadUtils.cpp", "../../common/ThreadStackManagerImpl.cpp", "../../common/ThreadStackManagerImpl.h", + "../../../OpenThread/GenericThreadBorderRouterDelegate.cpp", + "../../../OpenThread/GenericThreadBorderRouterDelegate.h", + # Temporary fix, to be revert once PR #34662 is merged, build issue when using GN check argument + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", ] - - deps += [ "${chip_root}/third_party/openthread:openthread" ] - public_deps += [ "${chip_root}/third_party/openthread:openthread-platform" ] + + deps += ["${chip_root}/src/app/common:ids",] + + if (!nxp_build_matter_standalone_lib) { + deps += [ "${chip_root}/third_party/openthread:openthread" ] + public_deps += [ "${chip_root}/third_party/openthread:openthread-platform" ] + } if (chip_mdns == "platform") { if (chip_enable_wifi) { - sources += [ "../../common/DnssdImpl.cpp" ] + sources += [ + "../../common/DnssdImpl.cpp", + "../../common/DnssdImplBr.cpp", + "../../common/DnssdImplBr.h", + "../../../OpenThread/DnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + ] } else { sources += [ "../../../OpenThread/DnssdImpl.cpp", diff --git a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp index c17e7df36c616c..fe8c6b012b4c3f 100644 --- a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp +++ b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp @@ -204,6 +204,7 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) otPlatLogInit(); otPlatRadioInit(); otPlatSetResetFunction(initiateResetInIdle); + otPlatRandomInit(); #endif #if CHIP_DEVICE_CONFIG_ENABLE_WPA diff --git a/src/platform/nxp/rt/rw61x/args.gni b/src/platform/nxp/rt/rw61x/args.gni index 5561196ea3a323..b9b34f2e7c3cbc 100644 --- a/src/platform/nxp/rt/rw61x/args.gni +++ b/src/platform/nxp/rt/rw61x/args.gni @@ -42,6 +42,8 @@ declare_args() { # if rw610_mbedtls_port_els_pkc is set to false software mbedtls is used instead rw610_mbedtls_port_els_pkc = true + + chip_enable_secondary_nwk_if = false } # TODO : Enable the OTA Requestor by default. From 0506b7b2d149d503843a496c192b5b3ab98809ef Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:51:16 +0200 Subject: [PATCH 05/18] [NXP][workflows] Only thermostat app support OTBR feature Signed-off-by: Martin Girardot --- .github/workflows/examples-nxp.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index fc929eff2601c0..e8e335997db24d 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -242,7 +242,6 @@ jobs: ./scripts/build/build_examples.py \ --target nxp-rw61x-freertos-all-clusters-wifi \ --target nxp-rw61x-freertos-all-clusters-thread \ - --target nxp-rw61x-freertos-all-clusters-thread-wifi \ --target nxp-rw61x-freertos-all-clusters-wifi-ota-cmake \ build \ --copy-artifacts-to out/artifacts \ @@ -265,7 +264,6 @@ jobs: ./scripts/build/build_examples.py \ --target nxp-rw61x-freertos-laundry-washer-wifi \ --target nxp-rw61x-freertos-laundry-washer-thread \ - --target nxp-rw61x-freertos-laundry-washer-thread-wifi \ build \ --copy-artifacts-to out/artifacts \ " From 658177b5271f298716a73c2fe2edd291d3d314cf Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 10:52:15 +0200 Subject: [PATCH 06/18] [NXP][doc] add OTBR guide Signed-off-by: Martin Girardot --- docs/guides/nxp/nxp_otbr_guide.md | 76 +++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 docs/guides/nxp/nxp_otbr_guide.md diff --git a/docs/guides/nxp/nxp_otbr_guide.md b/docs/guides/nxp/nxp_otbr_guide.md new file mode 100644 index 00000000000000..77bcb69ee528d5 --- /dev/null +++ b/docs/guides/nxp/nxp_otbr_guide.md @@ -0,0 +1,76 @@ +# Thread Border Router usage + +This document describes the use of the Thread Border router and secondary netwok interface for a Matter application + +
+ +- [Thread Border Router overwiew](#thread-border-router-overwiew) +- [Using the Thread Border Router Management cluster](#using-the-thread-border-router-management-cluster) +- [Using the Secondary Network commissioning interface](#using-the-secondary-network-commissioning-interface) +- [Using the Thread credential sharing mechanism](#using-the-thread-credential-sharing-mechanism) + +
+ + + +## Thread Border Router overwiew + +This section contains an overview of the Border Router architecture and describes the general use cases. + + + +## Using the Thread Border Router management cluster + +The Thread Border Router management cluster allows provisioning of the Thread interface using a Matter commissioner. + +After the device has been provisioned over WIFI the set active dataset command can be used to configure the Thread active dataset on the border router. Once the dataset is set successfully the Thread network interface will be enabled and the device will create a new PAN or join an existing one if already present. Note that this command cannot be used on a device that already has an active dataset configured. In this situation the set pending dataset command must be used instead. + +Before using the set active dataset command a fail-safe timer must be armed (recommend using a timeout of 120 seconds): + +``` +ubuntu@ubuntu:~$ ./chip-tool generalcommissioning arm-fail-safe timeout-seconds 1 node-id 0 +``` +Then an active dataset in HEX TLV format (the same type used to provision a Matter over Thread device using the `ble-thread` command) can be used to provision the Border Router. What the active dataset should be is outside the scope of this README but as an example one can be obtained from the OpenThread cli on an already provisioned device using the `dataset active -x` command. + +Note that the Thread Border Router management cluster has been set to endpoint 2 in the zap file. + +``` +ubuntu@ubuntu:~$ ./chip-tool threadborderroutermanagement set-active-dataset-request hex: node id 2 +``` + +If the active dataset command is successful, a commissioning complete command must be send to disarm the fail-safe timer and commit the configuration to non-volatile storage. + +``` +ubuntu@ubuntu:~$ ./chip-tool-19-jul generalcommissioning commissioning-complete node-id 0 +``` + +Note that this command cannot be used on a device that already has an active dataset configured. In this situation the set pending dataset command must be used instead. + +``` +ubuntu@ubuntu:~$ ./chip-tool threadborderroutermanagement set-pending-dataset-request hex: node id 2 +``` + +To read the active dataset of an already provisioned device, for example to make a joining Border Router use the same Thread network as an already configured one, the get active dataset command can be used: + +``` +ubuntu@ubuntu:~$ ./chip-tool-19-jul threadborderroutermanagement get-active-dataset-request node-id 2 +``` + + + +## Using the Secondary Network commissioning interface + +To use the secondary network commissioning interface over Thread the device must not be provisioned over WIFI. +The regular `ble-thread` pairing is used as for any other Matter over Thread device. The chip-tool will read all the endpoints of the device and discover Thread network commissioning cluster on endpoint 3 and use that to provision the device. As for any other Matter over Thread device a Thread Border Router is required in this case. + +``` +ubuntu@ubuntu:~$ ./chip-tool pairing ble-thread node-id hex: 20202021 3840 +``` + + + +## Using the Thread credential sharing mechanism + +The details about using the credential sharing mechanism are in the ot-nxp repo border router application [readme](https://github.com/NXP/ot-nxp/blob/v1.4.0-pvw1/examples/br/README-OTBR.md). See `Ephemeral Key functionality` section. + +Note that all OpenThread commands executed from then Matter CLI must have `otcli` prepended before the command. \ No newline at end of file From 6c8e99844e98ca15d872e164ed0f9356431b90db Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Mon, 3 Jun 2024 16:06:06 +0200 Subject: [PATCH 07/18] [NXP][platform][rw61x] Add support of boot reason Signed-off-by: Martin Girardot (cherry picked from commit d8f44419ea89d5ecec73fe8d82fdb30d444f49b3) --- src/platform/nxp/rt/rw61x/BUILD.gn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index b17f22391c2a11..c96a9f2e5e0e1a 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -34,7 +34,7 @@ source_set("nxp_ota") { } config("nxp_platform_config") { - defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"" ] + defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"", "CONFIG_BOOT_REASON_SDK_SUPPORT=1" ] include_dirs = [ ".", "../../common", @@ -67,6 +67,7 @@ config("nxp_platform_config") { if (chip_enable_wifi && chip_enable_openthread && !chip_enable_secondary_nwk_if) { defines += [ "_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" ] } + } static_library("nxp_platform") { From b26d91186cac676b7c85c6c1d3fcda01f2dc7486 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 14:44:31 +0200 Subject: [PATCH 08/18] [NXP] Adding wifi_connect module Signed-off-by: Martin Girardot --- .../all-clusters-app/nxp/rt/rw61x/BUILD.gn | 52 ++++-------------- .../laundry-washer-app/nxp/rt/rw61x/BUILD.gn | 53 ++++--------------- .../common/app_task/source/AppTaskBase.cpp | 2 +- .../common/wifi_connect/include/WifiConnect.h | 42 +++++++++++++++ .../wifi_connect/source/WifiConnect.cpp | 53 +++++++++++++++++++ examples/thermostat/nxp/rt/rw61x/BUILD.gn | 53 ++++--------------- 6 files changed, 129 insertions(+), 126 deletions(-) create mode 100644 examples/platform/nxp/common/wifi_connect/include/WifiConnect.h create mode 100644 examples/platform/nxp/common/wifi_connect/source/WifiConnect.cpp diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index b0e1c1c47a98ea..0e20d5510084fa 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -35,15 +35,11 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # Allows to start the tcp download test app - tcp_download = false - # Allows to start the wifi connect test app - wifi_connect = false - - # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. - wifi_ssid = "" - wifi_password = "" + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" # Setup discriminator as argument setup_discriminator = 3840 @@ -53,10 +49,6 @@ example_platform_dir = "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" common_example_dir = "${chip_root}/examples/platform/nxp/common" -if (tcp_download == true && wifi_connect == true) { - assert("Cannot enable tcp_download and wifi_connect at the same time!") -} - app_common_folder = "all-clusters-app/all-clusters-common" # Create here the SDK instance. @@ -213,42 +205,20 @@ rt_executable("all_cluster_app") { ] } - if (wifi_connect) { + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + defines += [ - "WIFI_CONNECT_TASK=1", - "WIFI_CONNECT=1", + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", ] - if (!chip_enable_matter_cli) { - assert(wifi_ssid != "" && wifi_password != "", - "WiFi SSID and password must be specified at build time!") - } - - if (wifi_ssid != "") { - defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] - } - - if (wifi_password != "") { - defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] - } - include_dirs += [ "${common_example_dir}/wifi_connect/include" ] sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] } - if (tcp_download) { - defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] - defines += [ - "WIFI_CONNECT=1", - "WIFI_SSID=\"${wifi_ssid}\"", - "WIFI_PASSWORD=\"${wifi_password}\"", - ] - - include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] - sources += - [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] - } - # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false # The would add to the build a dedicated application assert implementation. if (!sdk_fsl_assert_support) { diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index 580a3ad556702b..fda11c9c886ab0 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -35,15 +35,10 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # Allows to start the tcp download test app - tcp_download = false - - # Allows to start the wifi connect test app - wifi_connect = false - - # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. - wifi_ssid = "" - wifi_password = "" + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" # Setup discriminator as argument setup_discriminator = 3840 @@ -53,10 +48,6 @@ example_platform_dir = "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" common_example_dir = "${chip_root}/examples/platform/nxp/common" -if (tcp_download == true && wifi_connect == true) { - assert("Cannot enable tcp_download and wifi_connect at the same time!") -} - # Use NXP custom zap files for laundry-washer device-type app_common_folder = "laundry-washer-app/nxp/zap" @@ -218,42 +209,20 @@ rt_executable("laundry-washer") { ] } - if (wifi_connect) { + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + defines += [ - "WIFI_CONNECT_TASK=1", - "WIFI_CONNECT=1", + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", ] - if (!chip_enable_matter_cli) { - assert(wifi_ssid != "" && wifi_password != "", - "WiFi SSID and password must be specified at build time!") - } - - if (wifi_ssid != "") { - defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] - } - - if (wifi_password != "") { - defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] - } - include_dirs += [ "${common_example_dir}/wifi_connect/include" ] sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] } - if (tcp_download) { - defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] - defines += [ - "WIFI_CONNECT=1", - "WIFI_SSID=\"${wifi_ssid}\"", - "WIFI_PASSWORD=\"${wifi_password}\"", - ] - - include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] - sources += - [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] - } - # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false # The would add to the build a dedicated application assert implementation. if (!sdk_fsl_assert_support) { diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp index 37d363490bb76f..2646ffca4ef26d 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -216,7 +216,7 @@ void chip::NXP::App::AppTaskBase::InitServer(intptr_t arg) #endif #if CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT - WifiConnectAtboot(); + VerifyOrDie(WifiConnectAtboot(chip::NXP::App::GetAppTask().GetWifiDriverInstance()) == CHIP_NO_ERROR); #endif #if CHIP_DEVICE_CONFIG_ENABLE_TBR diff --git a/examples/platform/nxp/common/wifi_connect/include/WifiConnect.h b/examples/platform/nxp/common/wifi_connect/include/WifiConnect.h new file mode 100644 index 00000000000000..ea0b5cc9f4d8c1 --- /dev/null +++ b/examples/platform/nxp/common/wifi_connect/include/WifiConnect.h @@ -0,0 +1,42 @@ +/* + * + * 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 WifiConnect.h + * + * Wi-Fi Connect Module allowing to join a pre-defined Wi-Fi network + * + **/ + +#pragma once + +#include + +namespace chip { +namespace NXP { +namespace App { + +/* + * Function allowing to join a Wi-Fi network based on Wi-Fi build credentials + * Must be called after completing Wi-Fi driver initialization + */ +CHIP_ERROR WifiConnectAtboot(chip::DeviceLayer::NetworkCommissioning::WiFiDriver * wifiDriver); + +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/wifi_connect/source/WifiConnect.cpp b/examples/platform/nxp/common/wifi_connect/source/WifiConnect.cpp new file mode 100644 index 00000000000000..438bee5040795f --- /dev/null +++ b/examples/platform/nxp/common/wifi_connect/source/WifiConnect.cpp @@ -0,0 +1,53 @@ +/* + * + * 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 "WifiConnect.h" +#include +#include +#include + +namespace chip { +namespace NXP { +namespace App { + +CHIP_ERROR WifiConnectAtboot(chip::DeviceLayer::NetworkCommissioning::WiFiDriver * wifiDriver) +{ + VerifyOrReturnError(wifiDriver != nullptr, CHIP_ERROR_NOT_IMPLEMENTED); + + /* In case WiFi connect at boot is enabled try to set SSID to the predefined value */ + ByteSpan ssidSpan = ByteSpan(Uint8::from_const_char(CONFIG_CHIP_APP_WIFI_SSID), strlen(CONFIG_CHIP_APP_WIFI_SSID)); + ByteSpan passwordSpan = ByteSpan(Uint8::from_const_char(CONFIG_CHIP_APP_WIFI_PASSWORD), strlen(CONFIG_CHIP_APP_WIFI_PASSWORD)); + VerifyOrReturnError(IsSpanUsable(ssidSpan) && IsSpanUsable(passwordSpan), CHIP_ERROR_INVALID_ARGUMENT); + + chip::DeviceLayer::NetworkCommissioning::NetworkIterator * networks = wifiDriver->GetNetworks(); + /* In case Wi-Fi driver has already Wi-Fi network information, skip the connect stage */ + if (networks == nullptr || networks->Count() == 0) + { + uint8_t networkIndex; + chip::MutableCharSpan debugText; + chip::DeviceLayer::NetworkCommissioning::Status status = + wifiDriver->AddOrUpdateNetwork(ssidSpan, passwordSpan, debugText, networkIndex); + VerifyOrReturnError(status == chip::DeviceLayer::NetworkCommissioning::Status::kSuccess, CHIP_ERROR_CONNECTION_ABORTED); + wifiDriver->ConnectNetwork(ssidSpan, nullptr); + } + return CHIP_NO_ERROR; +} + +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 389f143a3939bd..b115499ef18297 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -35,15 +35,10 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # Allows to start the tcp download test app - tcp_download = false - - # Allows to start the wifi connect test app - wifi_connect = false - - # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. - wifi_ssid = "" - wifi_password = "" + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" # Setup discriminator as argument setup_discriminator = 3840 @@ -55,10 +50,6 @@ example_platform_dir = "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" common_example_dir = "${chip_root}/examples/platform/nxp/common" -if (tcp_download == true && wifi_connect == true) { - assert("Cannot enable tcp_download and wifi_connect at the same time!") -} - # Use NXP custom zap files for thermostatdevice-types app_common_folder = "thermostat/nxp/zap" @@ -227,42 +218,20 @@ rt_executable("thermostat") { ] } - if (wifi_connect) { + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + defines += [ - "WIFI_CONNECT_TASK=1", - "WIFI_CONNECT=1", + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", ] - if (!chip_enable_matter_cli) { - assert(wifi_ssid != "" && wifi_password != "", - "WiFi SSID and password must be specified at build time!") - } - - if (wifi_ssid != "") { - defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] - } - - if (wifi_password != "") { - defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] - } - include_dirs += [ "${common_example_dir}/wifi_connect/include" ] sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] } - if (tcp_download) { - defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] - defines += [ - "WIFI_CONNECT=1", - "WIFI_SSID=\"${wifi_ssid}\"", - "WIFI_PASSWORD=\"${wifi_password}\"", - ] - - include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] - sources += - [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] - } - # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false # The would add to the build a dedicated application assert implementation. if (!sdk_fsl_assert_support) { From 6ca036e0fb646af02628c4e90cd61baef6fed039 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Tue, 4 Jun 2024 10:09:53 +0200 Subject: [PATCH 09/18] [NXP] setup_discriminator argument value was only applied when OTA requestor enabled (cherry picked from commit fa9de443e3129ecf7befb4404fb2dd0efc213a29) --- examples/thermostat/nxp/rt/rw61x/BUILD.gn | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index b115499ef18297..103216828f3819 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -105,6 +105,10 @@ rt_sdk("sdk") { "CHIP_DEVICE_CONFIG_ENABLE_TBR=1", ] } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] } # Create the SDK driver instance. @@ -270,10 +274,6 @@ rt_executable("thermostat") { # Consequently, some sections will need to be shifted ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x20000" ] } - - defines += [ - "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", - ] } output_dir = root_out_dir From 1b1d4e0b7ccb311731f7a673865c5da54c804a51 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 18 Sep 2024 13:25:45 +0000 Subject: [PATCH 10/18] Restyled by gn --- .../all-clusters-app/nxp/rt/rw61x/BUILD.gn | 4 +- .../laundry-washer-app/nxp/rt/rw61x/BUILD.gn | 5 ++- examples/thermostat/nxp/rt/rw61x/BUILD.gn | 5 ++- src/platform/nxp/rt/rw61x/BUILD.gn | 37 +++++++++++-------- .../platforms/nxp/rt/rw61x/BUILD.gn | 8 ++-- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index 0e20d5510084fa..bdc878cc0f5250 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -35,7 +35,6 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # Allows to connect to a predefine Wi-Fi network at boot wifi_auto_connect_at_boot = false wifi_auto_connect_at_boot_ssid = "" @@ -206,7 +205,8 @@ rt_executable("all_cluster_app") { } if (wifi_auto_connect_at_boot) { - assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", "WiFi SSID and password must be specified at build time!") defines += [ diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index fda11c9c886ab0..cb0b7ba0a96439 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -35,7 +35,7 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # Allows to connect to a predefine Wi-Fi network at boot + # Allows to connect to a predefine Wi-Fi network at boot wifi_auto_connect_at_boot = false wifi_auto_connect_at_boot_ssid = "" wifi_auto_connect_at_boot_password = "" @@ -210,7 +210,8 @@ rt_executable("laundry-washer") { } if (wifi_auto_connect_at_boot) { - assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", "WiFi SSID and password must be specified at build time!") defines += [ diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 103216828f3819..f377845cd49f98 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -105,7 +105,7 @@ rt_sdk("sdk") { "CHIP_DEVICE_CONFIG_ENABLE_TBR=1", ] } - + defines += [ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", ] @@ -223,7 +223,8 @@ rt_executable("thermostat") { } if (wifi_auto_connect_at_boot) { - assert(wifi_auto_connect_at_boot_ssid != "" && wifi_auto_connect_at_boot_password != "", + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", "WiFi SSID and password must be specified at build time!") defines += [ diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index c96a9f2e5e0e1a..e80dd3cbd823f4 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -34,7 +34,10 @@ source_set("nxp_ota") { } config("nxp_platform_config") { - defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"", "CONFIG_BOOT_REASON_SDK_SUPPORT=1" ] + defines = [ + "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"", + "CONFIG_BOOT_REASON_SDK_SUPPORT=1", + ] include_dirs = [ ".", "../../common", @@ -63,11 +66,12 @@ config("nxp_platform_config") { defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] } } - # When OTBR is enabled Thread network commissioning cluster is enabled using chip_enable_secondary_nwk_if - if (chip_enable_wifi && chip_enable_openthread && !chip_enable_secondary_nwk_if) { + + # When OTBR is enabled Thread network commissioning cluster is enabled using chip_enable_secondary_nwk_if + if (chip_enable_wifi && chip_enable_openthread && + !chip_enable_secondary_nwk_if) { defines += [ "_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" ] } - } static_library("nxp_platform") { @@ -155,31 +159,32 @@ static_library("nxp_platform") { if (chip_enable_openthread) { sources += [ + # Temporary fix, to be revert once PR #34662 is merged, build issue when using GN check argument + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", + "../../../OpenThread/GenericThreadBorderRouterDelegate.cpp", + "../../../OpenThread/GenericThreadBorderRouterDelegate.h", "../../../OpenThread/OpenThreadUtils.cpp", "../../common/ThreadStackManagerImpl.cpp", "../../common/ThreadStackManagerImpl.h", - "../../../OpenThread/GenericThreadBorderRouterDelegate.cpp", - "../../../OpenThread/GenericThreadBorderRouterDelegate.h", - # Temporary fix, to be revert once PR #34662 is merged, build issue when using GN check argument - "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", ] - - deps += ["${chip_root}/src/app/common:ids",] - + + deps += [ "${chip_root}/src/app/common:ids" ] + if (!nxp_build_matter_standalone_lib) { deps += [ "${chip_root}/third_party/openthread:openthread" ] - public_deps += [ "${chip_root}/third_party/openthread:openthread-platform" ] + public_deps += + [ "${chip_root}/third_party/openthread:openthread-platform" ] } if (chip_mdns == "platform") { if (chip_enable_wifi) { - sources += [ - "../../common/DnssdImpl.cpp", - "../../common/DnssdImplBr.cpp", - "../../common/DnssdImplBr.h", + sources += [ "../../../OpenThread/DnssdImpl.cpp", "../../../OpenThread/OpenThreadDnssdImpl.cpp", "../../../OpenThread/OpenThreadDnssdImpl.h", + "../../common/DnssdImpl.cpp", + "../../common/DnssdImplBr.cpp", + "../../common/DnssdImplBr.h", ] } else { sources += [ diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index efa2cd16575f26..e9cebc925d47a1 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -61,7 +61,7 @@ config("openthread_rw61x_config") { "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", "OT_APP_BR_LWIP_HOOKS_EN=1", "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", - "OT_APP_CLI_LWIP_ADDON=1" + "OT_APP_CLI_LWIP_ADDON=1", ] } @@ -86,6 +86,9 @@ source_set("libopenthread-rw61x") { if (chip_enable_wifi && chip_enable_openthread) { sources += [ + "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", "${openthread_nxp_root}/src/common/br/border_agent.c", "${openthread_nxp_root}/src/common/br/br_rtos_manager.c", "${openthread_nxp_root}/src/common/br/infra_if.c", @@ -94,9 +97,6 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/common/br/mdns_socket.c", "${openthread_nxp_root}/src/common/br/udp_plat.c", "${openthread_nxp_root}/src/common/br/utils.c", - "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", - "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", - "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", ] deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] } From f68ea37932d6b3ced205329ef95d7812ac54bf18 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 18 Sep 2024 13:25:53 +0000 Subject: [PATCH 11/18] Restyled by prettier-markdown --- docs/guides/nxp/nxp_otbr_guide.md | 58 ++++++++++++++----- .../all-clusters-app/nxp/rt/rw61x/README.md | 29 +++++++--- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/docs/guides/nxp/nxp_otbr_guide.md b/docs/guides/nxp/nxp_otbr_guide.md index 77bcb69ee528d5..0e7c08e91b867e 100644 --- a/docs/guides/nxp/nxp_otbr_guide.md +++ b/docs/guides/nxp/nxp_otbr_guide.md @@ -1,6 +1,7 @@ # Thread Border Router usage -This document describes the use of the Thread Border router and secondary netwok interface for a Matter application +This document describes the use of the Thread Border router and secondary netwok +interface for a Matter application
@@ -15,42 +16,63 @@ This document describes the use of the Thread Border router and secondary netwok ## Thread Border Router overwiew -This section contains an overview of the Border Router architecture and describes the general use cases. +This section contains an overview of the Border Router architecture and +describes the general use cases. ## Using the Thread Border Router management cluster -The Thread Border Router management cluster allows provisioning of the Thread interface using a Matter commissioner. +The Thread Border Router management cluster allows provisioning of the Thread +interface using a Matter commissioner. -After the device has been provisioned over WIFI the set active dataset command can be used to configure the Thread active dataset on the border router. Once the dataset is set successfully the Thread network interface will be enabled and the device will create a new PAN or join an existing one if already present. Note that this command cannot be used on a device that already has an active dataset configured. In this situation the set pending dataset command must be used instead. +After the device has been provisioned over WIFI the set active dataset command +can be used to configure the Thread active dataset on the border router. Once +the dataset is set successfully the Thread network interface will be enabled and +the device will create a new PAN or join an existing one if already present. +Note that this command cannot be used on a device that already has an active +dataset configured. In this situation the set pending dataset command must be +used instead. -Before using the set active dataset command a fail-safe timer must be armed (recommend using a timeout of 120 seconds): +Before using the set active dataset command a fail-safe timer must be armed +(recommend using a timeout of 120 seconds): ``` ubuntu@ubuntu:~$ ./chip-tool generalcommissioning arm-fail-safe timeout-seconds 1 node-id 0 ``` -Then an active dataset in HEX TLV format (the same type used to provision a Matter over Thread device using the `ble-thread` command) can be used to provision the Border Router. What the active dataset should be is outside the scope of this README but as an example one can be obtained from the OpenThread cli on an already provisioned device using the `dataset active -x` command. -Note that the Thread Border Router management cluster has been set to endpoint 2 in the zap file. +Then an active dataset in HEX TLV format (the same type used to provision a +Matter over Thread device using the `ble-thread` command) can be used to +provision the Border Router. What the active dataset should be is outside the +scope of this README but as an example one can be obtained from the OpenThread +cli on an already provisioned device using the `dataset active -x` command. + +Note that the Thread Border Router management cluster has been set to endpoint 2 +in the zap file. ``` ubuntu@ubuntu:~$ ./chip-tool threadborderroutermanagement set-active-dataset-request hex: node id 2 ``` -If the active dataset command is successful, a commissioning complete command must be send to disarm the fail-safe timer and commit the configuration to non-volatile storage. +If the active dataset command is successful, a commissioning complete command +must be send to disarm the fail-safe timer and commit the configuration to +non-volatile storage. ``` ubuntu@ubuntu:~$ ./chip-tool-19-jul generalcommissioning commissioning-complete node-id 0 ``` -Note that this command cannot be used on a device that already has an active dataset configured. In this situation the set pending dataset command must be used instead. +Note that this command cannot be used on a device that already has an active +dataset configured. In this situation the set pending dataset command must be +used instead. ``` ubuntu@ubuntu:~$ ./chip-tool threadborderroutermanagement set-pending-dataset-request hex: node id 2 ``` -To read the active dataset of an already provisioned device, for example to make a joining Border Router use the same Thread network as an already configured one, the get active dataset command can be used: +To read the active dataset of an already provisioned device, for example to make +a joining Border Router use the same Thread network as an already configured +one, the get active dataset command can be used: ``` ubuntu@ubuntu:~$ ./chip-tool-19-jul threadborderroutermanagement get-active-dataset-request node-id 2 @@ -60,8 +82,12 @@ ubuntu@ubuntu:~$ ./chip-tool-19-jul threadborderroutermanagement get-active-data ## Using the Secondary Network commissioning interface -To use the secondary network commissioning interface over Thread the device must not be provisioned over WIFI. -The regular `ble-thread` pairing is used as for any other Matter over Thread device. The chip-tool will read all the endpoints of the device and discover Thread network commissioning cluster on endpoint 3 and use that to provision the device. As for any other Matter over Thread device a Thread Border Router is required in this case. +To use the secondary network commissioning interface over Thread the device must +not be provisioned over WIFI. The regular `ble-thread` pairing is used as for +any other Matter over Thread device. The chip-tool will read all the endpoints +of the device and discover Thread network commissioning cluster on endpoint 3 +and use that to provision the device. As for any other Matter over Thread device +a Thread Border Router is required in this case. ``` ubuntu@ubuntu:~$ ./chip-tool pairing ble-thread node-id hex: 20202021 3840 @@ -71,6 +97,10 @@ ubuntu@ubuntu:~$ ./chip-tool pairing ble-thread node-id hex: 202 ## Using the Thread credential sharing mechanism -The details about using the credential sharing mechanism are in the ot-nxp repo border router application [readme](https://github.com/NXP/ot-nxp/blob/v1.4.0-pvw1/examples/br/README-OTBR.md). See `Ephemeral Key functionality` section. +The details about using the credential sharing mechanism are in the ot-nxp repo +border router application +[readme](https://github.com/NXP/ot-nxp/blob/v1.4.0-pvw1/examples/br/README-OTBR.md). +See `Ephemeral Key functionality` section. -Note that all OpenThread commands executed from then Matter CLI must have `otcli` prepended before the command. \ No newline at end of file +Note that all OpenThread commands executed from then Matter CLI must have +`otcli` prepended before the command. diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index 543e1c7cc37622..b02f45000e9866 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -125,10 +125,13 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x #### Building with Matter over Wifi + OpenThread Border Router configuration on RW612 -This configuration supports the Thread Border Router management cluster to provision the Thread credentials. Enabling the Matter CLI in order to control the -Thread network on the Border Router is optional but recommended for other features like the Thread credential sharing. +This configuration supports the Thread Border Router management cluster to +provision the Thread credentials. Enabling the Matter CLI in order to control +the Thread network on the Border Router is optional but recommended for other +features like the Thread credential sharing. -Note that the Thread Border Router management cluster is only supported on the thermostat application for now. +Note that the Thread Border Router management cluster is only supported on the +thermostat application for now. - Build Matter with Border Router configuration with BLE commissioning (ble-wifi) : @@ -147,7 +150,11 @@ Optional GN options that can be added when building an application: - To enable the [secondary network commissioning interface](../../../../../docs/guides/nxp/nxp_otbr_guide.md#using-the-secondary-network-commissioning-interface), - the arguments `chip_enable_secondary_nwk_if=true` and `chip_device_config_thread_network_endpoint_id=2` must be added to the _gn gen_ command. Note that this is only supported when building the Matter over Wifi + OpenThread Border Router configuration. Note that is only supported on the on the thermostat application for now. + the arguments `chip_enable_secondary_nwk_if=true` and + `chip_device_config_thread_network_endpoint_id=2` must be added to the _gn + gen_ command. Note that this is only supported when building the Matter over + Wifi + OpenThread Border Router configuration. Note that is only supported + on the on the thermostat application for now. - To enable the [matter CLI](README.md#testing-the-all-clusters-application-with-matter-cli-enabled), the argument `chip_enable_matter_cli=true` must be added to the _gn gen_ @@ -271,12 +278,13 @@ The "ble-thread" pairing method can be used in order to commission the device. #### Matter over wifi with openthread border router configuration : -In order to create or join a Thread network on the Matter Border Router, the TBR management cluster or the -`otcli` commands from the matter CLI can be used. For more information about using the TBR management cluster follow instructions from ['Using the TBR management cluster'](../../../../../docs/guides/nxp/nxp_otbr_guide.md#using-the-thread-border-router-management-cluster). +In order to create or join a Thread network on the Matter Border Router, the TBR +management cluster or the `otcli` commands from the matter CLI can be used. For +more information about using the TBR management cluster follow instructions from +['Using the TBR management cluster'](../../../../../docs/guides/nxp/nxp_otbr_guide.md#using-the-thread-border-router-management-cluster). For more information about using the matter shell, follow instructions from ['Testing the all-clusters application with Matter CLI'](#testing-the-all-clusters-application-with-matter-cli-enabled). - In this configuration, the device can be commissioned over Wi-Fi with the 'ble-wifi' pairing method. @@ -391,6 +399,7 @@ Done leader Done ``` + ## OTA Software Update @@ -404,6 +413,8 @@ dedicated guide ## Thread Border Router overwiew -To enable Thread Border Router support see the [build](README.md#building) section. +To enable Thread Border Router support see the [build](README.md#building) +section. -The complete Border Router guide is located [here](../../../../../docs/guides/nxp/nxp_otbr_guide.md). +The complete Border Router guide is located +[here](../../../../../docs/guides/nxp/nxp_otbr_guide.md). From d4dedc625c5489dc6802a0cc3e2e68817236f6f2 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 15:34:55 +0200 Subject: [PATCH 12/18] [NXP] Regenerate .zap and .matter file for BR Signed-off-by: Martin Girardot --- .../nxp/zap/thermostat_matter_br.matter | 14 ++--- .../nxp/zap/thermostat_matter_br.zap | 54 +------------------ 2 files changed, 6 insertions(+), 62 deletions(-) diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.matter b/examples/thermostat/nxp/zap/thermostat_matter_br.matter index 13ec76f293969a..21c7711e1557ac 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter @@ -557,14 +557,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -591,7 +587,7 @@ cluster AccessControl = 31 { } /** 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): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -2239,7 +2235,7 @@ cluster Thermostat = 513 { } request struct SetActivePresetRequestRequest { - octet_string<16> presetHandle = 0; + nullable octet_string<16> presetHandle = 0; } response struct AtomicResponse = 253 { diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.zap b/examples/thermostat/nxp/zap/thermostat_matter_br.zap index f766783c3cbf75..212b57c25b5c1c 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.zap @@ -982,24 +982,6 @@ "isIncoming": 0, "isEnabled": 1 } - ], - "attributes": [ - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "client", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } ] }, { @@ -3135,40 +3117,6 @@ "isIncoming": 0, "isEnabled": 1 } - ], - "attributes": [ - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "client", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "client", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "4", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } ] }, { @@ -4917,7 +4865,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, From c2c3dea55989c3004718c38e09bbf41927e33565 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 16:04:40 +0200 Subject: [PATCH 13/18] [NXP] Fix spelling issue Signed-off-by: Martin Girardot --- docs/guides/nxp/nxp_otbr_guide.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/guides/nxp/nxp_otbr_guide.md b/docs/guides/nxp/nxp_otbr_guide.md index 0e7c08e91b867e..82b86633f0b600 100644 --- a/docs/guides/nxp/nxp_otbr_guide.md +++ b/docs/guides/nxp/nxp_otbr_guide.md @@ -1,20 +1,21 @@ # Thread Border Router usage -This document describes the use of the Thread Border router and secondary netwok +This document describes the use of the Thread Border router and secondary network interface for a Matter application
-- [Thread Border Router overwiew](#thread-border-router-overwiew) -- [Using the Thread Border Router Management cluster](#using-the-thread-border-router-management-cluster) -- [Using the Secondary Network commissioning interface](#using-the-secondary-network-commissioning-interface) -- [Using the Thread credential sharing mechanism](#using-the-thread-credential-sharing-mechanism) +- [Thread Border Router usage](#thread-border-router-usage) + - [Thread Border Router overview](#thread-border-router-overview) + - [Using the Thread Border Router management cluster](#using-the-thread-border-router-management-cluster) + - [Using the Secondary Network commissioning interface](#using-the-secondary-network-commissioning-interface) + - [Using the Thread credential sharing mechanism](#using-the-thread-credential-sharing-mechanism)
- + -## Thread Border Router overwiew +## Thread Border Router overview This section contains an overview of the Border Router architecture and describes the general use cases. @@ -103,4 +104,4 @@ border router application See `Ephemeral Key functionality` section. Note that all OpenThread commands executed from then Matter CLI must have -`otcli` prepended before the command. +`otcli` added before the command. From 960d75ab1f004cdbead9c8f2a6b915f824e2c336 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 18 Sep 2024 15:50:42 +0000 Subject: [PATCH 14/18] Restyled by prettier-markdown --- docs/guides/nxp/nxp_otbr_guide.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/guides/nxp/nxp_otbr_guide.md b/docs/guides/nxp/nxp_otbr_guide.md index 82b86633f0b600..fd993f02e5376a 100644 --- a/docs/guides/nxp/nxp_otbr_guide.md +++ b/docs/guides/nxp/nxp_otbr_guide.md @@ -1,15 +1,15 @@ # Thread Border Router usage -This document describes the use of the Thread Border router and secondary network -interface for a Matter application +This document describes the use of the Thread Border router and secondary +network interface for a Matter application
-- [Thread Border Router usage](#thread-border-router-usage) - - [Thread Border Router overview](#thread-border-router-overview) - - [Using the Thread Border Router management cluster](#using-the-thread-border-router-management-cluster) - - [Using the Secondary Network commissioning interface](#using-the-secondary-network-commissioning-interface) - - [Using the Thread credential sharing mechanism](#using-the-thread-credential-sharing-mechanism) +- [Thread Border Router usage](#thread-border-router-usage) + - [Thread Border Router overview](#thread-border-router-overview) + - [Using the Thread Border Router management cluster](#using-the-thread-border-router-management-cluster) + - [Using the Secondary Network commissioning interface](#using-the-secondary-network-commissioning-interface) + - [Using the Thread credential sharing mechanism](#using-the-thread-credential-sharing-mechanism)
From 87511e15d35fcb2bb055b6b49c9262e26b6aecab Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Wed, 18 Sep 2024 17:32:25 +0200 Subject: [PATCH 15/18] [NXP] Fix spelling issue Signed-off-by: Martin Girardot --- .github/.wordlist.txt | 1 + examples/all-clusters-app/nxp/rt/rw61x/README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index d0d8c0d9655462..a0dda2bd42edf0 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1628,3 +1628,4 @@ Zigbee zigbeealliance zigbeethread zsdk +TBR diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index b02f45000e9866..61d3f008697a58 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -16,7 +16,7 @@ commissioning and different cluster control. - [Testing the example](#testing-the-example) - [Matter Shell](#testing-the-all-clusters-application-with-matter-cli-enabled) - [OTA Software Update](#ota-software-update) -- [Thread Border Router overwiew](#thread-border-router-overwiew) +- [Thread Border Router overview](#thread-border-router-overview)
@@ -409,9 +409,9 @@ The process to follow in order to perform a software update is described in the dedicated guide ['Matter Over-The-Air Software Update with NXP RW61x example applications'](../../../../../docs/guides/nxp/nxp_rw61x_ota_software_update.md). - + -## Thread Border Router overwiew +## Thread Border Router overview To enable Thread Border Router support see the [build](README.md#building) section. From b5340b8324088cfbedbfb657e69238c4eb3e1a96 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Fri, 20 Sep 2024 08:40:07 +0200 Subject: [PATCH 16/18] [NXP] Fix otbr build issue Signed-off-by: Martin Girardot --- .../platforms/nxp/rt/rw61x/BUILD.gn | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index e9cebc925d47a1..4b80c848992d5c 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -58,11 +58,16 @@ config("openthread_rw61x_config") { "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", "OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF=0", "OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1", - "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", "OT_APP_BR_LWIP_HOOKS_EN=1", - "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", - "OT_APP_CLI_LWIP_ADDON=1", ] + + if (chip_enable_matter_cli) { + defines += [ + "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", + "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", + "OT_APP_CLI_LWIP_ADDON=1" + ] + } } # ot cli configs @@ -86,9 +91,6 @@ source_set("libopenthread-rw61x") { if (chip_enable_wifi && chip_enable_openthread) { sources += [ - "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", - "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", - "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", "${openthread_nxp_root}/src/common/br/border_agent.c", "${openthread_nxp_root}/src/common/br/br_rtos_manager.c", "${openthread_nxp_root}/src/common/br/infra_if.c", @@ -98,6 +100,15 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/common/br/udp_plat.c", "${openthread_nxp_root}/src/common/br/utils.c", ] + + if (chip_enable_matter_cli) { + sources += [ + "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", + ] + } + deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] } if (spinel_interface_rpmsg) { From 78b1363619bb121ee7243fa0747d496b6823309b Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 20 Sep 2024 07:42:56 +0000 Subject: [PATCH 17/18] Restyled by gn --- third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index 4b80c848992d5c..86c9f2fe2d5c58 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -65,7 +65,7 @@ config("openthread_rw61x_config") { defines += [ "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", - "OT_APP_CLI_LWIP_ADDON=1" + "OT_APP_CLI_LWIP_ADDON=1", ] } } From f60775e5be52dfc36eec47eba23ab26532365ca5 Mon Sep 17 00:00:00 2001 From: Martin Girardot Date: Fri, 20 Sep 2024 16:34:00 +0200 Subject: [PATCH 18/18] [NXP] Disable identify cluster on endpoint 0 Signed-off-by: Martin Girardot --- .../nxp/zap/thermostat_matter_br.matter | 13 -- .../nxp/zap/thermostat_matter_br.zap | 148 ------------------ 2 files changed, 161 deletions(-) diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.matter b/examples/thermostat/nxp/zap/thermostat_matter_br.matter index 21c7711e1557ac..bb72c0caceaf27 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter @@ -2315,19 +2315,6 @@ endpoint 0 { binding cluster OtaSoftwareUpdateProvider; - server cluster Identify { - ram attribute identifyTime default = 0x0000; - ram attribute identifyType default = 0x00; - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; - - handle command Identify; - } - server cluster Descriptor { callback attribute deviceTypeList; callback attribute serverList; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.zap b/examples/thermostat/nxp/zap/thermostat_matter_br.zap index 212b57c25b5c1c..3586eeb6b2320d 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.zap @@ -61,154 +61,6 @@ "deviceTypeCode": 22, "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": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x0000", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "IdentifyType", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "IdentifyTypeEnum", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x00", - "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": "EventList", - "code": 65530, - "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": "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": "4", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } - ] - }, { "name": "Descriptor", "code": 29,