diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md
index a11a552bf023a6..e23b2508a5ee54 100644
--- a/docs/zap_clusters.md
+++ b/docs/zap_clusters.md
@@ -113,6 +113,7 @@ Generally regenerate using one of:
| 1070 | 0x42E | TotalVolatileOrganicCompoundsConcentrationMeasurement |
| 1071 | 0x42F | RadonConcentrationMeasurement |
| 1105 | 0x451 | WiFiNetworkManagement |
+| 1107 | 0x453 | ThreadNetworkDirectory |
| 1283 | 0x503 | WakeOnLan |
| 1284 | 0x504 | Channel |
| 1285 | 0x505 | TargetNavigator |
diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml
index 9686aa74eed0d0..f6db1481074e3b 100644
--- a/src/app/zap-templates/zcl/data-model/all.xml
+++ b/src/app/zap-templates/zcl/data-model/all.xml
@@ -94,6 +94,7 @@
+
diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml
new file mode 100644
index 00000000000000..f802b7ab4452c0
--- /dev/null
+++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Network Infrastructure
+ Thread Network Directory
+ 0x0453
+ THREAD_NETWORK_DIRECTORY_CLUSTER
+ Manages the names and credentials of Thread networks visible to the user.
+
+ true
+ true
+
+
+
+
+
+ PreferredExtendedPanID
+
+
+
+
+ ThreadNetworks
+
+
+ ThreadNetworkTableSize
+
+
+ Adds an entry to the ThreadNetworks list.
+
+
+
+
+ Removes an entry from the ThreadNetworks list.
+
+
+
+
+ Retrieves a Thread Operational Dataset from the ThreadNetworks list.
+
+
+
+
+ This is the response to a GetOperationalDataset request.
+
+
+
+
+ This event SHALL be generated when an entry in ThreadNetworks is added, removed, or had its Operational Dataset changed.
+
+
+
+
+
diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json
index f3aa6ef0b47f48..30c14436667202 100644
--- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json
+++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json
@@ -116,6 +116,7 @@
"thermostat-cluster.xml",
"thermostat-user-interface-configuration-cluster.xml",
"thread-network-diagnostics-cluster.xml",
+ "thread-network-directory-cluster.xml",
"time-format-localization-cluster.xml",
"time-synchronization-cluster.xml",
"timer-cluster.xml",
diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json
index d85f850b2c9483..33955572d795ec 100644
--- a/src/app/zap-templates/zcl/zcl.json
+++ b/src/app/zap-templates/zcl/zcl.json
@@ -114,6 +114,7 @@
"thermostat-cluster.xml",
"thermostat-user-interface-configuration-cluster.xml",
"thread-network-diagnostics-cluster.xml",
+ "thread-network-directory-cluster.xml",
"time-format-localization-cluster.xml",
"time-synchronization-cluster.xml",
"timer-cluster.xml",
diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json
index d86979f40adc9e..67083c04d3177d 100644
--- a/src/app/zap_cluster_list.json
+++ b/src/app/zap_cluster_list.json
@@ -289,6 +289,7 @@
"THREAD_NETWORK_DIAGNOSTICS_CLUSTER": [
"thread-network-diagnostics-server"
],
+ "THREAD_NETWORK_DIRECTORY_CLUSTER": [],
"TIME_CLUSTER": [],
"TIME_FORMAT_LOCALIZATION_CLUSTER": ["time-format-localization-server"],
"TIME_SYNCHRONIZATION_CLUSTER": ["time-synchronization-server"],
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index e18d1cbe4a0193..ab2e0db009c888 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -7674,6 +7674,54 @@ cluster WiFiNetworkManagement = 1105 {
command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0;
}
+/** Manages the names and credentials of Thread networks visible to the user. */
+cluster ThreadNetworkDirectory = 1107 {
+ revision 1;
+
+ struct ThreadNetworkStruct {
+ int64u extendedPanID = 0;
+ char_string<16> networkName = 1;
+ int16u channel = 2;
+ }
+
+ info event access(read: operate) NetworkChanged = 0 {
+ int64u extendedPanID = 0;
+ }
+
+ attribute access(read: manage, write: manage) nullable int64u preferredExtendedPanID = 0;
+ readonly attribute access(read: operate) ThreadNetworkStruct threadNetworks[] = 1;
+ readonly attribute int8u threadNetworkTableSize = 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 AddNetworkRequest {
+ octet_string<254> operationalDataset = 0;
+ }
+
+ request struct RemoveNetworkRequest {
+ int64u extendedPanID = 0;
+ }
+
+ request struct GetOperationalDatasetRequest {
+ int64u extendedPanID = 0;
+ }
+
+ response struct OperationalDatasetResponse = 3 {
+ octet_string<254> operationalDataset = 0;
+ }
+
+ /** Adds an entry to the ThreadNetworks list. */
+ timed command access(invoke: manage) AddNetwork(AddNetworkRequest): DefaultSuccess = 0;
+ /** Removes an entry from the ThreadNetworks list. */
+ timed command access(invoke: manage) RemoveNetwork(RemoveNetworkRequest): DefaultSuccess = 1;
+ /** Retrieves a Thread Operational Dataset from the ThreadNetworks list. */
+ timed command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2;
+}
+
/** This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. */
cluster WakeOnLan = 1283 {
revision 1;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
index 7a6caeb9532993..7a16c3355daf4f 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
@@ -53083,6 +53083,362 @@ public void onSuccess(byte[] tlv) {
}
}
+ public static class ThreadNetworkDirectoryCluster extends BaseChipCluster {
+ public static final long CLUSTER_ID = 1107L;
+
+ private static final long PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID = 0L;
+ private static final long THREAD_NETWORKS_ATTRIBUTE_ID = 1L;
+ private static final long THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID = 2L;
+ private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L;
+ private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L;
+ private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L;
+ private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L;
+ private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L;
+ private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L;
+
+ public ThreadNetworkDirectoryCluster(long devicePtr, int endpointId) {
+ super(devicePtr, endpointId, CLUSTER_ID);
+ }
+
+ @Override
+ @Deprecated
+ public long initWithDevice(long devicePtr, int endpointId) {
+ return 0L;
+ }
+
+
+ public void addNetwork(DefaultClusterCallback callback, byte[] operationalDataset, int timedInvokeTimeoutMs) {
+ final long commandId = 0L;
+
+ ArrayList elements = new ArrayList<>();
+ final long operationalDatasetFieldID = 0L;
+ BaseTLVType operationalDatasettlvValue = new ByteArrayType(operationalDataset);
+ elements.add(new StructElement(operationalDatasetFieldID, operationalDatasettlvValue));
+
+ StructType commandArgs = new StructType(elements);
+ invoke(new InvokeCallbackImpl(callback) {
+ @Override
+ public void onResponse(StructType invokeStructValue) {
+ callback.onSuccess();
+ }}, commandId, commandArgs, timedInvokeTimeoutMs);
+ }
+
+
+ public void removeNetwork(DefaultClusterCallback callback, Long extendedPanID, int timedInvokeTimeoutMs) {
+ final long commandId = 1L;
+
+ ArrayList elements = new ArrayList<>();
+ final long extendedPanIDFieldID = 0L;
+ BaseTLVType extendedPanIDtlvValue = new UIntType(extendedPanID);
+ elements.add(new StructElement(extendedPanIDFieldID, extendedPanIDtlvValue));
+
+ StructType commandArgs = new StructType(elements);
+ invoke(new InvokeCallbackImpl(callback) {
+ @Override
+ public void onResponse(StructType invokeStructValue) {
+ callback.onSuccess();
+ }}, commandId, commandArgs, timedInvokeTimeoutMs);
+ }
+
+
+ public void getOperationalDataset(OperationalDatasetResponseCallback callback, Long extendedPanID, int timedInvokeTimeoutMs) {
+ final long commandId = 2L;
+
+ ArrayList elements = new ArrayList<>();
+ final long extendedPanIDFieldID = 0L;
+ BaseTLVType extendedPanIDtlvValue = new UIntType(extendedPanID);
+ elements.add(new StructElement(extendedPanIDFieldID, extendedPanIDtlvValue));
+
+ StructType commandArgs = new StructType(elements);
+ invoke(new InvokeCallbackImpl(callback) {
+ @Override
+ public void onResponse(StructType invokeStructValue) {
+ final long operationalDatasetFieldID = 0L;
+ byte[] operationalDataset = null;
+ for (StructElement element: invokeStructValue.value()) {
+ if (element.contextTagNum() == operationalDatasetFieldID) {
+ if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) {
+ ByteArrayType castingValue = element.value(ByteArrayType.class);
+ operationalDataset = castingValue.value(byte[].class);
+ }
+ }
+ }
+ callback.onSuccess(operationalDataset);
+ }}, commandId, commandArgs, timedInvokeTimeoutMs);
+ }
+
+ public interface OperationalDatasetResponseCallback extends BaseClusterCallback {
+ void onSuccess(byte[] operationalDataset);
+ }
+
+ public interface PreferredExtendedPanIDAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable Long value);
+ }
+
+ public interface ThreadNetworksAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface EventListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface AttributeListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public void readPreferredExtendedPanIDAttribute(
+ PreferredExtendedPanIDAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, true);
+ }
+
+ public void writePreferredExtendedPanIDAttribute(DefaultClusterCallback callback, Long value) {
+ writePreferredExtendedPanIDAttribute(callback, value, 0);
+ }
+
+ public void writePreferredExtendedPanIDAttribute(DefaultClusterCallback callback, Long value, int timedWriteTimeoutMs) {
+ BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType();
+ writeAttribute(new WriteAttributesCallbackImpl(callback), PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs);
+ }
+
+ public void subscribePreferredExtendedPanIDAttribute(
+ PreferredExtendedPanIDAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readThreadNetworksAttribute(
+ ThreadNetworksAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORKS_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, THREAD_NETWORKS_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeThreadNetworksAttribute(
+ ThreadNetworksAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORKS_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, THREAD_NETWORKS_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readThreadNetworkTableSizeAttribute(
+ IntegerAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeThreadNetworkTableSizeAttribute(
+ IntegerAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readGeneratedCommandListAttribute(
+ GeneratedCommandListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeGeneratedCommandListAttribute(
+ GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readAcceptedCommandListAttribute(
+ AcceptedCommandListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeAcceptedCommandListAttribute(
+ AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readEventListAttribute(
+ EventListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, EVENT_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeEventListAttribute(
+ EventListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readAttributeListAttribute(
+ AttributeListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeAttributeListAttribute(
+ AttributeListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readFeatureMapAttribute(
+ LongAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, FEATURE_MAP_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeFeatureMapAttribute(
+ LongAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readClusterRevisionAttribute(
+ IntegerAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CLUSTER_REVISION_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeClusterRevisionAttribute(
+ IntegerAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+ }
+
public static class WakeOnLanCluster extends BaseChipCluster {
public static final long CLUSTER_ID = 1283L;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java
index ce1a79c5a4a710..d25d80c3f791fc 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java
@@ -5584,6 +5584,52 @@ public String toString() {
return output.toString();
}
}
+public static class ThreadNetworkDirectoryClusterNetworkChangedEvent {
+ public Long extendedPanID;
+ private static final long EXTENDED_PAN_I_D_ID = 0L;
+
+ public ThreadNetworkDirectoryClusterNetworkChangedEvent(
+ Long extendedPanID
+ ) {
+ this.extendedPanID = extendedPanID;
+ }
+
+ public StructType encodeTlv() {
+ ArrayList values = new ArrayList<>();
+ values.add(new StructElement(EXTENDED_PAN_I_D_ID, new UIntType(extendedPanID)));
+
+ return new StructType(values);
+ }
+
+ public static ThreadNetworkDirectoryClusterNetworkChangedEvent decodeTlv(BaseTLVType tlvValue) {
+ if (tlvValue == null || tlvValue.type() != TLVType.Struct) {
+ return null;
+ }
+ Long extendedPanID = null;
+ for (StructElement element: ((StructType)tlvValue).value()) {
+ if (element.contextTagNum() == EXTENDED_PAN_I_D_ID) {
+ if (element.value(BaseTLVType.class).type() == TLVType.UInt) {
+ UIntType castingValue = element.value(UIntType.class);
+ extendedPanID = castingValue.value(Long.class);
+ }
+ }
+ }
+ return new ThreadNetworkDirectoryClusterNetworkChangedEvent(
+ extendedPanID
+ );
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ output.append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n");
+ output.append("\textendedPanID: ");
+ output.append(extendedPanID);
+ output.append("\n");
+ output.append("}\n");
+ return output.toString();
+ }
+}
public static class TargetNavigatorClusterTargetUpdatedEvent {
public ArrayList targetList;
public Integer currentTarget;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
index 7730f05efe734a..c8d48cce340e23 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
@@ -9277,6 +9277,82 @@ public String toString() {
return output.toString();
}
}
+public static class ThreadNetworkDirectoryClusterThreadNetworkStruct {
+ public Long extendedPanID;
+ public String networkName;
+ public Integer channel;
+ private static final long EXTENDED_PAN_I_D_ID = 0L;
+ private static final long NETWORK_NAME_ID = 1L;
+ private static final long CHANNEL_ID = 2L;
+
+ public ThreadNetworkDirectoryClusterThreadNetworkStruct(
+ Long extendedPanID,
+ String networkName,
+ Integer channel
+ ) {
+ this.extendedPanID = extendedPanID;
+ this.networkName = networkName;
+ this.channel = channel;
+ }
+
+ public StructType encodeTlv() {
+ ArrayList values = new ArrayList<>();
+ values.add(new StructElement(EXTENDED_PAN_I_D_ID, new UIntType(extendedPanID)));
+ values.add(new StructElement(NETWORK_NAME_ID, new StringType(networkName)));
+ values.add(new StructElement(CHANNEL_ID, new UIntType(channel)));
+
+ return new StructType(values);
+ }
+
+ public static ThreadNetworkDirectoryClusterThreadNetworkStruct decodeTlv(BaseTLVType tlvValue) {
+ if (tlvValue == null || tlvValue.type() != TLVType.Struct) {
+ return null;
+ }
+ Long extendedPanID = null;
+ String networkName = null;
+ Integer channel = null;
+ for (StructElement element: ((StructType)tlvValue).value()) {
+ if (element.contextTagNum() == EXTENDED_PAN_I_D_ID) {
+ if (element.value(BaseTLVType.class).type() == TLVType.UInt) {
+ UIntType castingValue = element.value(UIntType.class);
+ extendedPanID = castingValue.value(Long.class);
+ }
+ } else if (element.contextTagNum() == NETWORK_NAME_ID) {
+ if (element.value(BaseTLVType.class).type() == TLVType.String) {
+ StringType castingValue = element.value(StringType.class);
+ networkName = castingValue.value(String.class);
+ }
+ } else if (element.contextTagNum() == CHANNEL_ID) {
+ if (element.value(BaseTLVType.class).type() == TLVType.UInt) {
+ UIntType castingValue = element.value(UIntType.class);
+ channel = castingValue.value(Integer.class);
+ }
+ }
+ }
+ return new ThreadNetworkDirectoryClusterThreadNetworkStruct(
+ extendedPanID,
+ networkName,
+ channel
+ );
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ output.append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n");
+ output.append("\textendedPanID: ");
+ output.append(extendedPanID);
+ output.append("\n");
+ output.append("\tnetworkName: ");
+ output.append(networkName);
+ output.append("\n");
+ output.append("\tchannel: ");
+ output.append(channel);
+ output.append("\n");
+ output.append("}\n");
+ return output.toString();
+ }
+}
public static class ChannelClusterProgramCastStruct {
public String name;
public String role;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
index 506d7386935c47..cd89fd9df6d472 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
@@ -331,6 +331,9 @@ public static BaseCluster getCluster(long clusterId) {
if (clusterId == WiFiNetworkManagement.ID) {
return new WiFiNetworkManagement();
}
+ if (clusterId == ThreadNetworkDirectory.ID) {
+ return new ThreadNetworkDirectory();
+ }
if (clusterId == WakeOnLan.ID) {
return new WakeOnLan();
}
@@ -14418,6 +14421,164 @@ public long getCommandID(String name) throws IllegalArgumentException {
return Command.valueOf(name).getID();
}
}
+ public static class ThreadNetworkDirectory implements BaseCluster {
+ public static final long ID = 1107L;
+ public long getID() {
+ return ID;
+ }
+
+ public enum Attribute {
+ PreferredExtendedPanID(0L),
+ ThreadNetworks(1L),
+ ThreadNetworkTableSize(2L),
+ GeneratedCommandList(65528L),
+ AcceptedCommandList(65529L),
+ EventList(65530L),
+ AttributeList(65531L),
+ FeatureMap(65532L),
+ ClusterRevision(65533L),;
+ private final long id;
+ Attribute(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Attribute value(long id) throws NoSuchFieldError {
+ for (Attribute attribute : Attribute.values()) {
+ if (attribute.getID() == id) {
+ return attribute;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }
+
+ public enum Event {
+ NetworkChanged(0L),;
+ private final long id;
+ Event(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Event value(long id) throws NoSuchFieldError {
+ for (Event event : Event.values()) {
+ if (event.getID() == id) {
+ return event;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }
+
+ public enum Command {
+ AddNetwork(0L),
+ RemoveNetwork(1L),
+ GetOperationalDataset(2L),;
+ private final long id;
+ Command(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Command value(long id) throws NoSuchFieldError {
+ for (Command command : Command.values()) {
+ if (command.getID() == id) {
+ return command;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }public enum AddNetworkCommandField {OperationalDataset(0),;
+ private final int id;
+ AddNetworkCommandField(int id) {
+ this.id = id;
+ }
+
+ public int getID() {
+ return id;
+ }
+ public static AddNetworkCommandField value(int id) throws NoSuchFieldError {
+ for (AddNetworkCommandField field : AddNetworkCommandField.values()) {
+ if (field.getID() == id) {
+ return field;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }public enum RemoveNetworkCommandField {ExtendedPanID(0),;
+ private final int id;
+ RemoveNetworkCommandField(int id) {
+ this.id = id;
+ }
+
+ public int getID() {
+ return id;
+ }
+ public static RemoveNetworkCommandField value(int id) throws NoSuchFieldError {
+ for (RemoveNetworkCommandField field : RemoveNetworkCommandField.values()) {
+ if (field.getID() == id) {
+ return field;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }public enum GetOperationalDatasetCommandField {ExtendedPanID(0),;
+ private final int id;
+ GetOperationalDatasetCommandField(int id) {
+ this.id = id;
+ }
+
+ public int getID() {
+ return id;
+ }
+ public static GetOperationalDatasetCommandField value(int id) throws NoSuchFieldError {
+ for (GetOperationalDatasetCommandField field : GetOperationalDatasetCommandField.values()) {
+ if (field.getID() == id) {
+ return field;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }@Override
+ public String getAttributeName(long id) throws NoSuchFieldError {
+ return Attribute.value(id).toString();
+ }
+
+ @Override
+ public String getEventName(long id) throws NoSuchFieldError {
+ return Event.value(id).toString();
+ }
+
+ @Override
+ public String getCommandName(long id) throws NoSuchFieldError {
+ return Command.value(id).toString();
+ }
+
+ @Override
+ public long getAttributeID(String name) throws IllegalArgumentException {
+ return Attribute.valueOf(name).getID();
+ }
+
+ @Override
+ public long getEventID(String name) throws IllegalArgumentException {
+ return Event.valueOf(name).getID();
+ }
+
+ @Override
+ public long getCommandID(String name) throws IllegalArgumentException {
+ return Command.valueOf(name).getID();
+ }
+ }
public static class WakeOnLan implements BaseCluster {
public static final long ID = 1283L;
public long getID() {
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
index d7c4134c812d9d..47ee02f5ede86c 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
@@ -17426,6 +17426,154 @@ public void onError(Exception ex) {
}
}
+
+ public static class DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback implements ChipClusters.ThreadNetworkDirectoryCluster.OperationalDatasetResponseCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(byte[] operationalDataset) {
+ Map responseValues = new LinkedHashMap<>();
+
+ CommandResponseInfo operationalDatasetResponseValue = new CommandResponseInfo("operationalDataset", "byte[]");
+ responseValues.put(operationalDatasetResponseValue, operationalDataset);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception error) {
+ callback.onFailure(error);
+ }
+ }
+ public static class DelegatedThreadNetworkDirectoryClusterPreferredExtendedPanIDAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.PreferredExtendedPanIDAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable Long value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedThreadNetworkDirectoryClusterThreadNetworksAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.ThreadNetworksAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedThreadNetworkDirectoryClusterGeneratedCommandListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedThreadNetworkDirectoryClusterAcceptedCommandListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedThreadNetworkDirectoryClusterEventListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.EventListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedThreadNetworkDirectoryClusterAttributeListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.AttributeListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
public static class DelegatedWakeOnLanClusterGeneratedCommandListAttributeCallback implements ChipClusters.WakeOnLanCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
@@ -21308,6 +21456,10 @@ public Map initializeClusterMap() {
(ptr, endpointId) -> new ChipClusters.WiFiNetworkManagementCluster(ptr, endpointId), new HashMap<>());
clusterMap.put("wiFiNetworkManagement", wiFiNetworkManagementClusterInfo);
+ ClusterInfo threadNetworkDirectoryClusterInfo = new ClusterInfo(
+ (ptr, endpointId) -> new ChipClusters.ThreadNetworkDirectoryCluster(ptr, endpointId), new HashMap<>());
+ clusterMap.put("threadNetworkDirectory", threadNetworkDirectoryClusterInfo);
+
ClusterInfo wakeOnLanClusterInfo = new ClusterInfo(
(ptr, endpointId) -> new ChipClusters.WakeOnLanCluster(ptr, endpointId), new HashMap<>());
clusterMap.put("wakeOnLan", wakeOnLanClusterInfo);
@@ -21485,6 +21637,7 @@ public void combineCommand(Map destination, Map> getCommandMap() {
commandMap.put("wiFiNetworkManagement", wiFiNetworkManagementClusterInteractionInfoMap);
+ Map threadNetworkDirectoryClusterInteractionInfoMap = new LinkedHashMap<>();
+
+ Map threadNetworkDirectoryaddNetworkCommandParams = new LinkedHashMap();
+
+ CommandParameterInfo threadNetworkDirectoryaddNetworkoperationalDatasetCommandParameterInfo = new CommandParameterInfo("operationalDataset", byte[].class, byte[].class);
+ threadNetworkDirectoryaddNetworkCommandParams.put("operationalDataset",threadNetworkDirectoryaddNetworkoperationalDatasetCommandParameterInfo);
+ InteractionInfo threadNetworkDirectoryaddNetworkInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster)
+ .addNetwork((DefaultClusterCallback) callback
+ , (byte[])
+ commandArguments.get("operationalDataset"), 10000
+ );
+ },
+ () -> new DelegatedDefaultClusterCallback(),
+ threadNetworkDirectoryaddNetworkCommandParams
+ );
+ threadNetworkDirectoryClusterInteractionInfoMap.put("addNetwork", threadNetworkDirectoryaddNetworkInteractionInfo);
+
+ Map threadNetworkDirectoryremoveNetworkCommandParams = new LinkedHashMap();
+
+ CommandParameterInfo threadNetworkDirectoryremoveNetworkextendedPanIDCommandParameterInfo = new CommandParameterInfo("extendedPanID", Long.class, Long.class);
+ threadNetworkDirectoryremoveNetworkCommandParams.put("extendedPanID",threadNetworkDirectoryremoveNetworkextendedPanIDCommandParameterInfo);
+ InteractionInfo threadNetworkDirectoryremoveNetworkInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster)
+ .removeNetwork((DefaultClusterCallback) callback
+ , (Long)
+ commandArguments.get("extendedPanID"), 10000
+ );
+ },
+ () -> new DelegatedDefaultClusterCallback(),
+ threadNetworkDirectoryremoveNetworkCommandParams
+ );
+ threadNetworkDirectoryClusterInteractionInfoMap.put("removeNetwork", threadNetworkDirectoryremoveNetworkInteractionInfo);
+
+ Map threadNetworkDirectorygetOperationalDatasetCommandParams = new LinkedHashMap();
+
+ CommandParameterInfo threadNetworkDirectorygetOperationalDatasetextendedPanIDCommandParameterInfo = new CommandParameterInfo("extendedPanID", Long.class, Long.class);
+ threadNetworkDirectorygetOperationalDatasetCommandParams.put("extendedPanID",threadNetworkDirectorygetOperationalDatasetextendedPanIDCommandParameterInfo);
+ InteractionInfo threadNetworkDirectorygetOperationalDatasetInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster)
+ .getOperationalDataset((ChipClusters.ThreadNetworkDirectoryCluster.OperationalDatasetResponseCallback) callback
+ , (Long)
+ commandArguments.get("extendedPanID")
+
+ , 10000);
+ },
+ () -> new DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback(),
+ threadNetworkDirectorygetOperationalDatasetCommandParams
+ );
+ threadNetworkDirectoryClusterInteractionInfoMap.put("getOperationalDataset", threadNetworkDirectorygetOperationalDatasetInteractionInfo);
+
+ commandMap.put("threadNetworkDirectory", threadNetworkDirectoryClusterInteractionInfoMap);
+
Map wakeOnLanClusterInteractionInfoMap = new LinkedHashMap<>();
commandMap.put("wakeOnLan", wakeOnLanClusterInteractionInfoMap);
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
index e75473bc0869b8..c607d8deca891a 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
@@ -16610,6 +16610,109 @@ private static Map readWiFiNetworkManagementInteraction
return result;
}
+ private static Map readThreadNetworkDirectoryInteractionInfo() {
+ Map result = new LinkedHashMap<>();Map readThreadNetworkDirectoryPreferredExtendedPanIDCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readPreferredExtendedPanIDAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.PreferredExtendedPanIDAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterPreferredExtendedPanIDAttributeCallback(),
+ readThreadNetworkDirectoryPreferredExtendedPanIDCommandParams
+ );
+ result.put("readPreferredExtendedPanIDAttribute", readThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryThreadNetworksCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryThreadNetworksAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readThreadNetworksAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.ThreadNetworksAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterThreadNetworksAttributeCallback(),
+ readThreadNetworkDirectoryThreadNetworksCommandParams
+ );
+ result.put("readThreadNetworksAttribute", readThreadNetworkDirectoryThreadNetworksAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryThreadNetworkTableSizeCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryThreadNetworkTableSizeAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readThreadNetworkTableSizeAttribute(
+ (ChipClusters.IntegerAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(),
+ readThreadNetworkDirectoryThreadNetworkTableSizeCommandParams
+ );
+ result.put("readThreadNetworkTableSizeAttribute", readThreadNetworkDirectoryThreadNetworkTableSizeAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryGeneratedCommandListCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryGeneratedCommandListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readGeneratedCommandListAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.GeneratedCommandListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterGeneratedCommandListAttributeCallback(),
+ readThreadNetworkDirectoryGeneratedCommandListCommandParams
+ );
+ result.put("readGeneratedCommandListAttribute", readThreadNetworkDirectoryGeneratedCommandListAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryAcceptedCommandListCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryAcceptedCommandListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readAcceptedCommandListAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.AcceptedCommandListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterAcceptedCommandListAttributeCallback(),
+ readThreadNetworkDirectoryAcceptedCommandListCommandParams
+ );
+ result.put("readAcceptedCommandListAttribute", readThreadNetworkDirectoryAcceptedCommandListAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryEventListCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryEventListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readEventListAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.EventListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterEventListAttributeCallback(),
+ readThreadNetworkDirectoryEventListCommandParams
+ );
+ result.put("readEventListAttribute", readThreadNetworkDirectoryEventListAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryAttributeListCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryAttributeListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readAttributeListAttribute(
+ (ChipClusters.ThreadNetworkDirectoryCluster.AttributeListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterAttributeListAttributeCallback(),
+ readThreadNetworkDirectoryAttributeListCommandParams
+ );
+ result.put("readAttributeListAttribute", readThreadNetworkDirectoryAttributeListAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryFeatureMapCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryFeatureMapAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readFeatureMapAttribute(
+ (ChipClusters.LongAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(),
+ readThreadNetworkDirectoryFeatureMapCommandParams
+ );
+ result.put("readFeatureMapAttribute", readThreadNetworkDirectoryFeatureMapAttributeInteractionInfo);
+ Map readThreadNetworkDirectoryClusterRevisionCommandParams = new LinkedHashMap();
+ InteractionInfo readThreadNetworkDirectoryClusterRevisionAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readClusterRevisionAttribute(
+ (ChipClusters.IntegerAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(),
+ readThreadNetworkDirectoryClusterRevisionCommandParams
+ );
+ result.put("readClusterRevisionAttribute", readThreadNetworkDirectoryClusterRevisionAttributeInteractionInfo);
+
+ return result;
+ }
private static Map readWakeOnLanInteractionInfo() {
Map result = new LinkedHashMap<>();Map readWakeOnLanMACAddressCommandParams = new LinkedHashMap();
InteractionInfo readWakeOnLanMACAddressAttributeInteractionInfo = new InteractionInfo(
@@ -20670,6 +20773,7 @@ public Map> getReadAttributeMap() {
put("totalVolatileOrganicCompoundsConcentrationMeasurement", readTotalVolatileOrganicCompoundsConcentrationMeasurementInteractionInfo());
put("radonConcentrationMeasurement", readRadonConcentrationMeasurementInteractionInfo());
put("wiFiNetworkManagement", readWiFiNetworkManagementInteractionInfo());
+ put("threadNetworkDirectory", readThreadNetworkDirectoryInteractionInfo());
put("wakeOnLan", readWakeOnLanInteractionInfo());
put("channel", readChannelInteractionInfo());
put("targetNavigator", readTargetNavigatorInteractionInfo());
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
index 93f3a7790eb8fa..61b492fde61abd 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
@@ -3638,6 +3638,30 @@ public Map> getWriteAttributeMap() {
writeAttributeMap.put("radonConcentrationMeasurement", writeRadonConcentrationMeasurementInteractionInfo);
Map writeWiFiNetworkManagementInteractionInfo = new LinkedHashMap<>();
writeAttributeMap.put("wiFiNetworkManagement", writeWiFiNetworkManagementInteractionInfo);
+ Map writeThreadNetworkDirectoryInteractionInfo = new LinkedHashMap<>();
+ Map writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams = new LinkedHashMap();
+ CommandParameterInfo threadNetworkDirectorypreferredExtendedPanIDCommandParameterInfo =
+ new CommandParameterInfo(
+ "value",
+ Long.class,
+ Long.class
+ );
+ writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams.put(
+ "value",
+ threadNetworkDirectorypreferredExtendedPanIDCommandParameterInfo
+ );
+ InteractionInfo writeThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).writePreferredExtendedPanIDAttribute(
+ (DefaultClusterCallback) callback,
+ (Long) commandArguments.get("value")
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(),
+ writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams
+ );
+ writeThreadNetworkDirectoryInteractionInfo.put("writePreferredExtendedPanIDAttribute", writeThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo);
+ writeAttributeMap.put("threadNetworkDirectory", writeThreadNetworkDirectoryInteractionInfo);
Map writeWakeOnLanInteractionInfo = new LinkedHashMap<>();
writeAttributeMap.put("wakeOnLan", writeWakeOnLanInteractionInfo);
Map writeChannelInteractionInfo = new LinkedHashMap<>();
diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt
new file mode 100644
index 00000000000000..df86cf8e4f6f47
--- /dev/null
+++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package chip.devicecontroller.cluster.eventstructs
+
+import chip.devicecontroller.cluster.*
+import matter.tlv.ContextSpecificTag
+import matter.tlv.Tag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class ThreadNetworkDirectoryClusterNetworkChangedEvent(val extendedPanID: ULong) {
+ override fun toString(): String = buildString {
+ append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n")
+ append("\textendedPanID : $extendedPanID\n")
+ append("}\n")
+ }
+
+ fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
+ tlvWriter.apply {
+ startStructure(tlvTag)
+ put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID)
+ endStructure()
+ }
+ }
+
+ companion object {
+ private const val TAG_EXTENDED_PAN_I_D = 0
+
+ fun fromTlv(
+ tlvTag: Tag,
+ tlvReader: TlvReader
+ ): ThreadNetworkDirectoryClusterNetworkChangedEvent {
+ tlvReader.enterStructure(tlvTag)
+ val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D))
+
+ tlvReader.exitContainer()
+
+ return ThreadNetworkDirectoryClusterNetworkChangedEvent(extendedPanID)
+ }
+ }
+}
diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni
index 34fd21bb27d770..4f8bcd19a75f60 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni
+++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni
@@ -127,6 +127,7 @@ structs_sources = [
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterSecurityPolicy.kt",
+ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterDSTOffsetStruct.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterFabricScopedTrustedTimeSourceStruct.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterTimeZoneStruct.kt",
@@ -211,6 +212,7 @@ eventstructs_sources = [
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TargetNavigatorClusterTargetUpdatedEvent.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt",
+ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TimeSynchronizationClusterDSTStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TimeSynchronizationClusterTimeZoneStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/UnitTestingClusterTestDifferentVendorMeiEventEvent.kt",
diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt
new file mode 100644
index 00000000000000..ffc00a108110d7
--- /dev/null
+++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package chip.devicecontroller.cluster.structs
+
+import chip.devicecontroller.cluster.*
+import matter.tlv.ContextSpecificTag
+import matter.tlv.Tag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class ThreadNetworkDirectoryClusterThreadNetworkStruct(
+ val extendedPanID: ULong,
+ val networkName: String,
+ val channel: UInt
+) {
+ override fun toString(): String = buildString {
+ append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n")
+ append("\textendedPanID : $extendedPanID\n")
+ append("\tnetworkName : $networkName\n")
+ append("\tchannel : $channel\n")
+ append("}\n")
+ }
+
+ fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
+ tlvWriter.apply {
+ startStructure(tlvTag)
+ put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID)
+ put(ContextSpecificTag(TAG_NETWORK_NAME), networkName)
+ put(ContextSpecificTag(TAG_CHANNEL), channel)
+ endStructure()
+ }
+ }
+
+ companion object {
+ private const val TAG_EXTENDED_PAN_I_D = 0
+ private const val TAG_NETWORK_NAME = 1
+ private const val TAG_CHANNEL = 2
+
+ fun fromTlv(
+ tlvTag: Tag,
+ tlvReader: TlvReader
+ ): ThreadNetworkDirectoryClusterThreadNetworkStruct {
+ tlvReader.enterStructure(tlvTag)
+ val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D))
+ val networkName = tlvReader.getString(ContextSpecificTag(TAG_NETWORK_NAME))
+ val channel = tlvReader.getUInt(ContextSpecificTag(TAG_CHANNEL))
+
+ tlvReader.exitContainer()
+
+ return ThreadNetworkDirectoryClusterThreadNetworkStruct(extendedPanID, networkName, channel)
+ }
+ }
+}
diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt
new file mode 100644
index 00000000000000..8695d588b06d9b
--- /dev/null
+++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt
@@ -0,0 +1,1074 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package matter.controller.cluster.clusters
+
+import java.time.Duration
+import java.util.logging.Level
+import java.util.logging.Logger
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.transform
+import matter.controller.InvokeRequest
+import matter.controller.InvokeResponse
+import matter.controller.MatterController
+import matter.controller.ReadData
+import matter.controller.ReadRequest
+import matter.controller.SubscribeRequest
+import matter.controller.SubscriptionState
+import matter.controller.UByteSubscriptionState
+import matter.controller.UIntSubscriptionState
+import matter.controller.UShortSubscriptionState
+import matter.controller.WriteRequest
+import matter.controller.WriteRequests
+import matter.controller.WriteResponse
+import matter.controller.cluster.structs.*
+import matter.controller.model.AttributePath
+import matter.controller.model.CommandPath
+import matter.tlv.AnonymousTag
+import matter.tlv.ContextSpecificTag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class ThreadNetworkDirectoryCluster(
+ private val controller: MatterController,
+ private val endpointId: UShort
+) {
+ class OperationalDatasetResponse(val operationalDataset: ByteArray)
+
+ class PreferredExtendedPanIDAttribute(val value: ULong?)
+
+ sealed class PreferredExtendedPanIDAttributeSubscriptionState {
+ data class Success(val value: ULong?) : PreferredExtendedPanIDAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : PreferredExtendedPanIDAttributeSubscriptionState()
+
+ object SubscriptionEstablished : PreferredExtendedPanIDAttributeSubscriptionState()
+ }
+
+ class ThreadNetworksAttribute(val value: List)
+
+ sealed class ThreadNetworksAttributeSubscriptionState {
+ data class Success(val value: List) :
+ ThreadNetworksAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : ThreadNetworksAttributeSubscriptionState()
+
+ object SubscriptionEstablished : ThreadNetworksAttributeSubscriptionState()
+ }
+
+ class GeneratedCommandListAttribute(val value: List)
+
+ sealed class GeneratedCommandListAttributeSubscriptionState {
+ data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState()
+ }
+
+ class AcceptedCommandListAttribute(val value: List)
+
+ sealed class AcceptedCommandListAttributeSubscriptionState {
+ data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState()
+ }
+
+ class EventListAttribute(val value: List)
+
+ sealed class EventListAttributeSubscriptionState {
+ data class Success(val value: List) : EventListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : EventListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : EventListAttributeSubscriptionState()
+ }
+
+ class AttributeListAttribute(val value: List)
+
+ sealed class AttributeListAttributeSubscriptionState {
+ data class Success(val value: List) : AttributeListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : AttributeListAttributeSubscriptionState()
+ }
+
+ suspend fun addNetwork(operationalDataset: ByteArray, timedInvokeTimeout: Duration) {
+ val commandId: UInt = 0u
+
+ val tlvWriter = TlvWriter()
+ tlvWriter.startStructure(AnonymousTag)
+
+ val TAG_OPERATIONAL_DATASET_REQ: Int = 0
+ tlvWriter.put(ContextSpecificTag(TAG_OPERATIONAL_DATASET_REQ), operationalDataset)
+ tlvWriter.endStructure()
+
+ val request: InvokeRequest =
+ InvokeRequest(
+ CommandPath(endpointId, clusterId = CLUSTER_ID, commandId),
+ tlvPayload = tlvWriter.getEncoded(),
+ timedRequest = timedInvokeTimeout
+ )
+
+ val response: InvokeResponse = controller.invoke(request)
+ logger.log(Level.FINE, "Invoke command succeeded: ${response}")
+ }
+
+ suspend fun removeNetwork(extendedPanID: ULong, timedInvokeTimeout: Duration) {
+ val commandId: UInt = 1u
+
+ val tlvWriter = TlvWriter()
+ tlvWriter.startStructure(AnonymousTag)
+
+ val TAG_EXTENDED_PAN_I_D_REQ: Int = 0
+ tlvWriter.put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D_REQ), extendedPanID)
+ tlvWriter.endStructure()
+
+ val request: InvokeRequest =
+ InvokeRequest(
+ CommandPath(endpointId, clusterId = CLUSTER_ID, commandId),
+ tlvPayload = tlvWriter.getEncoded(),
+ timedRequest = timedInvokeTimeout
+ )
+
+ val response: InvokeResponse = controller.invoke(request)
+ logger.log(Level.FINE, "Invoke command succeeded: ${response}")
+ }
+
+ suspend fun getOperationalDataset(
+ extendedPanID: ULong,
+ timedInvokeTimeout: Duration
+ ): OperationalDatasetResponse {
+ val commandId: UInt = 2u
+
+ val tlvWriter = TlvWriter()
+ tlvWriter.startStructure(AnonymousTag)
+
+ val TAG_EXTENDED_PAN_I_D_REQ: Int = 0
+ tlvWriter.put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D_REQ), extendedPanID)
+ tlvWriter.endStructure()
+
+ val request: InvokeRequest =
+ InvokeRequest(
+ CommandPath(endpointId, clusterId = CLUSTER_ID, commandId),
+ tlvPayload = tlvWriter.getEncoded(),
+ timedRequest = timedInvokeTimeout
+ )
+
+ val response: InvokeResponse = controller.invoke(request)
+ logger.log(Level.FINE, "Invoke command succeeded: ${response}")
+
+ val tlvReader = TlvReader(response.payload)
+ tlvReader.enterStructure(AnonymousTag)
+ val TAG_OPERATIONAL_DATASET: Int = 0
+ var operationalDataset_decoded: ByteArray? = null
+
+ while (!tlvReader.isEndOfContainer()) {
+ val tag = tlvReader.peekElement().tag
+
+ if (tag == ContextSpecificTag(TAG_OPERATIONAL_DATASET)) {
+ operationalDataset_decoded = tlvReader.getByteArray(tag)
+ } else {
+ tlvReader.skipElement()
+ }
+ }
+
+ if (operationalDataset_decoded == null) {
+ throw IllegalStateException("operationalDataset not found in TLV")
+ }
+
+ tlvReader.exitContainer()
+
+ return OperationalDatasetResponse(operationalDataset_decoded)
+ }
+
+ suspend fun readPreferredExtendedPanIDAttribute(): PreferredExtendedPanIDAttribute {
+ val ATTRIBUTE_ID: UInt = 0u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Preferredextendedpanid attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: ULong? =
+ if (!tlvReader.isNull()) {
+ tlvReader.getULong(AnonymousTag)
+ } else {
+ tlvReader.getNull(AnonymousTag)
+ null
+ }
+
+ return PreferredExtendedPanIDAttribute(decodedValue)
+ }
+
+ suspend fun writePreferredExtendedPanIDAttribute(
+ value: ULong,
+ timedWriteTimeout: Duration? = null
+ ) {
+ val ATTRIBUTE_ID: UInt = 0u
+
+ val tlvWriter = TlvWriter()
+ tlvWriter.put(AnonymousTag, value)
+
+ val writeRequests: WriteRequests =
+ WriteRequests(
+ requests =
+ listOf(
+ WriteRequest(
+ attributePath =
+ AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID),
+ tlvPayload = tlvWriter.getEncoded()
+ )
+ ),
+ timedRequest = timedWriteTimeout
+ )
+
+ val response: WriteResponse = controller.write(writeRequests)
+
+ when (response) {
+ is WriteResponse.Success -> {
+ logger.log(Level.FINE, "Write command succeeded")
+ }
+ is WriteResponse.PartialWriteFailure -> {
+ val aggregatedErrorMessage =
+ response.failures.joinToString("\n") { failure ->
+ "Error at ${failure.attributePath}: ${failure.ex.message}"
+ }
+
+ response.failures.forEach { failure ->
+ logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}")
+ }
+
+ throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage")
+ }
+ }
+ }
+
+ suspend fun subscribePreferredExtendedPanIDAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 0u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ PreferredExtendedPanIDAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Preferredextendedpanid attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: ULong? =
+ if (!tlvReader.isNull()) {
+ tlvReader.getULong(AnonymousTag)
+ } else {
+ tlvReader.getNull(AnonymousTag)
+ null
+ }
+
+ decodedValue?.let { emit(PreferredExtendedPanIDAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(PreferredExtendedPanIDAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readThreadNetworksAttribute(): ThreadNetworksAttribute {
+ val ATTRIBUTE_ID: UInt = 1u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Threadnetworks attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(ThreadNetworkDirectoryClusterThreadNetworkStruct.fromTlv(AnonymousTag, tlvReader))
+ }
+ tlvReader.exitContainer()
+ }
+
+ return ThreadNetworksAttribute(decodedValue)
+ }
+
+ suspend fun subscribeThreadNetworksAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 1u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ ThreadNetworksAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Threadnetworks attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(
+ ThreadNetworkDirectoryClusterThreadNetworkStruct.fromTlv(AnonymousTag, tlvReader)
+ )
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(ThreadNetworksAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(ThreadNetworksAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readThreadNetworkTableSizeAttribute(): UByte {
+ val ATTRIBUTE_ID: UInt = 2u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Threadnetworktablesize attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UByte = tlvReader.getUByte(AnonymousTag)
+
+ return decodedValue
+ }
+
+ suspend fun subscribeThreadNetworkTableSizeAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 2u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UByteSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Threadnetworktablesize attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UByte = tlvReader.getUByte(AnonymousTag)
+
+ emit(UByteSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UByteSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute {
+ val ATTRIBUTE_ID: UInt = 65528u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ return GeneratedCommandListAttribute(decodedValue)
+ }
+
+ suspend fun subscribeGeneratedCommandListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65528u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ GeneratedCommandListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Generatedcommandlist attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute {
+ val ATTRIBUTE_ID: UInt = 65529u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ return AcceptedCommandListAttribute(decodedValue)
+ }
+
+ suspend fun subscribeAcceptedCommandListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65529u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ AcceptedCommandListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Acceptedcommandlist attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readEventListAttribute(): EventListAttribute {
+ val ATTRIBUTE_ID: UInt = 65530u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Eventlist attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ return EventListAttribute(decodedValue)
+ }
+
+ suspend fun subscribeEventListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65530u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ EventListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(EventListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(EventListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readAttributeListAttribute(): AttributeListAttribute {
+ val ATTRIBUTE_ID: UInt = 65531u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Attributelist attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ return AttributeListAttribute(decodedValue)
+ }
+
+ suspend fun subscribeAttributeListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65531u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ AttributeListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(AttributeListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readFeatureMapAttribute(): UInt {
+ val ATTRIBUTE_ID: UInt = 65532u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Featuremap attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UInt = tlvReader.getUInt(AnonymousTag)
+
+ return decodedValue
+ }
+
+ suspend fun subscribeFeatureMapAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65532u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UIntSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UInt = tlvReader.getUInt(AnonymousTag)
+
+ emit(UIntSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UIntSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readClusterRevisionAttribute(): UShort {
+ val ATTRIBUTE_ID: UInt = 65533u
+
+ val attributePath =
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+
+ val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath))
+
+ val response = controller.read(readRequest)
+
+ if (response.successes.isEmpty()) {
+ logger.log(Level.WARNING, "Read command failed")
+ throw IllegalStateException("Read command failed with failures: ${response.failures}")
+ }
+
+ logger.log(Level.FINE, "Read command succeeded")
+
+ val attributeData =
+ response.successes.filterIsInstance().firstOrNull {
+ it.path.attributeId == ATTRIBUTE_ID
+ }
+
+ requireNotNull(attributeData) { "Clusterrevision attribute not found in response" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UShort = tlvReader.getUShort(AnonymousTag)
+
+ return decodedValue
+ }
+
+ suspend fun subscribeClusterRevisionAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65533u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UShortSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Clusterrevision attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UShort = tlvReader.getUShort(AnonymousTag)
+
+ emit(UShortSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UShortSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ companion object {
+ private val logger = Logger.getLogger(ThreadNetworkDirectoryCluster::class.java.name)
+ const val CLUSTER_ID: UInt = 1107u
+ }
+}
diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt
new file mode 100644
index 00000000000000..8200ee623c2362
--- /dev/null
+++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package matter.controller.cluster.eventstructs
+
+import matter.controller.cluster.*
+import matter.tlv.ContextSpecificTag
+import matter.tlv.Tag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class ThreadNetworkDirectoryClusterNetworkChangedEvent(val extendedPanID: ULong) {
+ override fun toString(): String = buildString {
+ append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n")
+ append("\textendedPanID : $extendedPanID\n")
+ append("}\n")
+ }
+
+ fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
+ tlvWriter.apply {
+ startStructure(tlvTag)
+ put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID)
+ endStructure()
+ }
+ }
+
+ companion object {
+ private const val TAG_EXTENDED_PAN_I_D = 0
+
+ fun fromTlv(
+ tlvTag: Tag,
+ tlvReader: TlvReader
+ ): ThreadNetworkDirectoryClusterNetworkChangedEvent {
+ tlvReader.enterStructure(tlvTag)
+ val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D))
+
+ tlvReader.exitContainer()
+
+ return ThreadNetworkDirectoryClusterNetworkChangedEvent(extendedPanID)
+ }
+ }
+}
diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni
index e58b346b307ab7..f7670310f95cfd 100644
--- a/src/controller/java/generated/java/matter/controller/cluster/files.gni
+++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni
@@ -127,6 +127,7 @@ matter_structs_sources = [
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterSecurityPolicy.kt",
+ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterDSTOffsetStruct.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterFabricScopedTrustedTimeSourceStruct.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterTimeZoneStruct.kt",
@@ -211,6 +212,7 @@ matter_eventstructs_sources = [
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TargetNavigatorClusterTargetUpdatedEvent.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt",
+ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TimeSynchronizationClusterDSTStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TimeSynchronizationClusterTimeZoneStatusEvent.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/UnitTestingClusterTestDifferentVendorMeiEventEvent.kt",
@@ -331,6 +333,7 @@ matter_clusters_sources = [
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt",
+ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimeFormatLocalizationCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimerCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimeSynchronizationCluster.kt",
diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt
new file mode 100644
index 00000000000000..f7fb08d535fef5
--- /dev/null
+++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package matter.controller.cluster.structs
+
+import matter.controller.cluster.*
+import matter.tlv.ContextSpecificTag
+import matter.tlv.Tag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class ThreadNetworkDirectoryClusterThreadNetworkStruct(
+ val extendedPanID: ULong,
+ val networkName: String,
+ val channel: UShort
+) {
+ override fun toString(): String = buildString {
+ append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n")
+ append("\textendedPanID : $extendedPanID\n")
+ append("\tnetworkName : $networkName\n")
+ append("\tchannel : $channel\n")
+ append("}\n")
+ }
+
+ fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
+ tlvWriter.apply {
+ startStructure(tlvTag)
+ put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID)
+ put(ContextSpecificTag(TAG_NETWORK_NAME), networkName)
+ put(ContextSpecificTag(TAG_CHANNEL), channel)
+ endStructure()
+ }
+ }
+
+ companion object {
+ private const val TAG_EXTENDED_PAN_I_D = 0
+ private const val TAG_NETWORK_NAME = 1
+ private const val TAG_CHANNEL = 2
+
+ fun fromTlv(
+ tlvTag: Tag,
+ tlvReader: TlvReader
+ ): ThreadNetworkDirectoryClusterThreadNetworkStruct {
+ tlvReader.enterStructure(tlvTag)
+ val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D))
+ val networkName = tlvReader.getString(ContextSpecificTag(TAG_NETWORK_NAME))
+ val channel = tlvReader.getUShort(ContextSpecificTag(TAG_CHANNEL))
+
+ tlvReader.exitContainer()
+
+ return ThreadNetworkDirectoryClusterThreadNetworkStruct(extendedPanID, networkName, channel)
+ }
+ }
+}
diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
index ff10df38c79f9c..3b58043e65ee78 100644
--- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
+++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
@@ -37320,6 +37320,247 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR
}
break;
}
+ case app::Clusters::ThreadNetworkDirectory::Id: {
+ using namespace app::Clusters::ThreadNetworkDirectory;
+ switch (aPath.mAttributeId)
+ {
+ case Attributes::PreferredExtendedPanID::Id: {
+ using TypeInfo = Attributes::PreferredExtendedPanID::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ std::string valueClassName = "java/lang/Long";
+ std::string valueCtorSignature = "(J)V";
+ jlong jnivalue = static_cast(cppValue.Value());
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ }
+ return value;
+ }
+ case Attributes::ThreadNetworks::Id: {
+ using TypeInfo = Attributes::ThreadNetworks::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ jobject newElement_0_extendedPanID;
+ std::string newElement_0_extendedPanIDClassName = "java/lang/Long";
+ std::string newElement_0_extendedPanIDCtorSignature = "(J)V";
+ jlong jninewElement_0_extendedPanID = static_cast(entry_0.extendedPanID);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0_extendedPanIDClassName.c_str(), newElement_0_extendedPanIDCtorSignature.c_str(),
+ jninewElement_0_extendedPanID, newElement_0_extendedPanID);
+ jobject newElement_0_networkName;
+ LogErrorOnFailure(
+ chip::JniReferences::GetInstance().CharToStringUTF(entry_0.networkName, newElement_0_networkName));
+ jobject newElement_0_channel;
+ std::string newElement_0_channelClassName = "java/lang/Integer";
+ std::string newElement_0_channelCtorSignature = "(I)V";
+ jint jninewElement_0_channel = static_cast(entry_0.channel);
+ chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_channelClassName.c_str(),
+ newElement_0_channelCtorSignature.c_str(),
+ jninewElement_0_channel, newElement_0_channel);
+
+ jclass threadNetworkStructStructClass_1;
+ err = chip::JniReferences::GetInstance().GetLocalClassRef(
+ env, "chip/devicecontroller/ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct",
+ threadNetworkStructStructClass_1);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(Zcl, "Could not find class ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct");
+ return nullptr;
+ }
+
+ jmethodID threadNetworkStructStructCtor_1;
+ err = chip::JniReferences::GetInstance().FindMethod(env, threadNetworkStructStructClass_1, "",
+ "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/Integer;)V",
+ &threadNetworkStructStructCtor_1);
+ if (err != CHIP_NO_ERROR || threadNetworkStructStructCtor_1 == nullptr)
+ {
+ ChipLogError(Zcl, "Could not find ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct constructor");
+ return nullptr;
+ }
+
+ newElement_0 = env->NewObject(threadNetworkStructStructClass_1, threadNetworkStructStructCtor_1,
+ newElement_0_extendedPanID, newElement_0_networkName, newElement_0_channel);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::ThreadNetworkTableSize::Id: {
+ using TypeInfo = Attributes::ThreadNetworkTableSize::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ std::string valueClassName = "java/lang/Integer";
+ std::string valueCtorSignature = "(I)V";
+ jint jnivalue = static_cast(cppValue);
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue,
+ value);
+ return value;
+ }
+ case Attributes::GeneratedCommandList::Id: {
+ using TypeInfo = Attributes::GeneratedCommandList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::AcceptedCommandList::Id: {
+ using TypeInfo = Attributes::AcceptedCommandList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::EventList::Id: {
+ using TypeInfo = Attributes::EventList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::AttributeList::Id: {
+ using TypeInfo = Attributes::AttributeList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::FeatureMap::Id: {
+ using TypeInfo = Attributes::FeatureMap::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ std::string valueClassName = "java/lang/Long";
+ std::string valueCtorSignature = "(J)V";
+ jlong jnivalue = static_cast(cppValue);
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ return value;
+ }
+ case Attributes::ClusterRevision::Id: {
+ using TypeInfo = Attributes::ClusterRevision::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ std::string valueClassName = "java/lang/Integer";
+ std::string valueCtorSignature = "(I)V";
+ jint jnivalue = static_cast(cppValue);
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue,
+ value);
+ return value;
+ }
+ default:
+ *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
+ break;
+ }
+ break;
+ }
case app::Clusters::WakeOnLan::Id: {
using namespace app::Clusters::WakeOnLan;
switch (aPath.mAttributeId)
diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
index 7f210566b9aa37..ac55ed9125654e 100644
--- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
+++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
@@ -7399,6 +7399,54 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader &
}
break;
}
+ case app::Clusters::ThreadNetworkDirectory::Id: {
+ using namespace app::Clusters::ThreadNetworkDirectory;
+ switch (aPath.mEventId)
+ {
+ case Events::NetworkChanged::Id: {
+ Events::NetworkChanged::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value_extendedPanID;
+ std::string value_extendedPanIDClassName = "java/lang/Long";
+ std::string value_extendedPanIDCtorSignature = "(J)V";
+ jlong jnivalue_extendedPanID = static_cast(cppValue.extendedPanID);
+ chip::JniReferences::GetInstance().CreateBoxedObject(value_extendedPanIDClassName.c_str(),
+ value_extendedPanIDCtorSignature.c_str(),
+ jnivalue_extendedPanID, value_extendedPanID);
+
+ jclass networkChangedStructClass;
+ err = chip::JniReferences::GetInstance().GetLocalClassRef(
+ env, "chip/devicecontroller/ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent",
+ networkChangedStructClass);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(Zcl, "Could not find class ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent");
+ return nullptr;
+ }
+
+ jmethodID networkChangedStructCtor;
+ err = chip::JniReferences::GetInstance().FindMethod(env, networkChangedStructClass, "", "(Ljava/lang/Long;)V",
+ &networkChangedStructCtor);
+ if (err != CHIP_NO_ERROR || networkChangedStructCtor == nullptr)
+ {
+ ChipLogError(Zcl, "Could not find ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent constructor");
+ return nullptr;
+ }
+
+ jobject value = env->NewObject(networkChangedStructClass, networkChangedStructCtor, value_extendedPanID);
+
+ return value;
+ }
+ default:
+ *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
+ break;
+ }
+ break;
+ }
case app::Clusters::WakeOnLan::Id: {
using namespace app::Clusters::WakeOnLan;
switch (aPath.mEventId)
diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py
index 6acd5596b06d50..24b35747203355 100644
--- a/src/controller/python/chip/clusters/CHIPClusters.py
+++ b/src/controller/python/chip/clusters/CHIPClusters.py
@@ -11591,6 +11591,90 @@ class ChipClusters:
},
},
}
+ _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO = {
+ "clusterName": "ThreadNetworkDirectory",
+ "clusterId": 0x00000453,
+ "commands": {
+ 0x00000000: {
+ "commandId": 0x00000000,
+ "commandName": "AddNetwork",
+ "args": {
+ "operationalDataset": "bytes",
+ },
+ },
+ 0x00000001: {
+ "commandId": 0x00000001,
+ "commandName": "RemoveNetwork",
+ "args": {
+ "extendedPanID": "int",
+ },
+ },
+ 0x00000002: {
+ "commandId": 0x00000002,
+ "commandName": "GetOperationalDataset",
+ "args": {
+ "extendedPanID": "int",
+ },
+ },
+ },
+ "attributes": {
+ 0x00000000: {
+ "attributeName": "PreferredExtendedPanID",
+ "attributeId": 0x00000000,
+ "type": "int",
+ "reportable": True,
+ "writable": True,
+ },
+ 0x00000001: {
+ "attributeName": "ThreadNetworks",
+ "attributeId": 0x00000001,
+ "type": "",
+ "reportable": True,
+ },
+ 0x00000002: {
+ "attributeName": "ThreadNetworkTableSize",
+ "attributeId": 0x00000002,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFF8: {
+ "attributeName": "GeneratedCommandList",
+ "attributeId": 0x0000FFF8,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFF9: {
+ "attributeName": "AcceptedCommandList",
+ "attributeId": 0x0000FFF9,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFA: {
+ "attributeName": "EventList",
+ "attributeId": 0x0000FFFA,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFB: {
+ "attributeName": "AttributeList",
+ "attributeId": 0x0000FFFB,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFC: {
+ "attributeName": "FeatureMap",
+ "attributeId": 0x0000FFFC,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFD: {
+ "attributeName": "ClusterRevision",
+ "attributeId": 0x0000FFFD,
+ "type": "int",
+ "reportable": True,
+ },
+ },
+ }
_WAKE_ON_LAN_CLUSTER_INFO = {
"clusterName": "WakeOnLan",
"clusterId": 0x00000503,
@@ -14695,6 +14779,7 @@ class ChipClusters:
0x0000042E: _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO,
0x0000042F: _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO,
0x00000451: _WI_FI_NETWORK_MANAGEMENT_CLUSTER_INFO,
+ 0x00000453: _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO,
0x00000503: _WAKE_ON_LAN_CLUSTER_INFO,
0x00000504: _CHANNEL_CLUSTER_INFO,
0x00000505: _TARGET_NAVIGATOR_CLUSTER_INFO,
@@ -14817,6 +14902,7 @@ class ChipClusters:
"TotalVolatileOrganicCompoundsConcentrationMeasurement": _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO,
"RadonConcentrationMeasurement": _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO,
"WiFiNetworkManagement": _WI_FI_NETWORK_MANAGEMENT_CLUSTER_INFO,
+ "ThreadNetworkDirectory": _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO,
"WakeOnLan": _WAKE_ON_LAN_CLUSTER_INFO,
"Channel": _CHANNEL_CLUSTER_INFO,
"TargetNavigator": _TARGET_NAVIGATOR_CLUSTER_INFO,
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index c2db68c0ecfd4c..527bc943019cbb 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -40399,6 +40399,294 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
value: 'uint' = 0
+@dataclass
+class ThreadNetworkDirectory(Cluster):
+ id: typing.ClassVar[int] = 0x00000453
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="preferredExtendedPanID", Tag=0x00000000, Type=typing.Union[Nullable, uint]),
+ ClusterObjectFieldDescriptor(Label="threadNetworks", Tag=0x00000001, Type=typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]),
+ ClusterObjectFieldDescriptor(Label="threadNetworkTableSize", Tag=0x00000002, Type=uint),
+ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint),
+ ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint),
+ ])
+
+ preferredExtendedPanID: 'typing.Union[Nullable, uint]' = None
+ threadNetworks: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = None
+ threadNetworkTableSize: 'uint' = None
+ generatedCommandList: 'typing.List[uint]' = None
+ acceptedCommandList: 'typing.List[uint]' = None
+ eventList: 'typing.List[uint]' = None
+ attributeList: 'typing.List[uint]' = None
+ featureMap: 'uint' = None
+ clusterRevision: 'uint' = None
+
+ class Structs:
+ @dataclass
+ class ThreadNetworkStruct(ClusterObject):
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint),
+ ClusterObjectFieldDescriptor(Label="networkName", Tag=1, Type=str),
+ ClusterObjectFieldDescriptor(Label="channel", Tag=2, Type=uint),
+ ])
+
+ extendedPanID: 'uint' = 0
+ networkName: 'str' = ""
+ channel: 'uint' = 0
+
+ class Commands:
+ @dataclass
+ class AddNetwork(ClusterCommand):
+ cluster_id: typing.ClassVar[int] = 0x00000453
+ command_id: typing.ClassVar[int] = 0x00000000
+ is_client: typing.ClassVar[bool] = True
+ response_type: typing.ClassVar[str] = None
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="operationalDataset", Tag=0, Type=bytes),
+ ])
+
+ @ChipUtility.classproperty
+ def must_use_timed_invoke(cls) -> bool:
+ return True
+
+ operationalDataset: 'bytes' = b""
+
+ @dataclass
+ class RemoveNetwork(ClusterCommand):
+ cluster_id: typing.ClassVar[int] = 0x00000453
+ command_id: typing.ClassVar[int] = 0x00000001
+ is_client: typing.ClassVar[bool] = True
+ response_type: typing.ClassVar[str] = None
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint),
+ ])
+
+ @ChipUtility.classproperty
+ def must_use_timed_invoke(cls) -> bool:
+ return True
+
+ extendedPanID: 'uint' = 0
+
+ @dataclass
+ class GetOperationalDataset(ClusterCommand):
+ cluster_id: typing.ClassVar[int] = 0x00000453
+ command_id: typing.ClassVar[int] = 0x00000002
+ is_client: typing.ClassVar[bool] = True
+ response_type: typing.ClassVar[str] = 'OperationalDatasetResponse'
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint),
+ ])
+
+ @ChipUtility.classproperty
+ def must_use_timed_invoke(cls) -> bool:
+ return True
+
+ extendedPanID: 'uint' = 0
+
+ @dataclass
+ class OperationalDatasetResponse(ClusterCommand):
+ cluster_id: typing.ClassVar[int] = 0x00000453
+ command_id: typing.ClassVar[int] = 0x00000003
+ is_client: typing.ClassVar[bool] = False
+ response_type: typing.ClassVar[str] = None
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="operationalDataset", Tag=0, Type=bytes),
+ ])
+
+ operationalDataset: 'bytes' = b""
+
+ class Attributes:
+ @dataclass
+ class PreferredExtendedPanID(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000000
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint])
+
+ value: 'typing.Union[Nullable, uint]' = NullValue
+
+ @dataclass
+ class ThreadNetworks(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000001
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct])
+
+ value: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class ThreadNetworkTableSize(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000002
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=uint)
+
+ value: 'uint' = 0
+
+ @dataclass
+ class GeneratedCommandList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFF8
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class AcceptedCommandList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFF9
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class EventList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFA
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class AttributeList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFB
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class FeatureMap(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFC
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=uint)
+
+ value: 'uint' = 0
+
+ @dataclass
+ class ClusterRevision(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFD
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=uint)
+
+ value: 'uint' = 0
+
+ class Events:
+ @dataclass
+ class NetworkChanged(ClusterEvent):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000453
+
+ @ChipUtility.classproperty
+ def event_id(cls) -> int:
+ return 0x00000000
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint),
+ ])
+
+ extendedPanID: 'uint' = 0
+
+
@dataclass
class WakeOnLan(Cluster):
id: typing.ClassVar[int] = 0x00000503
diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml
index 637f92de14f824..8a1e95b8911ebe 100644
--- a/src/darwin/Framework/CHIP/templates/availability.yaml
+++ b/src/darwin/Framework/CHIP/templates/availability.yaml
@@ -9690,4 +9690,5 @@
provisional:
clusters:
# Targeting Fall 2024
+ - ThreadNetworkDirectory
- WiFiNetworkManagement
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
index a6ab1d6beee61c..d581289afd59f2 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
@@ -5318,6 +5318,42 @@ static BOOL AttributeIsSpecifiedInWiFiNetworkManagementCluster(AttributeId aAttr
}
}
}
+static BOOL AttributeIsSpecifiedInThreadNetworkDirectoryCluster(AttributeId aAttributeId)
+{
+ using namespace Clusters::ThreadNetworkDirectory;
+ switch (aAttributeId) {
+ case Attributes::PreferredExtendedPanID::Id: {
+ return YES;
+ }
+ case Attributes::ThreadNetworks::Id: {
+ return YES;
+ }
+ case Attributes::ThreadNetworkTableSize::Id: {
+ return YES;
+ }
+ case Attributes::GeneratedCommandList::Id: {
+ return YES;
+ }
+ case Attributes::AcceptedCommandList::Id: {
+ return YES;
+ }
+ case Attributes::EventList::Id: {
+ return YES;
+ }
+ case Attributes::AttributeList::Id: {
+ return YES;
+ }
+ case Attributes::FeatureMap::Id: {
+ return YES;
+ }
+ case Attributes::ClusterRevision::Id: {
+ return YES;
+ }
+ default: {
+ return NO;
+ }
+ }
+}
static BOOL AttributeIsSpecifiedInWakeOnLANCluster(AttributeId aAttributeId)
{
using namespace Clusters::WakeOnLan;
@@ -6837,6 +6873,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId)
case Clusters::WiFiNetworkManagement::Id: {
return AttributeIsSpecifiedInWiFiNetworkManagementCluster(aAttributeId);
}
+ case Clusters::ThreadNetworkDirectory::Id: {
+ return AttributeIsSpecifiedInThreadNetworkDirectoryCluster(aAttributeId);
+ }
case Clusters::WakeOnLan::Id: {
return AttributeIsSpecifiedInWakeOnLANCluster(aAttributeId);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
index f5b2ca3d7dd743..9497069cb7e507 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
@@ -15246,6 +15246,78 @@ static id _Nullable DecodeAttributeValueForWiFiNetworkManagementCluster(Attribut
*aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
return nil;
}
+static id _Nullable DecodeAttributeValueForThreadNetworkDirectoryCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
+{
+ using namespace Clusters::ThreadNetworkDirectory;
+ switch (aAttributeId) {
+ case Attributes::PreferredExtendedPanID::Id: {
+ using TypeInfo = Attributes::PreferredExtendedPanID::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSNumber * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = [NSNumber numberWithUnsignedLongLong:cppValue.Value()];
+ }
+ return value;
+ }
+ case Attributes::ThreadNetworks::Id: {
+ using TypeInfo = Attributes::ThreadNetworks::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSArray * _Nonnull value;
+ { // Scope for our temporary variables
+ auto * array_0 = [NSMutableArray new];
+ auto iter_0 = cppValue.begin();
+ while (iter_0.Next()) {
+ auto & entry_0 = iter_0.GetValue();
+ MTRThreadNetworkDirectoryClusterThreadNetworkStruct * newElement_0;
+ newElement_0 = [MTRThreadNetworkDirectoryClusterThreadNetworkStruct new];
+ newElement_0.extendedPanID = [NSNumber numberWithUnsignedLongLong:entry_0.extendedPanID];
+ newElement_0.networkName = AsString(entry_0.networkName);
+ if (newElement_0.networkName == nil) {
+ CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
+ *aError = err;
+ return nil;
+ }
+ newElement_0.channel = [NSNumber numberWithUnsignedShort:entry_0.channel];
+ [array_0 addObject:newElement_0];
+ }
+ CHIP_ERROR err = iter_0.GetStatus();
+ if (err != CHIP_NO_ERROR) {
+ *aError = err;
+ return nil;
+ }
+ value = array_0;
+ }
+ return value;
+ }
+ case Attributes::ThreadNetworkTableSize::Id: {
+ using TypeInfo = Attributes::ThreadNetworkTableSize::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSNumber * _Nonnull value;
+ value = [NSNumber numberWithUnsignedChar:cppValue];
+ return value;
+ }
+ default: {
+ break;
+ }
+ }
+
+ *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
+ return nil;
+}
static id _Nullable DecodeAttributeValueForWakeOnLANCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
{
using namespace Clusters::WakeOnLan;
@@ -19623,6 +19695,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T
case Clusters::WiFiNetworkManagement::Id: {
return DecodeAttributeValueForWiFiNetworkManagementCluster(aPath.mAttributeId, aReader, aError);
}
+ case Clusters::ThreadNetworkDirectory::Id: {
+ return DecodeAttributeValueForThreadNetworkDirectoryCluster(aPath.mAttributeId, aReader, aError);
+ }
case Clusters::WakeOnLan::Id: {
return DecodeAttributeValueForWakeOnLANCluster(aPath.mAttributeId, aReader, aError);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index d5e7efa37f08bd..c5e73b22368081 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -13065,6 +13065,106 @@ MTR_PROVISIONALLY_AVAILABLE
@end
+/**
+ * Cluster Thread Network Directory
+ *
+ * Manages the names and credentials of Thread networks visible to the user.
+ */
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRBaseClusterThreadNetworkDirectory : MTRGenericBaseCluster
+
+/**
+ * Command AddNetwork
+ *
+ * Adds an entry to the ThreadNetworks list.
+ */
+- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+/**
+ * Command RemoveNetwork
+ *
+ * Removes an entry from the ThreadNetworks list.
+ */
+- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+/**
+ * Command GetOperationalDataset
+ *
+ * Retrieves a Thread Operational Dataset from the ThreadNetworks list.
+ */
+- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributePreferredExtendedPanIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributePreferredExtendedPanIDWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributePreferredExtendedPanIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeThreadNetworksWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeThreadNetworksWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeThreadNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeThreadNetworkTableSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeThreadNetworkTableSizeWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeThreadNetworkTableSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+@end
+
+@interface MTRBaseClusterThreadNetworkDirectory (Availability)
+
+/**
+ * For all instance methods (reads, writes, commands) that take a completion,
+ * the completion will be called on the provided queue.
+ */
+- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device
+ endpointID:(NSNumber *)endpointID
+ queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE;
+
+@end
+
/**
* Cluster Wake on LAN
*
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
index 8155fed2e794f1..1df39709657551 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
@@ -93179,6 +93179,449 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC
@end
+@implementation MTRBaseClusterThreadNetworkDirectory
+
+- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params completion:(MTRStatusCompletion)completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterAddNetworkParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::AddNetwork::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:nil
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params completion:(MTRStatusCompletion)completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::RemoveNetwork::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:nil
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(response, error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams.class
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+
+- (void)readAttributePreferredExtendedPanIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
+{
+ [self writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
+}
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion
+{
+ // Make a copy of params before we go async.
+ params = [params copy];
+ value = [value copy];
+
+ auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
+ chip::Optional timedWriteTimeout;
+ if (params != nil) {
+ if (params.timedWriteTimeout != nil){
+ timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
+ }
+ }
+
+ ListFreer listFreer;
+ using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo;
+ TypeInfo::Type cppValue;
+ if (value == nil) {
+ cppValue.SetNull();
+ } else {
+ auto & nonNullValue_0 = cppValue.SetNonNull();
+ nonNullValue_0 = value.unsignedLongLongValue;
+ }
+
+ chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue);
+ return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); });
+ std::move(*bridge).DispatchAction(self.device);
+}
+
+- (void)subscribeAttributePreferredExtendedPanIDWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributePreferredExtendedPanIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeThreadNetworksWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeThreadNetworksWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeThreadNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeThreadNetworkTableSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeThreadNetworkTableSizeWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeThreadNetworkTableSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+@end
+
@implementation MTRBaseClusterWakeOnLAN
- (void)readAttributeMACAddressWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
index 0627e1d7937536..d609ce5c84179c 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
@@ -185,6 +185,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) {
MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042E,
MTRClusterIDTypeRadonConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042F,
MTRClusterIDTypeWiFiNetworkManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000451,
+ MTRClusterIDTypeThreadNetworkDirectoryID MTR_PROVISIONALLY_AVAILABLE = 0x00000453,
MTRClusterIDTypeWakeOnLANID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000503,
MTRClusterIDTypeChannelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000504,
MTRClusterIDTypeTargetNavigatorID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000505,
@@ -4371,6 +4372,17 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) {
MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID,
MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID,
+ // Cluster ThreadNetworkDirectory attributes
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000000,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID MTR_PROVISIONALLY_AVAILABLE = 0x00000001,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID,
+ MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID,
+
// Cluster WakeOnLan deprecated attribute names
MTRClusterWakeOnLanAttributeMACAddressID
MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterWakeOnLANAttributeMACAddressID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4))
@@ -6589,6 +6601,12 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) {
MTRCommandIDTypeClusterWiFiNetworkManagementCommandNetworkPassphraseRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000,
MTRCommandIDTypeClusterWiFiNetworkManagementCommandNetworkPassphraseResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001,
+ // Cluster ThreadNetworkDirectory commands
+ MTRCommandIDTypeClusterThreadNetworkDirectoryCommandAddNetworkID MTR_PROVISIONALLY_AVAILABLE = 0x00000000,
+ MTRCommandIDTypeClusterThreadNetworkDirectoryCommandRemoveNetworkID MTR_PROVISIONALLY_AVAILABLE = 0x00000001,
+ MTRCommandIDTypeClusterThreadNetworkDirectoryCommandGetOperationalDatasetID MTR_PROVISIONALLY_AVAILABLE = 0x00000002,
+ MTRCommandIDTypeClusterThreadNetworkDirectoryCommandOperationalDatasetResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003,
+
// Cluster Channel deprecated command id names
MTRClusterChannelCommandChangeChannelID
MTR_DEPRECATED("Please use MTRCommandIDTypeClusterChannelCommandChangeChannelID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4))
@@ -7337,6 +7355,9 @@ typedef NS_ENUM(uint32_t, MTREventIDType) {
MTREventIDTypeClusterPumpConfigurationAndControlEventAirDetectionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000F,
MTREventIDTypeClusterPumpConfigurationAndControlEventTurbineOperationID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000010,
+ // Cluster ThreadNetworkDirectory events
+ MTREventIDTypeClusterThreadNetworkDirectoryEventNetworkChangedID MTR_PROVISIONALLY_AVAILABLE = 0x00000000,
+
// Cluster TargetNavigator deprecated event names
// Cluster TargetNavigator events
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
index 7b8402cabc2fda..2306fdd1c7d92d 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
@@ -321,6 +321,9 @@
case MTRClusterIDTypeWiFiNetworkManagementID:
result = @"WiFiNetworkManagement";
break;
+ case MTRClusterIDTypeThreadNetworkDirectoryID:
+ result = @"ThreadNetworkDirectory";
+ break;
case MTRClusterIDTypeWakeOnLANID:
result = @"WakeOnLAN";
break;
@@ -7253,6 +7256,52 @@
break;
}
+ case MTRClusterIDTypeThreadNetworkDirectoryID:
+
+ switch (attributeID) {
+
+ // Cluster ThreadNetworkDirectory attributes
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID:
+ result = @"PreferredExtendedPanID";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID:
+ result = @"ThreadNetworks";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID:
+ result = @"ThreadNetworkTableSize";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID:
+ result = @"GeneratedCommandList";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID:
+ result = @"AcceptedCommandList";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID:
+ result = @"EventList";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID:
+ result = @"AttributeList";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID:
+ result = @"FeatureMap";
+ break;
+
+ case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID:
+ result = @"ClusterRevision";
+ break;
+
+ default:
+ result = [NSString stringWithFormat:@"", attributeID];
+ break;
+ }
+
case MTRClusterIDTypeWakeOnLANID:
switch (attributeID) {
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
index 34d469730f1c94..29249e35e5a360 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
@@ -6035,6 +6035,54 @@ MTR_PROVISIONALLY_AVAILABLE
@end
+/**
+ * Cluster Thread Network Directory
+ * Manages the names and credentials of Thread networks visible to the user.
+ */
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRClusterThreadNetworkDirectory : MTRGenericCluster
+
+- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributePreferredExtendedPanIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeThreadNetworksWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeThreadNetworkTableSizeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+@end
+
+@interface MTRClusterThreadNetworkDirectory (Availability)
+
+/**
+ * For all instance methods that take a completion (i.e. command invocations),
+ * the completion will be called on the provided queue.
+ */
+- (instancetype _Nullable)initWithDevice:(MTRDevice *)device
+ endpointID:(NSNumber *)endpointID
+ queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE;
+
+@end
+
/**
* Cluster Wake on LAN
* This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol.
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
index 2605a37007449c..c950d5e4f0f1b8 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
@@ -16838,6 +16838,156 @@ - (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetwo
@end
+@implementation MTRClusterThreadNetworkDirectory
+
+- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterAddNetworkParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::AddNetwork::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ expectedValues:expectedValues
+ expectedValueInterval:expectedValueIntervalMs
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:nil
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+
+- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::RemoveNetwork::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ expectedValues:expectedValues
+ expectedValueInterval:expectedValueIntervalMs
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:nil
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+
+- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion
+{
+ if (params == nil) {
+ params = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams
+ alloc] init];
+ }
+
+ auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) {
+ completion(response, error);
+ };
+
+ auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs;
+ if (timedInvokeTimeoutMs == nil) {
+ timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS);
+ }
+
+ using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type;
+ [self.device _invokeKnownCommandWithEndpointID:self.endpointID
+ clusterID:@(RequestType::GetClusterId())
+ commandID:@(RequestType::GetCommandId())
+ commandPayload:params
+ expectedValues:expectedValues
+ expectedValueInterval:expectedValueIntervalMs
+ timedInvokeTimeout:timedInvokeTimeoutMs
+ serverSideProcessingTimeout:params.serverSideProcessingTimeout
+ responseClass:MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams.class
+ queue:self.callbackQueue
+ completion:responseHandler];
+}
+
+- (NSDictionary * _Nullable)readAttributePreferredExtendedPanIDWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID) params:params];
+}
+
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs
+{
+ [self writeAttributePreferredExtendedPanIDWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil];
+}
+- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params
+{
+ NSNumber * timedWriteTimeout = params.timedWriteTimeout;
+
+ [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout];
+}
+
+- (NSDictionary * _Nullable)readAttributeThreadNetworksWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeThreadNetworkTableSizeWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID) params:params];
+}
+
+@end
+
@implementation MTRClusterWakeOnLAN
- (NSDictionary * _Nullable)readAttributeMACAddressWithParams:(MTRReadParams * _Nullable)params
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
index cfd06dee343cc0..0017193f50a673 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
@@ -8559,6 +8559,115 @@ MTR_PROVISIONALLY_AVAILABLE
error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE;
@end
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterAddNetworkParams : NSObject
+
+@property (nonatomic, copy) NSData * _Nonnull operationalDataset MTR_PROVISIONALLY_AVAILABLE;
+/**
+ * Controls whether the command is a timed command (using Timed Invoke).
+ *
+ * If nil (the default value), a regular invoke is done for commands that do
+ * not require a timed invoke and a timed invoke with some default timed request
+ * timeout is done for commands that require a timed invoke.
+ *
+ * If not nil, a timed invoke is done, with the provided value used as the timed
+ * request timeout. The value should be chosen small enough to provide the
+ * desired security properties but large enough that it will allow a round-trip
+ * from the sever to the client (for the status response and actual invoke
+ * request) within the timeout window.
+ *
+ */
+@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs;
+
+/**
+ * Controls how much time, in seconds, we will allow for the server to process the command.
+ *
+ * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes.
+ *
+ * If nil, the framework will try to select an appropriate timeout value itself.
+ */
+@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout;
+@end
+
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterRemoveNetworkParams : NSObject
+
+@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE;
+/**
+ * Controls whether the command is a timed command (using Timed Invoke).
+ *
+ * If nil (the default value), a regular invoke is done for commands that do
+ * not require a timed invoke and a timed invoke with some default timed request
+ * timeout is done for commands that require a timed invoke.
+ *
+ * If not nil, a timed invoke is done, with the provided value used as the timed
+ * request timeout. The value should be chosen small enough to provide the
+ * desired security properties but large enough that it will allow a round-trip
+ * from the sever to the client (for the status response and actual invoke
+ * request) within the timeout window.
+ *
+ */
+@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs;
+
+/**
+ * Controls how much time, in seconds, we will allow for the server to process the command.
+ *
+ * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes.
+ *
+ * If nil, the framework will try to select an appropriate timeout value itself.
+ */
+@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout;
+@end
+
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams : NSObject
+
+@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE;
+/**
+ * Controls whether the command is a timed command (using Timed Invoke).
+ *
+ * If nil (the default value), a regular invoke is done for commands that do
+ * not require a timed invoke and a timed invoke with some default timed request
+ * timeout is done for commands that require a timed invoke.
+ *
+ * If not nil, a timed invoke is done, with the provided value used as the timed
+ * request timeout. The value should be chosen small enough to provide the
+ * desired security properties but large enough that it will allow a round-trip
+ * from the sever to the client (for the status response and actual invoke
+ * request) within the timeout window.
+ *
+ */
+@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs;
+
+/**
+ * Controls how much time, in seconds, we will allow for the server to process the command.
+ *
+ * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes.
+ *
+ * If nil, the framework will try to select an appropriate timeout value itself.
+ */
+@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout;
+@end
+
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams : NSObject
+
+@property (nonatomic, copy) NSData * _Nonnull operationalDataset MTR_PROVISIONALLY_AVAILABLE;
+
+/**
+ * Initialize an MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams with a response-value dictionary
+ * of the sort that MTRDeviceResponseHandler would receive.
+ *
+ * Will return nil and hand out an error if the response-value dictionary is not
+ * a command data response or is not the right command response.
+ *
+ * Will return nil and hand out an error if the data response does not match the known
+ * schema for this command.
+ */
+- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue
+ error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE;
+@end
+
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
@interface MTRChannelClusterChangeChannelParams : NSObject
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
index af9752c200df41..689b7382ab3fb5 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
@@ -24120,6 +24120,322 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WiFiNetw
@end
+@implementation MTRThreadNetworkDirectoryClusterAddNetworkParams
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _operationalDataset = [NSData data];
+ _timedInvokeTimeoutMs = nil;
+ _serverSideProcessingTimeout = nil;
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone;
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterAddNetworkParams alloc] init];
+
+ other.operationalDataset = self.operationalDataset;
+ other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs;
+ other.serverSideProcessingTimeout = self.serverSideProcessingTimeout;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: operationalDataset:%@; >", NSStringFromClass([self class]), [_operationalDataset base64EncodedStringWithOptions:0]];
+ return descriptionString;
+}
+
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterAddNetworkParams (InternalMethods)
+
+- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader
+{
+ chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Type encodableStruct;
+ ListFreer listFreer;
+ {
+ encodableStruct.operationalDataset = AsByteSpan(self.operationalDataset);
+ }
+
+ auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
+ if (buffer.IsNull()) {
+ return CHIP_ERROR_NO_MEMORY;
+ }
+
+ chip::System::PacketBufferTLVWriter writer;
+ // Commands never need chained buffers, since they cannot be chunked.
+ writer.Init(std::move(buffer), /* useChainedBuffers = */ false);
+
+ ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct));
+
+ ReturnErrorOnFailure(writer.Finalize(&buffer));
+
+ reader.Init(std::move(buffer));
+ return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag());
+}
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error
+{
+ chip::System::PacketBufferTLVReader reader;
+ CHIP_ERROR err = [self _encodeToTLVReader:reader];
+ if (err != CHIP_NO_ERROR) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:err];
+ }
+ return nil;
+ }
+
+ auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader);
+ if (decodedObj == nil) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE];
+ }
+ }
+ return decodedObj;
+}
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterRemoveNetworkParams
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _extendedPanID = @(0);
+ _timedInvokeTimeoutMs = nil;
+ _serverSideProcessingTimeout = nil;
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone;
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams alloc] init];
+
+ other.extendedPanID = self.extendedPanID;
+ other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs;
+ other.serverSideProcessingTimeout = self.serverSideProcessingTimeout;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID];
+ return descriptionString;
+}
+
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterRemoveNetworkParams (InternalMethods)
+
+- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader
+{
+ chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Type encodableStruct;
+ ListFreer listFreer;
+ {
+ encodableStruct.extendedPanID = self.extendedPanID.unsignedLongLongValue;
+ }
+
+ auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
+ if (buffer.IsNull()) {
+ return CHIP_ERROR_NO_MEMORY;
+ }
+
+ chip::System::PacketBufferTLVWriter writer;
+ // Commands never need chained buffers, since they cannot be chunked.
+ writer.Init(std::move(buffer), /* useChainedBuffers = */ false);
+
+ ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct));
+
+ ReturnErrorOnFailure(writer.Finalize(&buffer));
+
+ reader.Init(std::move(buffer));
+ return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag());
+}
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error
+{
+ chip::System::PacketBufferTLVReader reader;
+ CHIP_ERROR err = [self _encodeToTLVReader:reader];
+ if (err != CHIP_NO_ERROR) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:err];
+ }
+ return nil;
+ }
+
+ auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader);
+ if (decodedObj == nil) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE];
+ }
+ }
+ return decodedObj;
+}
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _extendedPanID = @(0);
+ _timedInvokeTimeoutMs = nil;
+ _serverSideProcessingTimeout = nil;
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone;
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams alloc] init];
+
+ other.extendedPanID = self.extendedPanID;
+ other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs;
+ other.serverSideProcessingTimeout = self.serverSideProcessingTimeout;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID];
+ return descriptionString;
+}
+
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams (InternalMethods)
+
+- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader
+{
+ chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Type encodableStruct;
+ ListFreer listFreer;
+ {
+ encodableStruct.extendedPanID = self.extendedPanID.unsignedLongLongValue;
+ }
+
+ auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
+ if (buffer.IsNull()) {
+ return CHIP_ERROR_NO_MEMORY;
+ }
+
+ chip::System::PacketBufferTLVWriter writer;
+ // Commands never need chained buffers, since they cannot be chunked.
+ writer.Init(std::move(buffer), /* useChainedBuffers = */ false);
+
+ ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct));
+
+ ReturnErrorOnFailure(writer.Finalize(&buffer));
+
+ reader.Init(std::move(buffer));
+ return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag());
+}
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error
+{
+ chip::System::PacketBufferTLVReader reader;
+ CHIP_ERROR err = [self _encodeToTLVReader:reader];
+ if (err != CHIP_NO_ERROR) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:err];
+ }
+ return nil;
+ }
+
+ auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader);
+ if (decodedObj == nil) {
+ if (error) {
+ *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE];
+ }
+ }
+ return decodedObj;
+}
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _operationalDataset = [NSData data];
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone;
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams alloc] init];
+
+ other.operationalDataset = self.operationalDataset;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: operationalDataset:%@; >", NSStringFromClass([self class]), [_operationalDataset base64EncodedStringWithOptions:0]];
+ return descriptionString;
+}
+
+- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue
+ error:(NSError * __autoreleasing *)error
+{
+ if (!(self = [super init])) {
+ return nil;
+ }
+
+ using DecodableType = chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType;
+ chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue
+ clusterID:DecodableType::GetClusterId()
+ commandID:DecodableType::GetCommandId()
+ error:error];
+ if (buffer.IsNull()) {
+ return nil;
+ }
+
+ chip::TLV::TLVReader reader;
+ reader.Init(buffer->Start(), buffer->DataLength());
+
+ CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag());
+ if (err == CHIP_NO_ERROR) {
+ DecodableType decodedStruct;
+ err = chip::app::DataModel::Decode(reader, decodedStruct);
+ if (err == CHIP_NO_ERROR) {
+ err = [self _setFieldsFromDecodableStruct:decodedStruct];
+ if (err == CHIP_NO_ERROR) {
+ return self;
+ }
+ }
+ }
+
+ NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()];
+ MTR_LOG_ERROR("%s", errorStr.UTF8String);
+ if (error != nil) {
+ NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) };
+ *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo];
+ }
+ return nil;
+}
+
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams (InternalMethods)
+
+- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType &)decodableStruct
+{
+ {
+ self.operationalDataset = AsData(decodableStruct.operationalDataset);
+ }
+ return CHIP_NO_ERROR;
+}
+
+@end
+
@implementation MTRChannelClusterChangeChannelParams
- (instancetype)init
{
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h
index 2b629efdc5a24d..5794e71a896729 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h
@@ -1582,6 +1582,30 @@ NS_ASSUME_NONNULL_BEGIN
@end
+@interface MTRThreadNetworkDirectoryClusterAddNetworkParams (InternalMethods)
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error;
+
+@end
+
+@interface MTRThreadNetworkDirectoryClusterRemoveNetworkParams (InternalMethods)
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error;
+
+@end
+
+@interface MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams (InternalMethods)
+
+- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error;
+
+@end
+
+@interface MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams (InternalMethods)
+
+- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType &)decodableStruct;
+
+@end
+
@interface MTRChannelClusterChangeChannelParams (InternalMethods)
- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error;
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
index 0ea5a38336bb2a..ee4d2c1386bff0 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
@@ -965,6 +965,24 @@ static BOOL CommandNeedsTimedInvokeInWiFiNetworkManagementCluster(AttributeId aA
}
}
}
+static BOOL CommandNeedsTimedInvokeInThreadNetworkDirectoryCluster(AttributeId aAttributeId)
+{
+ using namespace Clusters::ThreadNetworkDirectory;
+ switch (aAttributeId) {
+ case Commands::AddNetwork::Id: {
+ return YES;
+ }
+ case Commands::RemoveNetwork::Id: {
+ return YES;
+ }
+ case Commands::GetOperationalDataset::Id: {
+ return YES;
+ }
+ default: {
+ return NO;
+ }
+ }
+}
static BOOL CommandNeedsTimedInvokeInWakeOnLANCluster(AttributeId aAttributeId)
{
using namespace Clusters::WakeOnLan;
@@ -1431,6 +1449,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn
case Clusters::WiFiNetworkManagement::Id: {
return CommandNeedsTimedInvokeInWiFiNetworkManagementCluster(commandID);
}
+ case Clusters::ThreadNetworkDirectory::Id: {
+ return CommandNeedsTimedInvokeInThreadNetworkDirectoryCluster(commandID);
+ }
case Clusters::WakeOnLan::Id: {
return CommandNeedsTimedInvokeInWakeOnLANCluster(commandID);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
index 9fc3cd16b8235a..69c23e1451e9b7 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
@@ -4047,6 +4047,35 @@ static id _Nullable DecodeEventPayloadForWiFiNetworkManagementCluster(EventId aE
*aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
return nil;
}
+static id _Nullable DecodeEventPayloadForThreadNetworkDirectoryCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
+{
+ using namespace Clusters::ThreadNetworkDirectory;
+ switch (aEventId) {
+ case Events::NetworkChanged::Id: {
+ Events::NetworkChanged::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+
+ __auto_type * value = [MTRThreadNetworkDirectoryClusterNetworkChangedEvent new];
+
+ do {
+ NSNumber * _Nonnull memberValue;
+ memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.extendedPanID];
+ value.extendedPanID = memberValue;
+ } while (0);
+
+ return value;
+ }
+ default: {
+ break;
+ }
+ }
+
+ *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
+ return nil;
+}
static id _Nullable DecodeEventPayloadForWakeOnLANCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
{
using namespace Clusters::WakeOnLan;
@@ -4851,6 +4880,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead
case Clusters::WiFiNetworkManagement::Id: {
return DecodeEventPayloadForWiFiNetworkManagementCluster(aPath.mEventId, aReader, aError);
}
+ case Clusters::ThreadNetworkDirectory::Id: {
+ return DecodeEventPayloadForThreadNetworkDirectoryCluster(aPath.mEventId, aReader, aError);
+ }
case Clusters::WakeOnLan::Id: {
return DecodeEventPayloadForWakeOnLANCluster(aPath.mEventId, aReader, aError);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
index 92bd095b954393..e4d9eb08566a50 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
@@ -1637,6 +1637,18 @@ MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct",
@property (nonatomic, copy) NSNumber * _Nullable coolSetpoint MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct", ios(16.1, 17.4), macos(13.0, 14.4), watchos(9.1, 10.4), tvos(16.1, 17.4));
@end
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterThreadNetworkStruct : NSObject
+@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE;
+@property (nonatomic, copy) NSString * _Nonnull networkName MTR_PROVISIONALLY_AVAILABLE;
+@property (nonatomic, copy) NSNumber * _Nonnull channel MTR_PROVISIONALLY_AVAILABLE;
+@end
+
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRThreadNetworkDirectoryClusterNetworkChangedEvent : NSObject
+@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE;
+@end
+
MTR_PROVISIONALLY_AVAILABLE
@interface MTRChannelClusterProgramCastStruct : NSObject
@property (nonatomic, copy) NSString * _Nonnull name MTR_PROVISIONALLY_AVAILABLE;
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
index c9c38c72710756..30c3531c6d7668 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
@@ -6884,6 +6884,66 @@ @implementation MTRThermostatClusterThermostatScheduleTransition : MTRThermostat
@dynamic coolSetpoint;
@end
+@implementation MTRThreadNetworkDirectoryClusterThreadNetworkStruct
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _extendedPanID = @(0);
+
+ _networkName = @"";
+
+ _channel = @(0);
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterThreadNetworkStruct alloc] init];
+
+ other.extendedPanID = self.extendedPanID;
+ other.networkName = self.networkName;
+ other.channel = self.channel;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; networkName:%@; channel:%@; >", NSStringFromClass([self class]), _extendedPanID, _networkName, _channel];
+ return descriptionString;
+}
+
+@end
+
+@implementation MTRThreadNetworkDirectoryClusterNetworkChangedEvent
+- (instancetype)init
+{
+ if (self = [super init]) {
+
+ _extendedPanID = @(0);
+ }
+ return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+ auto other = [[MTRThreadNetworkDirectoryClusterNetworkChangedEvent alloc] init];
+
+ other.extendedPanID = self.extendedPanID;
+
+ return other;
+}
+
+- (NSString *)description
+{
+ NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID];
+ return descriptionString;
+}
+
+@end
+
@implementation MTRChannelClusterProgramCastStruct
- (instancetype)init
{
diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
index 78448839fc5e93..84233e5ad954d4 100644
--- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
+++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
@@ -34669,6 +34669,242 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu
} // namespace Attributes
} // namespace WiFiNetworkManagement
+namespace ThreadNetworkDirectory {
+namespace Attributes {
+
+namespace PreferredExtendedPanID {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType temp;
+ uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ if (Traits::IsNullValue(temp))
+ {
+ value.SetNull();
+ }
+ else
+ {
+ value.SetNonNull() = Traits::StorageToWorking(temp);
+ }
+ return status;
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE,
+ markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
+}
+
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType value;
+ Traits::SetNull(value);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE,
+ markDirty);
+}
+
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType value;
+ Traits::SetNull(value);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value,
+ MarkAttributeDirty markDirty)
+{
+ if (value.IsNull())
+ {
+ return SetNull(endpoint, markDirty);
+ }
+
+ return Set(endpoint, value.Value(), markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value)
+{
+ if (value.IsNull())
+ {
+ return SetNull(endpoint);
+ }
+
+ return Set(endpoint, value.Value());
+}
+
+} // namespace PreferredExtendedPanID
+
+namespace ThreadNetworkTableSize {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType temp;
+ uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ *value = Traits::StorageToWorking(temp);
+ return status;
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
+}
+
+} // namespace ThreadNetworkTableSize
+
+namespace FeatureMap {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType temp;
+ uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ *value = Traits::StorageToWorking(temp);
+ return status;
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE,
+ markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
+}
+
+} // namespace FeatureMap
+
+namespace ClusterRevision {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType temp;
+ uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ *value = Traits::StorageToWorking(temp);
+ return status;
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE,
+ markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
+}
+
+} // namespace ClusterRevision
+
+} // namespace Attributes
+} // namespace ThreadNetworkDirectory
+
namespace WakeOnLan {
namespace Attributes {
diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h
index d7c5c77d861bd0..7ebe0abeca5474 100644
--- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h
+++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h
@@ -5334,6 +5334,41 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu
} // namespace Attributes
} // namespace WiFiNetworkManagement
+namespace ThreadNetworkDirectory {
+namespace Attributes {
+
+namespace PreferredExtendedPanID {
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int64u
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty);
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint);
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value,
+ MarkAttributeDirty markDirty);
+} // namespace PreferredExtendedPanID
+
+namespace ThreadNetworkTableSize {
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value); // int8u
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty);
+} // namespace ThreadNetworkTableSize
+
+namespace FeatureMap {
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty);
+} // namespace FeatureMap
+
+namespace ClusterRevision {
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value);
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty);
+} // namespace ClusterRevision
+
+} // namespace Attributes
+} // namespace ThreadNetworkDirectory
+
namespace WakeOnLan {
namespace Attributes {
diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h
index a3a86e3b222917..e260c824886cd6 100644
--- a/zzz_generated/app-common/app-common/zap-generated/callback.h
+++ b/zzz_generated/app-common/app-common/zap-generated/callback.h
@@ -538,6 +538,11 @@ void emberAfRadonConcentrationMeasurementClusterInitCallback(chip::EndpointId en
*/
void emberAfWiFiNetworkManagementClusterInitCallback(chip::EndpointId endpoint);
+/**
+ * @param endpoint Endpoint that is being initialized
+ */
+void emberAfThreadNetworkDirectoryClusterInitCallback(chip::EndpointId endpoint);
+
/**
* @param endpoint Endpoint that is being initialized
*/
@@ -4531,6 +4536,44 @@ chip::Protocols::InteractionModel::Status MatterWiFiNetworkManagementClusterServ
*/
void emberAfWiFiNetworkManagementClusterServerTickCallback(chip::EndpointId endpoint);
+//
+// Thread Network Directory Cluster
+//
+
+/**
+ * @param endpoint Endpoint that is being initialized
+ */
+void emberAfThreadNetworkDirectoryClusterServerInitCallback(chip::EndpointId endpoint);
+
+/**
+ * @param endpoint Endpoint that is being shutdown
+ */
+void MatterThreadNetworkDirectoryClusterServerShutdownCallback(chip::EndpointId endpoint);
+
+/**
+ * @param endpoint Endpoint that is being initialized
+ */
+void emberAfThreadNetworkDirectoryClusterClientInitCallback(chip::EndpointId endpoint);
+
+/**
+ * @param attributePath Concrete attribute path that changed
+ */
+void MatterThreadNetworkDirectoryClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath);
+
+/**
+ * @param attributePath Concrete attribute path to be changed
+ * @param attributeType Attribute type
+ * @param size Attribute size
+ * @param value Attribute value
+ */
+chip::Protocols::InteractionModel::Status MatterThreadNetworkDirectoryClusterServerPreAttributeChangedCallback(
+ const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value);
+
+/**
+ * @param endpoint Endpoint that is being served
+ */
+void emberAfThreadNetworkDirectoryClusterServerTickCallback(chip::EndpointId endpoint);
+
//
// Wake on LAN Cluster
//
@@ -6158,6 +6201,24 @@ bool emberAfColorControlClusterMoveColorTemperatureCallback(
bool emberAfColorControlClusterStepColorTemperatureCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::ColorControl::Commands::StepColorTemperature::DecodableType & commandData);
+/**
+ * @brief Thread Network Directory Cluster AddNetwork Command callback (from client)
+ */
+bool emberAfThreadNetworkDirectoryClusterAddNetworkCallback(
+ chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
+ const chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::DecodableType & commandData);
+/**
+ * @brief Thread Network Directory Cluster RemoveNetwork Command callback (from client)
+ */
+bool emberAfThreadNetworkDirectoryClusterRemoveNetworkCallback(
+ chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
+ const chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::DecodableType & commandData);
+/**
+ * @brief Thread Network Directory Cluster GetOperationalDataset Command callback (from client)
+ */
+bool emberAfThreadNetworkDirectoryClusterGetOperationalDatasetCallback(
+ chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
+ const chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::DecodableType & commandData);
/**
* @brief Channel Cluster ChangeChannel Command callback (from client)
*/
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index bad7df9b4b8fa8..df8ddd16ba31e3 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -4311,6 +4311,8 @@ enum class Feature : uint32_t
namespace WiFiNetworkManagement {} // namespace WiFiNetworkManagement
+namespace ThreadNetworkDirectory {} // namespace ThreadNetworkDirectory
+
namespace WakeOnLan {} // namespace WakeOnLan
namespace Channel {
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
index 3e72137d33179a..0e3ec1d0347e1f 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
@@ -22952,6 +22952,263 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre
namespace Events {} // namespace Events
} // namespace WiFiNetworkManagement
+namespace ThreadNetworkDirectory {
+namespace Structs {
+
+namespace ThreadNetworkStruct {
+CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
+{
+ DataModel::WrappedStructEncoder encoder{ aWriter, aTag };
+ encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID);
+ encoder.Encode(to_underlying(Fields::kNetworkName), networkName);
+ encoder.Encode(to_underlying(Fields::kChannel), channel);
+ return encoder.Finalize();
+}
+
+CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
+{
+ detail::StructDecodeIterator __iterator(reader);
+ while (true)
+ {
+ auto __element = __iterator.Next();
+ if (std::holds_alternative(__element))
+ {
+ return std::get(__element);
+ }
+
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ const uint8_t __context_tag = std::get(__element);
+
+ if (__context_tag == to_underlying(Fields::kExtendedPanID))
+ {
+ err = DataModel::Decode(reader, extendedPanID);
+ }
+ else if (__context_tag == to_underlying(Fields::kNetworkName))
+ {
+ err = DataModel::Decode(reader, networkName);
+ }
+ else if (__context_tag == to_underlying(Fields::kChannel))
+ {
+ err = DataModel::Decode(reader, channel);
+ }
+ else
+ {
+ }
+
+ ReturnErrorOnFailure(err);
+ }
+}
+
+} // namespace ThreadNetworkStruct
+} // namespace Structs
+
+namespace Commands {
+namespace AddNetwork {
+CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
+{
+ DataModel::WrappedStructEncoder encoder{ aWriter, aTag };
+ encoder.Encode(to_underlying(Fields::kOperationalDataset), operationalDataset);
+ return encoder.Finalize();
+}
+
+CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
+{
+ detail::StructDecodeIterator __iterator(reader);
+ while (true)
+ {
+ auto __element = __iterator.Next();
+ if (std::holds_alternative(__element))
+ {
+ return std::get(__element);
+ }
+
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ const uint8_t __context_tag = std::get(__element);
+
+ if (__context_tag == to_underlying(Fields::kOperationalDataset))
+ {
+ err = DataModel::Decode(reader, operationalDataset);
+ }
+ else
+ {
+ }
+
+ ReturnErrorOnFailure(err);
+ }
+}
+} // namespace AddNetwork.
+namespace RemoveNetwork {
+CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
+{
+ DataModel::WrappedStructEncoder encoder{ aWriter, aTag };
+ encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID);
+ return encoder.Finalize();
+}
+
+CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
+{
+ detail::StructDecodeIterator __iterator(reader);
+ while (true)
+ {
+ auto __element = __iterator.Next();
+ if (std::holds_alternative(__element))
+ {
+ return std::get(__element);
+ }
+
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ const uint8_t __context_tag = std::get(__element);
+
+ if (__context_tag == to_underlying(Fields::kExtendedPanID))
+ {
+ err = DataModel::Decode(reader, extendedPanID);
+ }
+ else
+ {
+ }
+
+ ReturnErrorOnFailure(err);
+ }
+}
+} // namespace RemoveNetwork.
+namespace GetOperationalDataset {
+CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
+{
+ DataModel::WrappedStructEncoder encoder{ aWriter, aTag };
+ encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID);
+ return encoder.Finalize();
+}
+
+CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
+{
+ detail::StructDecodeIterator __iterator(reader);
+ while (true)
+ {
+ auto __element = __iterator.Next();
+ if (std::holds_alternative(__element))
+ {
+ return std::get(__element);
+ }
+
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ const uint8_t __context_tag = std::get(__element);
+
+ if (__context_tag == to_underlying(Fields::kExtendedPanID))
+ {
+ err = DataModel::Decode(reader, extendedPanID);
+ }
+ else
+ {
+ }
+
+ ReturnErrorOnFailure(err);
+ }
+}
+} // namespace GetOperationalDataset.
+namespace OperationalDatasetResponse {
+CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
+{
+ DataModel::WrappedStructEncoder encoder{ aWriter, aTag };
+ encoder.Encode(to_underlying(Fields::kOperationalDataset), operationalDataset);
+ return encoder.Finalize();
+}
+
+CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
+{
+ detail::StructDecodeIterator __iterator(reader);
+ while (true)
+ {
+ auto __element = __iterator.Next();
+ if (std::holds_alternative(__element))
+ {
+ return std::get