[NXP] Add TBRM and wifi connect support (#35646)
* [NXP] Update ot-nxp submodule
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP][third_party] Enable lwip and ephemeral key CLI addons
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [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 <martin.girardot@nxp.com>
* [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 <martin.girardot@nxp.com>
* [NXP][workflows] Only thermostat app support OTBR feature
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP][doc] add OTBR guide
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP][platform][rw61x] Add support of boot reason
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
(cherry picked from commit d8f44419ea89d5ecec73fe8d82fdb30d444f49b3)
* [NXP] Adding wifi_connect module
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP] setup_discriminator argument value was only applied when OTA requestor enabled
(cherry picked from commit fa9de443e3129ecf7befb4404fb2dd0efc213a29)
* Restyled by gn
* Restyled by prettier-markdown
* [NXP] Regenerate .zap and .matter file for BR
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP] Fix spelling issue
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* Restyled by prettier-markdown
* [NXP] Fix spelling issue
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* [NXP] Fix otbr build issue
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
* Restyled by gn
* [NXP] Disable identify cluster on endpoint 0
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
---------
Signed-off-by: Martin Girardot <martin.girardot@nxp.com>
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt
index 9467074..dc56ae9 100644
--- a/.github/.wordlist.txt
+++ b/.github/.wordlist.txt
@@ -1630,3 +1630,4 @@
zigbeealliance
zigbeethread
zsdk
+TBR
diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml
index fc929ef..e8e3359 100644
--- a/.github/workflows/examples-nxp.yaml
+++ b/.github/workflows/examples-nxp.yaml
@@ -242,7 +242,6 @@
./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 @@
./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 \
"
diff --git a/docs/guides/nxp/nxp_otbr_guide.md b/docs/guides/nxp/nxp_otbr_guide.md
new file mode 100644
index 0000000..fd993f0
--- /dev/null
+++ b/docs/guides/nxp/nxp_otbr_guide.md
@@ -0,0 +1,107 @@
+# Thread Border Router usage
+
+This document describes the use of the Thread Border router and secondary
+network interface for a Matter application
+
+<hr>
+
+- [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)
+
+<hr>
+
+<a name="thread-border-router-overview"></a>
+
+## Thread Border Router overview
+
+This section contains an overview of the Border Router architecture and
+describes the general use cases.
+
+<a name="using-the-thread-border-router-management-cluster"></a>
+
+## 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:<active-dataset> 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:<active-dataset> 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
+```
+
+<a name="using-the-secondary-network-commissioning-interface"></a>
+
+## 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:<active-dataset> 20202021 3840
+```
+
+<a name="using-the-thread-credential-sharing-mechanism"></a>
+
+## 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` added before the command.
diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn
index b0e1c1c..bdc878c 100644
--- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn
+++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn
@@ -35,15 +35,10 @@
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 @@
"${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 +204,21 @@
]
}
- 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/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md
index 9356e4b..61d3f00 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 @@
- [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 overview](#thread-border-router-overview)
<hr>
@@ -124,8 +125,13 @@
#### 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) :
@@ -143,6 +149,13 @@
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_
command.
@@ -265,9 +278,11 @@
#### 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
@@ -393,3 +408,13 @@
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).
+
+<a name="thread-border-router-overview"></a>
+
+## Thread Border Router overview
+
+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/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn
index 580a3ad..cb0b7ba 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(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 @@
"${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,21 @@
]
}
- 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/include/AppTaskBase.h b/examples/platform/nxp/common/app_task/include/AppTaskBase.h
index 38770fa..ab29af2 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 @@
*/
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 c62be98..2646ffc 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 <app/util/attribute-storage.h>
#include <app/clusters/network-commissioning/network-commissioning.h>
+
#include <platform/CommissionableDataProvider.h>
#include "lib/core/ErrorStr.h"
@@ -56,8 +57,8 @@
#include <lib/support/ThreadOperationalDataset.h>
#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 <app/TestEventTriggerDelegate.h>
#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_TBR
+#include "platform/OpenThread/GenericThreadBorderRouterDelegate.h"
+#include <app/clusters/thread-border-router-management-server/thread-border-router-management-server.h>
+#endif
+
#ifndef CONFIG_THREAD_DEVICE_TYPE
#define CONFIG_THREAD_DEVICE_TYPE kThreadDeviceType_Router
#endif
@@ -120,12 +126,23 @@
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 @@
#if CONFIG_CHIP_OTA_PROVIDER
InitOTAServer();
#endif
+
+#if CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT
+ VerifyOrDie(WifiConnectAtboot(chip::NXP::App::GetAppTask().GetWifiDriverInstance()) == CHIP_NO_ERROR);
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_TBR
+ GetAppTask().EnableTbrManagementCluster();
+#endif
}
CHIP_ERROR chip::NXP::App::AppTaskBase::Init()
@@ -326,10 +351,6 @@
}
#endif
-#if CONFIG_CHIP_TCP_DOWNLOAD
- EnableTcpDownloadComponent();
-#endif
-
exit:
return err;
}
@@ -443,3 +464,19 @@
ChipLogProgress(DeviceLayer, "Current Software Version: %s, %d", currentSoftwareVer, static_cast<int>(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 4cbd502..fc8b2ed 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 @@
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 2e40fde..1bab4b0 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 <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/server/Dnssd.h>
@@ -73,7 +75,7 @@
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 @@
/* 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 @@
PlatformMgrImpl().StopBLEConnectivity();
ThreadStackMgrImpl().UnlockThreadStack();
}
+#endif
}
#endif
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 0000000..ea0b5cc
--- /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 <platform/NetworkCommissioning.h>
+
+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 0000000..438bee5
--- /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 <lib/support/Span.h>
+#include <platform/ConnectivityManager.h>
+#include <platform/NetworkCommissioning.h>
+
+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 30af1be..f377845 100644
--- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn
+++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn
@@ -35,15 +35,10 @@
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 @@
"${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"
@@ -107,10 +98,17 @@
# 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",
+ ]
}
+
+ defines += [
+ "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}",
+ ]
}
# Create the SDK driver instance.
@@ -224,42 +222,21 @@
]
}
- 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) {
@@ -298,10 +275,6 @@
# 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
diff --git a/examples/thermostat/nxp/zap/BUILD.gn b/examples/thermostat/nxp/zap/BUILD.gn
index c3a3df7..f3c6524 100644
--- a/examples/thermostat/nxp/zap/BUILD.gn
+++ b/examples/thermostat/nxp/zap/BUILD.gn
@@ -20,7 +20,10 @@
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 0000000..bb72c0c
--- /dev/null
+++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter
@@ -0,0 +1,2766 @@
+// 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) FabricRestrictionReviewUpdate = 2 {
+ int64u token = 0;
+ optional long_char_string instruction = 1;
+ optional long_char_string ARLRequestFlowUrl = 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): ReviewFabricRestrictionsResponse = 0;
+}
+
+/** This cluster provides attributes and events for determining basic information about Nodes, which supports both
+ Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number,
+ which apply to the whole Node. Also allows setting user device information such as location. */
+cluster BasicInformation = 40 {
+ revision 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 {
+ nullable 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 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 0000000..3586eeb
--- /dev/null
+++ b/examples/thermostat/nxp/zap/thermostat_matter_br.zap
@@ -0,0 +1,5392 @@
+{
+ "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": "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
+ }
+ ]
+ },
+ {
+ "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
+ }
+ ]
+ },
+ {
+ "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": 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": "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
diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp
index 09d716a..3473fc7 100644
--- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp
+++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp
@@ -95,10 +95,6 @@
GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>::_Init();
#endif
-#if CHIP_DEVICE_CONFIG_ENABLE_WPA
- StartWiFiManagement();
-#endif
-
SuccessOrExit(err);
exit:
@@ -614,6 +610,11 @@
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 d0069ce..4393270 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,462 +17,113 @@
*/
#include "lib/dnssd/platform/Dnssd.h"
+#include "platform/CHIPDeviceLayer.h"
+
+#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
-#include <lib/support/FixedBufferAllocator.h>
-#include <platform/CHIPDeviceLayer.h>
-#include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h>
-#include <platform/OpenThread/OpenThreadUtils.h>
+#include <lib/support/logging/CHIPLogging.h>
-#include <platform/nxp/common/ConnectivityManagerImpl.h>
-
-#include <openthread/mdns.h>
-#include <openthread/srp_server.h>
+#include <DnssdImplBr.h>
+#include <platform/OpenThread/OpenThreadDnssdImpl.h>
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<otMdnsService *>(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;
- }
+ ReturnErrorOnFailure(NxpChipDnssdPublishService(service, callback, context));
+ }
+ else if (ConnectivityMgr().IsThreadProvisioned())
+ {
+ ReturnErrorOnFailure(OpenThreadDnssdPublishService(service, callback, context));
}
-#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 ChipDnssdFinalizeServiceUpdate()
-{
- 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 ChipDnssdFinalizeServiceUpdate()
+CHIP_ERROR ChipDnssdRemoveServices()
{
- 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);
+ if (ConnectivityMgr().IsWiFiStationConnected())
+ {
+ ReturnErrorOnFailure(NxpChipDnssdRemoveServices());
+ }
+ else if (ConnectivityMgr().IsThreadProvisioned())
+ {
+ ReturnErrorOnFailure(OpenThreadDnssdRemoveServices());
+ }
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)
+CHIP_ERROR ChipDnssdFinalizeServiceUpdate()
{
- *browseIdentifier = reinterpret_cast<intptr_t>(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<mDnsQueryCtx>(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)
+ if (ConnectivityMgr().IsWiFiStationConnected())
{
- bBrowseInProgress = true;
- *browseIdentifier = reinterpret_cast<intptr_t>(mBrowseContext);
+ ReturnErrorOnFailure(NxpChipDnssdFinalizeServiceUpdate());
}
- else
+ else if (ConnectivityMgr().IsThreadProvisioned())
{
- 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<intptr_t>(mBrowseContext));
- }
- else
- {
- Platform::Delete<mDnsQueryCtx>(mBrowseContext);
- mBrowseContext = nullptr;
- }
+ ReturnErrorOnFailure(OpenThreadDnssdFinalizeServiceUpdate());
}
- return error;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType,
+ chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context,
+ intptr_t * browseIdentifier)
+{
+ if (ConnectivityMgr().IsWiFiStationConnected()) //|| ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey))
+ {
+ ReturnErrorOnFailure(NxpChipDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier));
+ }
+ else if (ConnectivityMgr().IsThreadProvisioned())
+ {
+ ReturnErrorOnFailure(OpenThreadDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier));
+ }
+
+ return CHIP_NO_ERROR;
}
CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier)
{
- mDnsQueryCtx * browseContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(browseContext));
- }
- return MapOpenThreadError(error);
+ return NxpChipDnssdStopBrowse(browseIdentifier);
}
-CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context)
+CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::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<mDnsQueryCtx>(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)
+ if (ConnectivityMgr().IsWiFiStationConnected()) //|| ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey))
{
- // 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));
+ ReturnErrorOnFailure(NxpChipDnssdResolve(service, interface, callback, context));
}
- else
+ else if (ConnectivityMgr().IsThreadProvisioned())
{
- return error;
+ ReturnErrorOnFailure(OpenThreadDnssdResolve(service, interface, callback, context));
}
+
+ return CHIP_NO_ERROR;
}
+
void ChipDnssdResolveNoLongerNeeded(const char * instanceName)
{
- if (mResolveContext != nullptr)
- {
- if (strcmp(instanceName, mResolveContext->mMdnsService.mName) == 0)
- {
- otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &mResolveContext->mSrvInfo);
-
- Platform::Delete<mDnsQueryCtx>(mResolveContext);
- mResolveContext = nullptr;
- }
- }
+ NxpChipDnssdResolveNoLongerNeeded(instanceName);
}
CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface)
@@ -479,460 +131,5 @@
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<mDnsQueryCtx>(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<intptr_t>(serviceContext));
- }
- else
- {
- Platform::Delete<mDnsQueryCtx>(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<intptr_t>(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 <instance>.<type>.<protocol>.<domain-name>. the <instance> 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 <instance>.<type>.<protocol>.<domain-name>. the <type> 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 <instance>.<type>.<protocol>.<domain-name>. the <type> 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 <hostname>.<domain-name>. the <hostname> 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 <type>.<protocol> the <type> 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 <type>.<protocol>. the .<protocol> 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;
- }
-
- 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<mDnsQueryCtx>(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<intptr_t>(tmpContext));
- }
- else
- {
- Platform::Delete<mDnsQueryCtx>(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<intptr_t>(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<intptr_t>(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<intptr_t>(mResolveContext));
-}
-
-static void DispatchBrowseEmpty(intptr_t context)
-{
- auto * browseContext = reinterpret_cast<mDnsQueryCtx *>(context);
- browseContext->mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error);
- Platform::Delete<mDnsQueryCtx>(browseContext);
- mBrowseContext = nullptr;
- bBrowseInProgress = false;
-}
-
-static void DispatchBrowse(intptr_t context)
-{
- auto * browseContext = reinterpret_cast<mDnsQueryCtx *>(context);
- browseContext->mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error);
- Platform::Delete<mDnsQueryCtx>(browseContext);
-}
-
-static void DispatchTxtResolve(intptr_t context)
-{
- mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(resolveContext));
- }
-}
-
-static void DispatchAddressResolve(intptr_t context)
-{
- otError error;
- mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(resolveContext));
- }
-}
-
-static void DispatchResolve(intptr_t context)
-{
- mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(context);
- Dnssd::DnssdService & service = resolveContext->mMdnsService;
- Span<Inet::IPAddress> ipAddrs;
-
- // Stop Address resolver, we have finished resolving the service
- otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo);
-
- if (service.mAddress.has_value())
- {
- ipAddrs = Span<Inet::IPAddress>(&*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<mDnsQueryCtx>(resolveContext);
-}
-
-static void DispatchResolveError(intptr_t context)
-{
- mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(context);
- Span<Inet::IPAddress> 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<mDnsQueryCtx>(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<intptr_t>(&resolveContext));
-}
-
} // namespace Dnssd
} // namespace chip
diff --git a/src/platform/nxp/common/DnssdImplBr.cpp b/src/platform/nxp/common/DnssdImplBr.cpp
new file mode 100644
index 0000000..6b84f1f
--- /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 <lib/support/CodeUtils.h>
+#include <lib/support/FixedBufferAllocator.h>
+#include <platform/CHIPDeviceLayer.h>
+#include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h>
+#include <platform/OpenThread/OpenThreadUtils.h>
+
+#include <platform/nxp/common/ConnectivityManagerImpl.h>
+
+#include <openthread/mdns.h>
+#include <openthread/srp_server.h>
+
+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<otMdnsService *>(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<intptr_t>(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<mDnsQueryCtx>(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<intptr_t>(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<intptr_t>(mBrowseContext));
+ }
+ else
+ {
+ Platform::Delete<mDnsQueryCtx>(mBrowseContext);
+ mBrowseContext = nullptr;
+ }
+ }
+ return error;
+}
+
+CHIP_ERROR NxpChipDnssdStopBrowse(intptr_t browseIdentifier)
+{
+ mDnsQueryCtx * browseContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(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<mDnsQueryCtx>(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<mDnsQueryCtx>(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<mDnsQueryCtx>(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<intptr_t>(serviceContext));
+ }
+ else
+ {
+ Platform::Delete<mDnsQueryCtx>(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<intptr_t>(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 <instance>.<type>.<protocol>.<domain-name>. the <instance> 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 <instance>.<type>.<protocol>.<domain-name>. the <type> 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 <instance>.<type>.<protocol>.<domain-name>. the <type> 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 <hostname>.<domain-name>. the <hostname> 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 <type>.<protocol> the <type> 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 <type>.<protocol>. the .<protocol> 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<mDnsQueryCtx>(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<intptr_t>(tmpContext));
+ }
+ else
+ {
+ Platform::Delete<mDnsQueryCtx>(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<intptr_t>(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<intptr_t>(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<intptr_t>(mResolveContext));
+}
+
+static void DispatchBrowseEmpty(intptr_t context)
+{
+ auto * browseContext = reinterpret_cast<mDnsQueryCtx *>(context);
+ browseContext->mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error);
+ Platform::Delete<mDnsQueryCtx>(browseContext);
+ mBrowseContext = nullptr;
+ bBrowseInProgress = false;
+}
+
+static void DispatchBrowse(intptr_t context)
+{
+ auto * browseContext = reinterpret_cast<mDnsQueryCtx *>(context);
+ browseContext->mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error);
+ Platform::Delete<mDnsQueryCtx>(browseContext);
+}
+
+static void DispatchTxtResolve(intptr_t context)
+{
+ mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(resolveContext));
+ }
+}
+
+static void DispatchAddressResolve(intptr_t context)
+{
+ otError error;
+ mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(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<intptr_t>(resolveContext));
+ }
+}
+
+static void DispatchResolve(intptr_t context)
+{
+ mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(context);
+ Dnssd::DnssdService & service = resolveContext->mMdnsService;
+ Span<Inet::IPAddress> ipAddrs;
+
+ // Stop Address resolver, we have finished resolving the service
+ otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo);
+
+ if (service.mAddress.has_value())
+ {
+ ipAddrs = Span<Inet::IPAddress>(&*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<mDnsQueryCtx>(resolveContext);
+}
+
+static void DispatchResolveError(intptr_t context)
+{
+ mDnsQueryCtx * resolveContext = reinterpret_cast<mDnsQueryCtx *>(context);
+ Span<Inet::IPAddress> 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<mDnsQueryCtx>(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<intptr_t>(&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 0000000..970a2c6
--- /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 <lib/dnssd/platform/Dnssd.h>
+
+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 447ef29..e80dd3c 100644
--- a/src/platform/nxp/rt/rw61x/BUILD.gn
+++ b/src/platform/nxp/rt/rw61x/BUILD.gn
@@ -34,7 +34,10 @@
}
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",
@@ -63,8 +66,10 @@
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_" ]
}
}
@@ -154,17 +159,33 @@
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",
]
- 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 += [
+ "../../../OpenThread/DnssdImpl.cpp",
+ "../../../OpenThread/OpenThreadDnssdImpl.cpp",
+ "../../../OpenThread/OpenThreadDnssdImpl.h",
+ "../../common/DnssdImpl.cpp",
+ "../../common/DnssdImplBr.cpp",
+ "../../common/DnssdImplBr.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 c17e7df..fe8c6b0 100644
--- a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp
+++ b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp
@@ -204,6 +204,7 @@
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 5561196..b9b34f2 100644
--- a/src/platform/nxp/rt/rw61x/args.gni
+++ b/src/platform/nxp/rt/rw61x/args.gni
@@ -42,6 +42,8 @@
# 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.
diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp
index 0a3248f..0a48082 160000
--- a/third_party/openthread/ot-nxp
+++ b/third_party/openthread/ot-nxp
@@ -1 +1 @@
-Subproject commit 0a3248f5c8ec5a9fd05541974872323f26d5182f
+Subproject commit 0a4808291289019d0930a6a63afd87c2983353f5
diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn
index 6d4854f..86c9f2f 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 @@
"${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" ]
@@ -57,6 +60,14 @@
"OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1",
"OT_APP_BR_LWIP_HOOKS_EN=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
@@ -89,6 +100,15 @@
"${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) {