diff --git a/data_model/clusters/BooleanSensorConfiguration.xml b/data_model/clusters/BooleanSensorConfiguration.xml
deleted file mode 100644
index 7321a70113087f..00000000000000
--- a/data_model/clusters/BooleanSensorConfiguration.xml
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
index 9c3e474946addf..e1dace194762d8 100644
--- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
+++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
@@ -3716,6 +3716,130 @@ cluster ActivatedCarbonFilterMonitoring = 114 {
command ResetCondition(): DefaultSuccess = 0;
}
+/** This cluster is used to configure a boolean sensor. */
+provisional cluster BooleanStateConfiguration = 128 {
+ revision 1;
+
+ bitmap AlarmModeBitmap : bitmap8 {
+ kVisual = 0x1;
+ kAudible = 0x2;
+ }
+
+ bitmap Feature : bitmap32 {
+ kVisual = 0x1;
+ kAudible = 0x2;
+ kAlarmSuppress = 0x4;
+ kSensitivityLevel = 0x8;
+ }
+
+ bitmap SensorFaultBitmap : bitmap16 {
+ kGeneralFault = 0x1;
+ }
+
+ info event AlarmsStateChanged = 0 {
+ AlarmModeBitmap alarmsActive = 0;
+ optional AlarmModeBitmap alarmsSuppressed = 1;
+ }
+
+ info event SensorFault = 1 {
+ SensorFaultBitmap sensorFault = 0;
+ }
+
+ attribute optional int8u currentSensitivityLevel = 0;
+ readonly attribute optional int8u supportedSensitivityLevels = 1;
+ readonly attribute optional int8u defaultSensitivityLevel = 2;
+ readonly attribute optional AlarmModeBitmap alarmsActive = 3;
+ readonly attribute optional AlarmModeBitmap alarmsSuppressed = 4;
+ readonly attribute optional AlarmModeBitmap alarmsEnabled = 5;
+ readonly attribute optional AlarmModeBitmap alarmsSupported = 6;
+ readonly attribute optional SensorFaultBitmap sensorFault = 7;
+ 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 SuppressAlarmRequest {
+ AlarmModeBitmap alarmsToSuppress = 0;
+ }
+
+ request struct EnableDisableAlarmRequest {
+ AlarmModeBitmap alarmsToEnableDisable = 0;
+ }
+
+ /** This command is used to suppress the specified alarm mode. */
+ command SuppressAlarm(SuppressAlarmRequest): DefaultSuccess = 0;
+ /** This command is used to enable or disable the specified alarm mode. */
+ command EnableDisableAlarm(EnableDisableAlarmRequest): DefaultSuccess = 1;
+}
+
+/** This cluster is used to configure a valve. */
+provisional cluster ValveConfigurationAndControl = 129 {
+ revision 1;
+
+ enum StatusCodeEnum : enum8 {
+ kFailureDueToFault = 2;
+ }
+
+ enum ValveStateEnum : enum8 {
+ kClosed = 0;
+ kOpen = 1;
+ kTransitioning = 2;
+ }
+
+ bitmap Feature : bitmap32 {
+ kTimeSync = 0x1;
+ kLevel = 0x2;
+ }
+
+ bitmap ValveFaultBitmap : bitmap16 {
+ kGeneralFault = 0x1;
+ kBlocked = 0x2;
+ kLeaking = 0x4;
+ kNotConnected = 0x8;
+ kShortCircuit = 0x10;
+ kCurrentExceeded = 0x20;
+ }
+
+ info event ValveStateChanged = 0 {
+ ValveStateEnum valveState = 0;
+ optional percent valveLevel = 1;
+ }
+
+ info event ValveFault = 1 {
+ ValveFaultBitmap valveFault = 0;
+ }
+
+ readonly attribute nullable elapsed_s openDuration = 0;
+ attribute nullable elapsed_s defaultOpenDuration = 1;
+ readonly attribute optional nullable epoch_us autoCloseTime = 2;
+ readonly attribute nullable elapsed_s remainingDuration = 3;
+ readonly attribute nullable ValveStateEnum currentState = 4;
+ readonly attribute nullable ValveStateEnum targetState = 5;
+ readonly attribute optional nullable percent currentLevel = 6;
+ readonly attribute optional nullable percent targetLevel = 7;
+ attribute optional percent defaultOpenLevel = 8;
+ readonly attribute optional ValveFaultBitmap valveFault = 9;
+ readonly attribute optional int8u levelStep = 10;
+ readonly attribute command_id generatedCommandList[] = 65528;
+ readonly attribute command_id acceptedCommandList[] = 65529;
+ readonly attribute event_id eventList[] = 65530;
+ readonly attribute attrib_id attributeList[] = 65531;
+ readonly attribute bitmap32 featureMap = 65532;
+ readonly attribute int16u clusterRevision = 65533;
+
+ request struct OpenRequest {
+ optional nullable elapsed_s openDuration = 0;
+ optional percent targetLevel = 1;
+ }
+
+ /** This command is used to set the valve to its open position. */
+ command Open(OpenRequest): DefaultSuccess = 0;
+ /** This command is used to set the valve to its closed position. */
+ command Close(): DefaultSuccess = 1;
+}
+
/** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */
provisional cluster ElectricalEnergyMeasurement = 145 {
revision 1;
@@ -7426,6 +7550,53 @@ endpoint 1 {
handle command ResetCondition;
}
+ server cluster BooleanStateConfiguration {
+ emits event AlarmsStateChanged;
+ emits event SensorFault;
+ callback attribute currentSensitivityLevel;
+ ram attribute supportedSensitivityLevels default = 3;
+ ram attribute defaultSensitivityLevel default = 2;
+ ram attribute alarmsActive;
+ ram attribute alarmsSuppressed;
+ persist attribute alarmsEnabled;
+ ram attribute alarmsSupported default = 0x03;
+ ram attribute sensorFault default = 0;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ ram attribute featureMap default = 0x0F;
+ ram attribute clusterRevision default = 1;
+
+ handle command SuppressAlarm;
+ handle command EnableDisableAlarm;
+ }
+
+ server cluster ValveConfigurationAndControl {
+ emits event ValveStateChanged;
+ emits event ValveFault;
+ ram attribute openDuration;
+ persist attribute defaultOpenDuration;
+ ram attribute autoCloseTime;
+ callback attribute remainingDuration;
+ ram attribute currentState;
+ ram attribute targetState;
+ ram attribute currentLevel;
+ ram attribute targetLevel;
+ persist attribute defaultOpenLevel default = 100;
+ ram attribute valveFault default = 0;
+ ram attribute levelStep default = 1;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ ram attribute featureMap default = 3;
+ ram attribute clusterRevision default = 1;
+
+ handle command Open;
+ handle command Close;
+ }
+
server cluster ElectricalEnergyMeasurement {
emits event CumulativeEnergyMeasured;
emits event PeriodicEnergyMeasured;
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
index 0c14d72717e091..fabe40ca88f598 100644
--- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
+++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
@@ -17,12 +17,6 @@
}
],
"package": [
- {
- "pathRelativity": "relativeToZap",
- "path": "../../../src/app/zap-templates/app-templates.json",
- "type": "gen-templates-json",
- "version": "chip-v1"
- },
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json",
@@ -30,6 +24,12 @@
"category": "matter",
"version": 1,
"description": "Matter SDK ZCL data with some extensions"
+ },
+ {
+ "pathRelativity": "relativeToZap",
+ "path": "../../../src/app/zap-templates/app-templates.json",
+ "type": "gen-templates-json",
+ "version": "chip-v1"
}
],
"endpointTypes": [
@@ -8427,7 +8427,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
- "defaultValue": "",
+ "defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
@@ -8459,7 +8459,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
- "defaultValue": "",
+ "defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
@@ -8475,7 +8475,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
- "defaultValue": "",
+ "defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
@@ -8491,7 +8491,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
- "defaultValue": "",
+ "defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
@@ -8507,7 +8507,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
- "defaultValue": "",
+ "defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
@@ -11803,6 +11803,592 @@
}
]
},
+ {
+ "name": "Boolean State Configuration",
+ "code": 128,
+ "mfgCode": null,
+ "define": "BOOLEAN_STATE_CONFIGURATION_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "apiMaturity": "provisional",
+ "commands": [
+ {
+ "name": "SuppressAlarm",
+ "code": 0,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ },
+ {
+ "name": "EnableDisableAlarm",
+ "code": 1,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ }
+ ],
+ "attributes": [
+ {
+ "name": "CurrentSensitivityLevel",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int8u",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "2",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "SupportedSensitivityLevels",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int8u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "3",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "DefaultSensitivityLevel",
+ "code": 2,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int8u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "2",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AlarmsActive",
+ "code": 3,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmModeBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AlarmsSuppressed",
+ "code": 4,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmModeBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AlarmsEnabled",
+ "code": 5,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmModeBitmap",
+ "included": 1,
+ "storageOption": "NVM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AlarmsSupported",
+ "code": 6,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmModeBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0x03",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "SensorFault",
+ "code": 7,
+ "mfgCode": null,
+ "side": "server",
+ "type": "SensorFaultBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0x0F",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ],
+ "events": [
+ {
+ "name": "AlarmsStateChanged",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "included": 1
+ },
+ {
+ "name": "SensorFault",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "included": 1
+ }
+ ]
+ },
+ {
+ "name": "Valve Configuration and Control",
+ "code": 129,
+ "mfgCode": null,
+ "define": "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "apiMaturity": "provisional",
+ "commands": [
+ {
+ "name": "Open",
+ "code": 0,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ },
+ {
+ "name": "Close",
+ "code": 1,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ }
+ ],
+ "attributes": [
+ {
+ "name": "OpenDuration",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "elapsed_s",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "DefaultOpenDuration",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "elapsed_s",
+ "included": 1,
+ "storageOption": "NVM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AutoCloseTime",
+ "code": 2,
+ "mfgCode": null,
+ "side": "server",
+ "type": "epoch_us",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "RemainingDuration",
+ "code": 3,
+ "mfgCode": null,
+ "side": "server",
+ "type": "elapsed_s",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "CurrentState",
+ "code": 4,
+ "mfgCode": null,
+ "side": "server",
+ "type": "ValveStateEnum",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "TargetState",
+ "code": 5,
+ "mfgCode": null,
+ "side": "server",
+ "type": "ValveStateEnum",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "CurrentLevel",
+ "code": 6,
+ "mfgCode": null,
+ "side": "server",
+ "type": "percent",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "TargetLevel",
+ "code": 7,
+ "mfgCode": null,
+ "side": "server",
+ "type": "percent",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "DefaultOpenLevel",
+ "code": 8,
+ "mfgCode": null,
+ "side": "server",
+ "type": "percent",
+ "included": 1,
+ "storageOption": "NVM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "100",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ValveFault",
+ "code": 9,
+ "mfgCode": null,
+ "side": "server",
+ "type": "ValveFaultBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "LevelStep",
+ "code": 10,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int8u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": null,
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "3",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ],
+ "events": [
+ {
+ "name": "ValveStateChanged",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "included": 1
+ },
+ {
+ "name": "ValveFault",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "included": 1
+ }
+ ]
+ },
{
"name": "Electrical Energy Measurement",
"code": 145,
diff --git a/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp
new file mode 100644
index 00000000000000..36716ec69ce52e
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp
@@ -0,0 +1,49 @@
+/*
+ *
+ * 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.
+ */
+
+#include
+#include
+
+#include
+
+using namespace chip;
+using namespace chip::app::Clusters::BooleanStateConfiguration;
+using namespace chip::DeviceLayer;
+
+bool HandleBooleanStateConfigurationTestEventTrigger(uint64_t eventTrigger)
+{
+ BooleanStateConfigurationTrigger trigger = static_cast(eventTrigger);
+
+ switch (trigger)
+ {
+ case BooleanStateConfigurationTrigger::kSensorTrigger:
+ ChipLogProgress(Support, "[BooleanStateConfiguration-Test-Event] => Trigger sensor");
+ SetAllEnabledAlarmsActive(1);
+ break;
+
+ case BooleanStateConfigurationTrigger::kSensorUntrigger:
+ ChipLogProgress(Support, "[BooleanStateConfiguration-Test-Event] => Untrigger sensor");
+ ClearAllAlarms(1);
+ break;
+
+ default:
+
+ return false;
+ }
+
+ return true;
+}
diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt
index c5d40048308c2d..89ce7c1c872160 100644
--- a/examples/all-clusters-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt
@@ -39,6 +39,7 @@ set(SRC_DIRS_LIST
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/test-cluster-server"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/boolean-state-configuration-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/descriptor"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/fault-injection-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/fan-control-server"
@@ -86,6 +87,7 @@ set(SRC_DIRS_LIST
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/resource-monitoring-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/valve-configuration-and-control-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/dishwasher-alarm-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-dryer-controls-server"
diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn
index 343372676bd8fc..b2cc122b5090ab 100644
--- a/examples/all-clusters-app/linux/BUILD.gn
+++ b/examples/all-clusters-app/linux/BUILD.gn
@@ -23,6 +23,7 @@ source_set("chip-all-clusters-common") {
sources = [
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp",
+ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp",
@@ -45,6 +46,7 @@ source_set("chip-all-clusters-common") {
"${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp",
"AllClustersCommandDelegate.cpp",
"AppOptions.cpp",
+ "ValveControlDelegate.cpp",
"WindowCoveringManager.cpp",
"include/tv-callbacks.cpp",
"include/tv-callbacks.h",
diff --git a/examples/all-clusters-app/linux/ValveControlDelegate.cpp b/examples/all-clusters-app/linux/ValveControlDelegate.cpp
new file mode 100644
index 00000000000000..9c51aff63101f5
--- /dev/null
+++ b/examples/all-clusters-app/linux/ValveControlDelegate.cpp
@@ -0,0 +1,76 @@
+/**
+ *
+ * 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.
+ */
+
+#include "ValveControlDelegate.h"
+#include
+#include
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters::ValveConfigurationAndControl;
+using namespace chip::app::Clusters::TimeSynchronization;
+
+static chip::Percent sLevel = 1;
+static uint32_t sLastOpenDuration = 0;
+static constexpr EndpointId kValveEndpoint = 1;
+
+DataModel::Nullable ValveControlDelegate::HandleOpenValve(DataModel::Nullable level)
+{
+ chip::Percent currentLevel = sLevel;
+ sLevel = level.IsNull() ? 100 : level.Value();
+ sLastOpenDuration = 0;
+ ChipLogProgress(NotSpecified, "Valve openinig from level: %d to %d", currentLevel, sLevel);
+
+ // In this demo application, the trasition is considered instant,
+ // so current level is set to the requested level and current state is set to kOpen.
+ currentLevel = sLevel;
+ Attributes::CurrentState::Set(kValveEndpoint, ValveConfigurationAndControl::ValveStateEnum::kOpen);
+
+ return DataModel::Nullable(currentLevel);
+}
+
+CHIP_ERROR ValveControlDelegate::HandleCloseValve()
+{
+ sLastOpenDuration = 0;
+ sLevel = 0;
+ ReturnErrorOnFailure(ValveConfigurationAndControl::UpdateCurrentLevel(kValveEndpoint, sLevel));
+ ReturnErrorOnFailure(
+ ValveConfigurationAndControl::UpdateCurrentState(kValveEndpoint, ValveConfigurationAndControl::ValveStateEnum::kClosed));
+ ChipLogProgress(NotSpecified, "Valve closed");
+ return CHIP_NO_ERROR;
+}
+
+void ValveControlDelegate::HandleRemainingDurationTick(uint32_t duration)
+{
+ ChipLogProgress(NotSpecified, "Valve remaining duration ticking: %dsec level: %d duration %d", duration, sLevel,
+ sLastOpenDuration);
+ if (sLastOpenDuration == 0)
+ {
+ VerifyOrReturn(CHIP_NO_ERROR == ValveConfigurationAndControl::UpdateCurrentLevel(kValveEndpoint, sLevel),
+ ChipLogError(NotSpecified, "Updating current level failed"));
+ VerifyOrReturn(CHIP_NO_ERROR ==
+ ValveConfigurationAndControl::UpdateCurrentState(kValveEndpoint,
+ ValveConfigurationAndControl::ValveStateEnum::kOpen),
+ ChipLogError(NotSpecified, "Updating current state failed"));
+ }
+ sLastOpenDuration = duration;
+}
+
+void ExtendedTimeSyncDelegate::UTCTimeChanged(uint64_t time)
+{
+ ValveConfigurationAndControl::UpdateAutoCloseTime(time);
+}
diff --git a/examples/all-clusters-app/linux/ValveControlDelegate.h b/examples/all-clusters-app/linux/ValveControlDelegate.h
new file mode 100644
index 00000000000000..76f0f17a8fdfd1
--- /dev/null
+++ b/examples/all-clusters-app/linux/ValveControlDelegate.h
@@ -0,0 +1,49 @@
+/**
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace ValveConfigurationAndControl {
+
+class ValveControlDelegate : public Delegate
+{
+public:
+ DataModel::Nullable HandleOpenValve(DataModel::Nullable level) override;
+ CHIP_ERROR HandleCloseValve() override;
+ void HandleRemainingDurationTick(uint32_t duration) override;
+};
+
+} // namespace ValveConfigurationAndControl
+
+namespace TimeSynchronization {
+
+class ExtendedTimeSyncDelegate : public DefaultTimeSyncDelegate
+{
+public:
+ void UTCTimeChanged(uint64_t time) override;
+};
+
+} // namespace TimeSynchronization
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/all-clusters-app/linux/args.gni b/examples/all-clusters-app/linux/args.gni
index 1bcd86f18843b8..d414ad5dedaf5d 100644
--- a/examples/all-clusters-app/linux/args.gni
+++ b/examples/all-clusters-app/linux/args.gni
@@ -28,3 +28,4 @@ matter_enable_tracing_support = true
matter_log_json_payload_decode_full = true
matter_log_json_payload_hex = true
chip_enable_smoke_co_trigger = true
+chip_enable_boolean_state_configuration_trigger = true
diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp
index 05435df44e81b8..49ee513ca33f95 100644
--- a/examples/all-clusters-app/linux/main-common.cpp
+++ b/examples/all-clusters-app/linux/main-common.cpp
@@ -17,6 +17,7 @@
*/
#include "AllClustersCommandDelegate.h"
+#include "ValveControlDelegate.h"
#include "WindowCoveringManager.h"
#include "air-quality-instance.h"
#include "dishwasher-mode.h"
@@ -38,6 +39,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -64,6 +67,8 @@ AllClustersCommandDelegate sAllClustersCommandDelegate;
Clusters::WindowCovering::WindowCoveringManager sWindowCoveringManager;
Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+Clusters::ValveConfigurationAndControl::ValveControlDelegate sValveDelegate;
+Clusters::TimeSynchronization::ExtendedTimeSyncDelegate sTimeSyncDelegate;
// Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces
constexpr const uint8_t kNamespaceCommon = 7;
@@ -218,6 +223,9 @@ void ApplicationInit()
#endif
Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
+ Clusters::ValveConfigurationAndControl::SetDefaultDelegate(chip::EndpointId(1), &sValveDelegate);
+ Clusters::TimeSynchronization::SetDefaultDelegate(&sTimeSyncDelegate);
+
SetTagList(/* endpoint= */ 0, Span(gEp0TagList));
SetTagList(/* endpoint= */ 1, Span(gEp1TagList));
SetTagList(/* endpoint= */ 2, Span(gEp2TagList));
diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter
index 6065ce3b36efc0..6023f53fa18bba 100644
--- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter
+++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter
@@ -1631,7 +1631,7 @@ cluster OccupancySensing = 1030 {
}
endpoint 0 {
- device type ma_rootdevice = 22, version 1;
+ device type ma_rootdevice = 22, version 2;
binding cluster OtaSoftwareUpdateProvider;
diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
index b37968d2d15978..8c58d93a8a6b41 100644
--- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
+++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap
@@ -51,7 +51,7 @@
}
],
"deviceVersions": [
- 1
+ 2
],
"deviceIdentifiers": [
22
@@ -4748,4 +4748,4 @@
}
],
"log": []
-}
\ No newline at end of file
+}
diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn
index 36f52d917f22db..cc87b4fc1532d6 100644
--- a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn
@@ -93,10 +93,7 @@ k32w0_executable("contact_sensor_app") {
"${k32w0_platform_dir}/common/CustomFactoryDataProvider.h",
]
- defines = [
- "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1",
- "CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS=3",
- ]
+ defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ]
}
deps = [
diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md
index f616ddfeeca4f9..27ae15b672eb05 100644
--- a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md
+++ b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md
@@ -177,56 +177,58 @@ contact status.
In order to build the Project CHIP example, we recommend using a Linux
distribution (the demo-application was compiled on Ubuntu 20.04).
-- Start building the application either with Secure Element or without, SDK is
- downloaded with west tool.
+Activate the Matter environment:
- - without Secure Element
+```bash
+user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
+```
- ```
- user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
+To bring the SDK in the environment, the user can:
+
+- download it with west tool, in which case it will be handled automatically
+ by gn:
+
+ ```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml
user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update
```
- In case there are local modification to the already installed git NXP SDK:
- Use the below west `forall` command instead of the west init command to
- reset the west workspace. Warning: all local changes will be lost after
+ In case there are local modification to the already installed github NXP
+ SDK, use the below `west forall` command instead of the `west init` command
+ to reset the west workspace. Warning: all local changes will be lost after
running this command.
```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
- user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$west forall -c "git reset --hard && git clean -xdf" -a
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west forall -c "git reset --hard && git clean -xdf" -a
```
- Build the application
-
- Prior to building, the user can specify a custom `SDK` path by setting
- `NXP_K32W0_SDK_ROOT`:
+- set up a custom path to the SDK, in which case
+ `k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\"` must be added to the `gn gen`
+ command:
```
- user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=$(pwd)/third_party/nxp/k32w0_sdk/repo/core
+ user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/custom/path/to/SDK
```
- If the environment variable `NXP_K32W0_SDK_ROOT` is not set, it will default
- to the `SDK` found in `third_party/nxp/k32w0_sdk/repo/core`.
+Start building the application:
- ```
- user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w0
- user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true"
- user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ ninja -C out/debug
- ```
+```bash
+user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w0
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true"
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ ninja -C out/debug
+```
- - with Secure element Exactly the same steps as above but set
- chip_with_se05x=1 in the gn command and add argument
- chip_enable_ota_requestor=false
+To build with Secure Element, follow the same steps as above but set
+`chip_with_se05x=1 chip_enable_ota_requestor=false` in the `gn gen` command.
-Note that option chip_enable_ota_requestor=false are required for building with
-Secure Element. These can be changed if building without Secure Element
+Note that option `chip_enable_ota_requestor=false` is required for building with
+Secure Element due to flash constraints.
- K32W041AM flavor
- Exactly the same steps as above but set argument build_for_k32w041am=1 in
+ Exactly the same steps as above but set argument `build_for_k32w041am=1` in
the gn command.
Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the
diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
index b48b97c55e6f94..72f94878cf328f 100644
--- a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
+++ b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
@@ -48,13 +48,6 @@
#define CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER 0
#endif
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
-#ifndef CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS
-// Set to 3: default number of custom Ids from CustomFactoryDataProvider example
-#define CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS 3
-#endif
-#endif
-
// VID/PID for product => will be used by Basic Information Cluster
#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037
#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA220
diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp
index 484ddce1b7ce1b..5c942db19b3af5 100644
--- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp
+++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp
@@ -85,7 +85,10 @@ using namespace chip::app;
AppTask AppTask::sAppTask;
#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-static AppTask::FactoryDataProvider sFactoryDataProvider;
+static chip::DeviceLayer::FactoryDataProviderImpl sFactoryDataProvider;
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+static chip::DeviceLayer::CustomFactoryDataProvider sCustomFactoryDataProvider;
+#endif
#endif
static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop,
@@ -199,6 +202,9 @@ CHIP_ERROR AppTask::Init()
SetDeviceInstanceInfoProvider(&sFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider);
SetCommissionableDataProvider(&sFactoryDataProvider);
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+ sCustomFactoryDataProvider.ParseFunctionExample();
+#endif
#else
#ifdef ENABLE_HSM_DEVICE_ATTESTATION
SetDeviceAttestationCredentialsProvider(Examples::GetExampleSe05xDACProvider());
diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h
index 58effbdba14162..867a496de1e56d 100644
--- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h
+++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h
@@ -49,15 +49,6 @@
class AppTask
{
-public:
-#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
- using FactoryDataProvider = chip::DeviceLayer::CustomFactoryDataProvider;
-#else
- using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl;
-#endif
-#endif
-
public:
CHIP_ERROR StartAppTask();
static void AppTaskMain(void * pvParameter);
diff --git a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
index a71bf63dc6d4e0..93bf1dc363f9dd 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
@@ -95,10 +95,7 @@ k32w0_executable("light_app") {
"${k32w0_platform_dir}/common/CustomFactoryDataProvider.h",
]
- defines = [
- "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1",
- "CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS=3",
- ]
+ defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ]
}
deps = [
diff --git a/examples/lighting-app/nxp/k32w/k32w0/README.md b/examples/lighting-app/nxp/k32w/k32w0/README.md
index b43a08622eb330..3194d71b39b889 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/README.md
+++ b/examples/lighting-app/nxp/k32w/k32w0/README.md
@@ -192,58 +192,58 @@ effects:
In order to build the Project CHIP example, we recommend using a Linux
distribution (the demo-application was compiled on Ubuntu 20.04).
-- Start building the application either with Secure Element or without, SDK is
- downloaded with west tool.
- - without Secure Element
+Activate the Matter environment:
-```
+```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
-user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update
```
-In case there are local modification to the already installed git NXP SDK: Use
-the below west `forall` command instead of the west init command to reset the
-west workspace. Warning: all local changes will be lost after running this
-command.
+To bring the SDK in the environment, the user can:
-```bash
-user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$west forall -c "git reset --hard && git clean -xdf" -a
-```
+- download it with west tool, in which case it will be handled automatically
+ by gn:
-Build the application
+ ```bash
+ user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update
+ ```
-Prior to building, the user can specify a custom `SDK` path by setting
-`NXP_K32W0_SDK_ROOT`:
+ In case there are local modification to the already installed github NXP
+ SDK, use the below `west forall` command instead of the `west init` command
+ to reset the west workspace. Warning: all local changes will be lost after
+ running this command.
-```
-user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=$(pwd)/third_party/nxp/k32w0_sdk/repo/core
-```
+ ```bash
+ user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west forall -c "git reset --hard && git clean -xdf" -a
+ ```
+
+- set up a custom path to the SDK, in which case
+ `k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\"` must be added to the `gn gen`
+ command:
-If the environment variable `NXP_K32W0_SDK_ROOT` is not set, it will default to
-the `SDK` found in `third_party/nxp/k32w0_sdk/repo/core`.
+ ```
+ user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/custom/path/to/SDK
+ ```
-```
+Start building the application:
+
+```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w/k32w0
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true"
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ ninja -C out/debug
```
- - with Secure element
-
-```
- Exactly the same steps as above but set chip_with_se05x=1 in the gn command
- and add argument chip_enable_ota_requestor=false
-```
+To build with Secure Element, follow the same steps as above but set
+`chip_with_se05x=1 chip_enable_ota_requestor=false` in the `gn gen` command.
-Note that option chip_enable_ota_requestor=false are required for building with
-Secure Element. These can be changed if building without Secure Element
+Note that option `chip_enable_ota_requestor=false` is required for building with
+Secure Element due to flash constraints.
- K32W041AM flavor
- Exactly the same steps as above but set argument build_for_k32w041am=1 in
+ Exactly the same steps as above but set argument `build_for_k32w041am=1` in
the gn command.
Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the
diff --git a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
index 10019a4268cad2..946d457622e467 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
+++ b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
@@ -48,13 +48,6 @@
#define CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER 0
#endif
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
-#ifndef CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS
-// Set to 3: default number of custom Ids from CustomFactoryDataProvider example
-#define CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS 3
-#endif
-#endif
-
// VID/PID for product => will be used by Basic Information Cluster
#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037
#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA220
diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
index e63c35a1489ee0..557293f6bac2aa 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
+++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
@@ -85,7 +85,10 @@ using namespace chip::app;
AppTask AppTask::sAppTask;
#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-static AppTask::FactoryDataProvider sFactoryDataProvider;
+static chip::DeviceLayer::FactoryDataProviderImpl sFactoryDataProvider;
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+static chip::DeviceLayer::CustomFactoryDataProvider sCustomFactoryDataProvider;
+#endif
#endif
// This key is for testing/certification only and should not be used in production devices.
@@ -190,6 +193,9 @@ CHIP_ERROR AppTask::Init()
SetDeviceInstanceInfoProvider(&sFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider);
SetCommissionableDataProvider(&sFactoryDataProvider);
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+ sCustomFactoryDataProvider.ParseFunctionExample();
+#endif
#else
#ifdef ENABLE_HSM_DEVICE_ATTESTATION
SetDeviceAttestationCredentialsProvider(Examples::GetExampleSe05xDACProvider());
diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h
index 83dfd33da2abd9..9590734521d5e1 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h
+++ b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h
@@ -49,15 +49,6 @@
class AppTask
{
-public:
-#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
- using FactoryDataProvider = chip::DeviceLayer::CustomFactoryDataProvider;
-#else
- using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl;
-#endif
-#endif
-
public:
CHIP_ERROR StartAppTask();
static void AppTaskMain(void * pvParameter);
diff --git a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn
index fd095a2cb197c5..a7643a9f847931 100644
--- a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn
+++ b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn
@@ -82,6 +82,8 @@ k32w1_executable("light_app") {
"main/main.cpp",
]
+ public = [ "${chip_root}/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h" ]
+
deps = [
":sdk",
"${chip_root}/examples/common/QRCode",
diff --git a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn b/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
index 0b752583604a89..c755514d66a175 100644
--- a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
@@ -92,10 +92,7 @@ k32w0_executable("lock_app") {
"${k32w0_platform_dir}/common/CustomFactoryDataProvider.h",
]
- defines = [
- "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1",
- "CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS=3",
- ]
+ defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ]
}
deps = [
diff --git a/examples/lock-app/nxp/k32w/k32w0/README.md b/examples/lock-app/nxp/k32w/k32w0/README.md
index b5fec55268371c..49920906819b0f 100644
--- a/examples/lock-app/nxp/k32w/k32w0/README.md
+++ b/examples/lock-app/nxp/k32w/k32w0/README.md
@@ -173,59 +173,67 @@ will be initiated.
In order to build the Project CHIP example, we recommend using a Linux
distribution (the demo-application was compiled on Ubuntu 20.04).
-- Start building the application either with Secure Element or without, SDK is
- downloaded with west tool.
+Activate the Matter environment:
- - without Secure Element
-
-```
+```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
-user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update
```
-In case there are local modification to the already installed git NXP SDK: Use
-the below west `forall` command instead of the west init command to reset the
-west workspace. Warning: all local changes will be lost after running this
-command.
+To bring the SDK in the environment, the user can:
-```bash
-user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
-user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$west forall -c "git reset --hard && git clean -xdf" -a
-```
+- download it with west tool, in which case it will be handled automatically
+ by gn:
-Build the application
+ ```bash
+ user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update
+ ```
-Prior to building, the user can specify a custom `SDK` path by setting
-`NXP_K32W0_SDK_ROOT`:
+ In case there are local modification to the already installed github NXP
+ SDK, use the below `west forall` command instead of the `west init` command
+ to reset the west workspace. Warning: all local changes will be lost after
+ running this command.
-```
-user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=$(pwd)/third_party/nxp/k32w0_sdk/repo/core
-```
+ ```bash
+ user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo
+ user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west forall -c "git reset --hard && git clean -xdf" -a
+ ```
-If the environment variable `NXP_K32W0_SDK_ROOT` is not set, it will default to
-the `SDK` found in `third_party/nxp/k32w0_sdk/repo/core`.
+- set up a custom path to the SDK, in which case
+ `k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\"` must be added to the `gn gen`
+ command:
-```
+ ```
+ user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/custom/path/to/SDK
+ ```
+
+Start building the application:
+
+```bash
user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lock-app/nxp/k32w/k32w0
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true"
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ ninja -C out/debug
```
- - with Secure element
- Exactly the same steps as above but set chip_with_se05x=1 in the gn command.
+To build with Secure Element, follow the same steps as above but set
+`chip_with_se05x=1` in the `gn gen` command.
+
+- K32W041AM flavor
+
+ Exactly the same steps as above but set argument `build_for_k32w041am=1` in
+ the gn command.
Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the
-build argument (chip_with_OM15082) inside the gn build instruction should be set
-to zero. The argument chip_with_OM15082 is set to zero by default.
+build argument (`chip_with_OM15082`) inside the gn build instruction should be
+set to zero. The argument `chip_with_OM15082` is set to zero by default.
-In case that Openthread CLI is needed, chip_with_ot_cli build argument must be
+In case that Openthread CLI is needed, `chip_with_ot_cli` build argument must be
set to 1.
In case the board doesn't have 32KHz crystal fitted, one can use the 32KHz free
-running oscillator as a clock source. In this case one must set the use_fro_32k
-argument to 1.
+running oscillator as a clock source. In this case one must set the
+`use_fro_32k` argument to 1.
In case signing errors are encountered when running the "sign_images.sh" script
(run automatically) install the recommanded packages (python version > 3, pip3,
diff --git a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
index c74714bded920f..43598870fb7533 100644
--- a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
+++ b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
@@ -48,13 +48,6 @@
#define CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER 0
#endif
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
-#ifndef CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS
-// Set to 3: default number of custom Ids from CustomFactoryDataProvider example
-#define CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS 3
-#endif
-#endif
-
// VID/PID for product => will be used by Basic Information Cluster
#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037
#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA220
diff --git a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
index fff749b311678e..130569791e2e8e 100644
--- a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
+++ b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
@@ -71,7 +71,10 @@ using namespace ::chip::DeviceLayer;
AppTask AppTask::sAppTask;
#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-static AppTask::FactoryDataProvider sFactoryDataProvider;
+static chip::DeviceLayer::FactoryDataProviderImpl sFactoryDataProvider;
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+static chip::DeviceLayer::CustomFactoryDataProvider sCustomFactoryDataProvider;
+#endif
#endif
CHIP_ERROR AppTask::StartAppTask()
@@ -102,6 +105,9 @@ CHIP_ERROR AppTask::Init()
SetDeviceInstanceInfoProvider(&sFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider);
SetCommissionableDataProvider(&sFactoryDataProvider);
+#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
+ sCustomFactoryDataProvider.ParseFunctionExample();
+#endif
#else
#ifdef ENABLE_HSM_DEVICE_ATTESTATION
SetDeviceAttestationCredentialsProvider(Examples::GetExampleSe05xDACProvider());
diff --git a/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h
index cbaa5757374497..1addd9236c4bcf 100644
--- a/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h
+++ b/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h
@@ -40,15 +40,6 @@
class AppTask
{
-public:
-#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
- using FactoryDataProvider = chip::DeviceLayer::CustomFactoryDataProvider;
-#else
- using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl;
-#endif
-#endif
-
public:
CHIP_ERROR StartAppTask();
static void AppTaskMain(void * pvParameter);
diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp
index 04ed5ad74fa8cc..86382f75665c06 100644
--- a/examples/platform/linux/AppMain.cpp
+++ b/examples/platform/linux/AppMain.cpp
@@ -80,6 +80,9 @@
#if CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER
#include
#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_BOOLEAN_STATE_CONFIGURATION_TRIGGER
+#include
+#endif
#include
#include
@@ -551,6 +554,12 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
ByteSpan(LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey), otherDelegate
};
otherDelegate = &smokeCOTestEventTriggerDelegate;
+#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_BOOLEAN_STATE_CONFIGURATION_TRIGGER
+ static BooleanStateConfigurationTestEventTriggerDelegate booleanStateConfigurationTestEventTriggerDelegate{
+ ByteSpan(LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey), otherDelegate
+ };
+ otherDelegate = &booleanStateConfigurationTestEventTriggerDelegate;
#endif
// For general testing of TestEventTrigger, we have a common "core" event trigger delegate.
static SampleTestEventTriggerDelegate testEventTriggerDelegate;
diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn
index 46229c5f7ed42c..4a4099c4150bf5 100644
--- a/examples/platform/linux/BUILD.gn
+++ b/examples/platform/linux/BUILD.gn
@@ -21,6 +21,8 @@ import("${chip_root}/src/tracing/tracing_args.gni")
declare_args() {
chip_enable_smoke_co_trigger = false
+
+ chip_enable_boolean_state_configuration_trigger = false
}
config("app-main-config") {
@@ -37,6 +39,10 @@ source_set("smco-test-event-trigger") {
sources = [ "${chip_root}/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h" ]
}
+source_set("boolean-state-configuration-test-event-trigger") {
+ sources = [ "${chip_root}/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.h" ]
+}
+
source_set("app-main") {
defines = [ "ENABLE_TRACING=${matter_enable_tracing_support}" ]
sources = [
@@ -59,6 +65,7 @@ source_set("app-main") {
]
public_deps = [
+ ":boolean-state-configuration-test-event-trigger",
":smco-test-event-trigger",
"${chip_root}/src/lib",
"${chip_root}/src/platform/logging:force_stdio",
@@ -94,7 +101,10 @@ source_set("app-main") {
]
}
- defines += [ "CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER=${chip_enable_smoke_co_trigger}" ]
+ defines += [
+ "CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER=${chip_enable_smoke_co_trigger}",
+ "CHIP_DEVICE_CONFIG_ENABLE_BOOLEAN_STATE_CONFIGURATION_TRIGGER=${chip_enable_boolean_state_configuration_trigger}",
+ ]
public_configs = [ ":app-main-config" ]
}
diff --git a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp
index 18e809509fc803..7f2f6d9bc0cad0 100644
--- a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp
+++ b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp
@@ -24,21 +24,10 @@ static constexpr size_t kMaxLengthCustomId1 = 10;
static constexpr size_t kMaxLengthCustomId2 = 50;
static constexpr size_t kMaxLengthCustomId3 = 100;
-CustomFactoryDataProvider & CustomFactoryDataProvider::GetDefaultInstance()
+CustomFactoryDataProvider::CustomFactoryDataProvider()
{
- static CustomFactoryDataProvider sInstance;
- return sInstance;
-}
-
-CHIP_ERROR CustomFactoryDataProvider::SetCustomIds()
-{
- static_assert(CustomFactoryIds::kCustomMaxId == FactoryDataProvider::kNumberOfIds,
- "kNumberOfIds is computed based on CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS.");
- maxLengths[CustomFactoryIds::kCustomId1] = kMaxLengthCustomId1;
- maxLengths[CustomFactoryIds::kCustomId2] = kMaxLengthCustomId2;
- maxLengths[CustomFactoryIds::kCustomId3] = kMaxLengthCustomId3;
-
- return CHIP_NO_ERROR;
+ // Custom ids should be from a range that does not overlap with the standard factory data range.
+ static_assert((uint16_t) CustomFactoryIds::kCustomId1 >= (uint16_t) FactoryDataProvider::FactoryDataId::kMaxId);
}
CHIP_ERROR CustomFactoryDataProvider::ParseFunctionExample()
@@ -49,7 +38,9 @@ CHIP_ERROR CustomFactoryDataProvider::ParseFunctionExample()
uint16_t userDataSize = 0;
// A user can use FactoryDataProvider::SearchForId to read an id from internal
// flash factory data section.
- ReturnErrorOnFailure(SearchForId(CustomFactoryIds::kCustomId1, buffer.data(), buffer.size(), userDataSize));
+ auto * provider = static_cast(DeviceLayer::GetDeviceInstanceInfoProvider());
+ ReturnErrorOnFailure((provider != nullptr) ? CHIP_NO_ERROR : CHIP_ERROR_INVALID_ADDRESS);
+ ReturnErrorOnFailure(provider->SearchForId(CustomFactoryIds::kCustomId1, buffer.data(), buffer.size(), userDataSize));
// Data should now be ready for custom parsing.
diff --git a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h
index 9edd603b4677c8..dfb722d67fdc11 100644
--- a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h
+++ b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h
@@ -27,26 +27,21 @@ namespace DeviceLayer {
* provider based on this example.
*/
-class CustomFactoryDataProvider : public FactoryDataProviderImpl
+class CustomFactoryDataProvider
{
public:
- /* Custom IDs should start from FactoryDataId::kMaxId, which is
+ /* Custom IDs should start from at least FactoryDataId::kMaxId, which is
* the next available valid ID. Last default ID is kMaxId - 1.
*/
enum CustomFactoryIds
{
- kCustomId1 = FactoryDataId::kMaxId,
+ kCustomId1 = 200, // Random id that is greater than FactoryDataId::kMaxId.
kCustomId2,
kCustomId3,
kCustomMaxId
};
- static CustomFactoryDataProvider & GetDefaultInstance();
-
- CustomFactoryDataProvider() {}
-
- /* SetCustomIds() must be implemented in order to define custom IDs. */
- CHIP_ERROR SetCustomIds() override;
+ CustomFactoryDataProvider();
/* Declare here custom functions to be implemented. */
CHIP_ERROR ParseFunctionExample();
diff --git a/examples/platform/nxp/k32w/k32w0/common/README.md b/examples/platform/nxp/k32w/k32w0/common/README.md
index 459f62f049e337..59347d6bfd205d 100644
--- a/examples/platform/nxp/k32w/k32w0/common/README.md
+++ b/examples/platform/nxp/k32w/k32w0/common/README.md
@@ -12,10 +12,11 @@ following interfaces:
- DeviceAttestationCredentialsProvider
- DeviceInstanceInfoProvider
-A user can inherit `FactoryDataProviderImpl` to provide additional functionality
-(such as parsing custom factory data fields) that is customer specific.
+A user can use `FactoryDataProvider::SearchForId` API to extract information
+about custom factory data ids.
-What **shall** be done to enable usage of a custom factory provider:
+What **shall** be done to enable usage of a custom factory provider in the
+reference app:
- Set `use_custom_factory_provider=1`. This option is only available when
factory data is used (`chip_with_factory_data=1`). An assert will be raised
@@ -33,28 +34,15 @@ What **shall** be done to enable usage of a custom factory provider:
defines = [
"CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1",
- "CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS=3"
]
}
```
- Note that new flags were introduced:
-
- - `CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER`: select between using
- `FactoryDataProviderImpl` or `CustomFactoryDataProvider` when
- registering the provider.
- - `CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS`: set the number of
- custom IDs (which are different than the default IDs). If this macro is
- not correctly set, compilation should fail.
-
-- The default IDs are validated directly in `SearchForId`, but custom IDs
- should set their maximum lengths through `SetCustomIds` method.
-- `FactoryDataProvider::kNumberOfIds` is computed at compile time and should
- represent the number of IDs (custom + default). Custom IDs should start from
- `FactoryDataId::kMaxId`, which is the next valid ID. IDs
- `[1, FactoryDataId::kMaxId - 1]` are reserved for default factory data IDs.
-
-Please refer to `CustomFactoryDataProvider` for a minimal example of a custom
-factory data provider and note that its implementation is just an example of how
-to integrate a custom provider into the application, while still using the
-default implementation provided by `FactoryDataProviderImpl`.
+Note that new flags were introduced:
+
+- `CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER`: add custom factory data related
+ code in reference app.
+
+Please refer to `CustomFactoryDataProvider` for a minimal example of leveraging
+the standard factory data provider to parse custom factory data information.
+Real applications could use the public API of `FactoryDataProvider` directly.
diff --git a/scripts/py_matter_idl/matter_idl/backwards_compatibility.py b/scripts/py_matter_idl/matter_idl/backwards_compatibility.py
index 9a6684c8031b9a..99adaf7a64bc0b 100644
--- a/scripts/py_matter_idl/matter_idl/backwards_compatibility.py
+++ b/scripts/py_matter_idl/matter_idl/backwards_compatibility.py
@@ -17,7 +17,7 @@
import logging
from typing import Callable, Dict, List, Optional, Protocol, TypeVar
-from matter_idl.matter_idl_types import Attribute, Bitmap, Cluster, Command, Enum, Event, Field, Idl, Struct
+from matter_idl.matter_idl_types import ApiMaturity, Attribute, Bitmap, Cluster, Command, Enum, Event, Field, Idl, Struct
class Compatibility(enum.Enum):
@@ -52,6 +52,13 @@ def attribute_name(attribute: Attribute) -> str:
return attribute.definition.name
+def not_stable(maturity: ApiMaturity):
+ """Determine if the given api maturity allows binary/api changes or not."""
+ # TODO: internal and deprecated not currently widely used,
+ # so we enforce stability on them for now.
+ return maturity == ApiMaturity.PROVISIONAL
+
+
class CompatibilityChecker:
def __init__(self, original: Idl, updated: Idl):
self._original_idl = original
@@ -271,6 +278,11 @@ def _check_cluster_list_compatible(self, original: List[Cluster], updated: List[
for original_cluster in original:
updated_cluster = updated_clusters.get(original_cluster.name)
+
+ if not_stable(updated_cluster.api_maturity) or not_stable(original_cluster.api_maturity):
+ # no point in checking
+ continue
+
self._check_cluster_compatible(original_cluster, updated_cluster)
def _check_cluster_compatible(self, original_cluster: Cluster, updated_cluster: Optional[Cluster]):
diff --git a/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py b/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py
index dece1632ac4719..e94e79abd5fce5 100755
--- a/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py
+++ b/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py
@@ -104,6 +104,13 @@ def test_clusters_enum_add_remove(self):
"server cluster A = 16 { enum X : ENUM8 { A = 1; }}",
Compatibility.FORWARD_FAIL)
+ def test_provisional_cluster(self):
+ self.ValidateUpdate(
+ "Provisional cluster changes are ok.",
+ "provisional server cluster A = 16 { enum X : ENUM8 { A = 1; B = 2; } info event A = 1 { int8u x = 1;} }",
+ "provisional server cluster A = 16 { enum X : ENUM8 { A = 1; B = 3; } info event A = 2 { int16u x = 1;} }",
+ Compatibility.ALL_OK)
+
def test_clusters_enum_code(self):
self.ValidateUpdate(
"Adding an enum is ok. Also validates code formatting",
diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni
index b882c875dc3ac2..a22e4811433802 100644
--- a/src/app/chip_data_model.gni
+++ b/src/app/chip_data_model.gni
@@ -324,6 +324,13 @@ template("chip_data_model") {
"${_app_root}/clusters/${cluster}/SmokeCOTestEventTriggerDelegate.cpp",
"${_app_root}/clusters/${cluster}/SmokeCOTestEventTriggerDelegate.h",
]
+ } else if (cluster == "boolean-state-configuration-server") {
+ sources += [
+ "${_app_root}/clusters/${cluster}/${cluster}.cpp",
+ "${_app_root}/clusters/${cluster}/${cluster}.h",
+ "${_app_root}/clusters/${cluster}/BooleanStateConfigurationTestEventTriggerDelegate.cpp",
+ "${_app_root}/clusters/${cluster}/BooleanStateConfigurationTestEventTriggerDelegate.h",
+ ]
} else if (cluster == "air-quality-server") {
sources += [
"${_app_root}/clusters/${cluster}/${cluster}.cpp",
diff --git a/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.cpp b/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.cpp
new file mode 100644
index 00000000000000..00a42592929671
--- /dev/null
+++ b/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.cpp
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ */
+
+#include "BooleanStateConfigurationTestEventTriggerDelegate.h"
+
+using namespace chip::app::Clusters::BooleanStateConfiguration;
+
+namespace chip {
+
+bool BooleanStateConfigurationTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const
+{
+ return !mEnableKey.empty() && mEnableKey.data_equal(enableKey);
+}
+
+CHIP_ERROR BooleanStateConfigurationTestEventTriggerDelegate::HandleEventTrigger(uint64_t eventTrigger)
+{
+ if (HandleBooleanStateConfigurationTestEventTrigger(eventTrigger))
+ {
+ return CHIP_NO_ERROR;
+ }
+ if (mOtherDelegate != nullptr)
+ {
+ return mOtherDelegate->HandleEventTrigger(eventTrigger);
+ }
+ return CHIP_ERROR_INVALID_ARGUMENT;
+}
+
+} // namespace chip
diff --git a/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.h b/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.h
new file mode 100644
index 00000000000000..43b68e284497e0
--- /dev/null
+++ b/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationTestEventTriggerDelegate.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace chip {
+
+enum class BooleanStateConfigurationTrigger : uint64_t
+{
+ kSensorTrigger = 0x0080000000000000,
+ kSensorUntrigger = 0x0080000000000001,
+};
+
+class BooleanStateConfigurationTestEventTriggerDelegate : public TestEventTriggerDelegate
+{
+public:
+ explicit BooleanStateConfigurationTestEventTriggerDelegate(const ByteSpan & enableKey,
+ TestEventTriggerDelegate * otherDelegate) :
+ mEnableKey(enableKey),
+ mOtherDelegate(otherDelegate)
+ {}
+
+ bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override;
+ CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override;
+
+private:
+ ByteSpan mEnableKey;
+ TestEventTriggerDelegate * mOtherDelegate;
+};
+
+} // namespace chip
+
+/**
+ * @brief User handler for handling the test event trigger
+ *
+ * @note If TestEventTrigger is enabled, it needs to be implemented in the app
+ *
+ * @param eventTrigger Event trigger to handle
+ *
+ * @retval true on success
+ * @retval false if error happened
+ */
+bool HandleBooleanStateConfigurationTestEventTrigger(uint64_t eventTrigger);
diff --git a/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-delegate.h b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-delegate.h
new file mode 100644
index 00000000000000..4fd84a43f43cda
--- /dev/null
+++ b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-delegate.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace BooleanStateConfiguration {
+
+/** @brief
+ * Defines methods for implementing application-specific logic for the Boolean State Configuration Cluster.
+ */
+class Delegate
+{
+public:
+ Delegate(){};
+
+ virtual CHIP_ERROR HandleSuppressAlarm(BooleanStateConfiguration::AlarmModeBitmap alarmToSuppress) = 0;
+ virtual CHIP_ERROR HandleEnableDisableAlarms(chip::BitMask alarms) = 0;
+
+ virtual ~Delegate() = default;
+};
+
+} // namespace BooleanStateConfiguration
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.cpp b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.cpp
new file mode 100644
index 00000000000000..dd81c90cd00191
--- /dev/null
+++ b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.cpp
@@ -0,0 +1,443 @@
+/**
+ *
+ * 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.
+ *
+ */
+
+#include "boolean-state-configuration-server.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::BooleanStateConfiguration::Attributes;
+using chip::app::Clusters::BooleanStateConfiguration::Delegate;
+using chip::Protocols::InteractionModel::Status;
+
+static constexpr size_t kBooleanStateConfigurationDelegateTableSize =
+ EMBER_AF_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
+
+static_assert(kBooleanStateConfigurationDelegateTableSize <= kEmberInvalidEndpointIndex,
+ "BooleanStateConfiguration Delegate table size error");
+
+static constexpr uint8_t kMinSupportedSensitivityLevels = 2;
+static constexpr uint8_t kMaxSupportedSensitivityLevels = 10;
+
+static CHIP_ERROR StoreCurrentSensitivityLevel(EndpointId ep, uint8_t level);
+
+namespace {
+Delegate * gDelegateTable[kBooleanStateConfigurationDelegateTableSize] = { nullptr };
+
+Delegate * GetDelegate(EndpointId endpoint)
+{
+ uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, BooleanStateConfiguration::Id,
+ EMBER_AF_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT);
+ return (ep >= kBooleanStateConfigurationDelegateTableSize ? nullptr : gDelegateTable[ep]);
+}
+
+bool isDelegateNull(Delegate * delegate)
+{
+ if (delegate == nullptr)
+ {
+ return true;
+ }
+ return false;
+}
+
+class BooleanStateConfigAttrAccess : public AttributeAccessInterface
+{
+public:
+ BooleanStateConfigAttrAccess() : AttributeAccessInterface(Optional::Missing(), BooleanStateConfiguration::Id) {}
+
+ CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override;
+ CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
+
+private:
+ CHIP_ERROR WriteCurrentSensitivityLevel(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder);
+ CHIP_ERROR ReadCurrentSensitivityLevel(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder);
+};
+
+BooleanStateConfigAttrAccess gAttrAccess;
+
+CHIP_ERROR BooleanStateConfigAttrAccess::WriteCurrentSensitivityLevel(const ConcreteDataAttributePath & aPath,
+ AttributeValueDecoder & aDecoder)
+{
+ uint8_t curSenLevel;
+ ReturnErrorOnFailure(aDecoder.Decode(curSenLevel));
+
+ return StoreCurrentSensitivityLevel(aPath.mEndpointId, curSenLevel);
+}
+
+CHIP_ERROR BooleanStateConfigAttrAccess::ReadCurrentSensitivityLevel(const ConcreteReadAttributePath & aPath,
+ AttributeValueEncoder & aEncoder)
+{
+ uint8_t senLevel;
+ CHIP_ERROR err = GetSafeAttributePersistenceProvider()->ReadScalarValue(aPath, senLevel);
+ if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
+ {
+ uint8_t supportedSensLevel;
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == SupportedSensitivityLevels::Get(aPath.mEndpointId, &supportedSensLevel),
+ CHIP_IM_GLOBAL_STATUS(Failure));
+ VerifyOrReturnError(supportedSensLevel >= kMinSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(Failure));
+ VerifyOrReturnError(supportedSensLevel <= kMaxSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(Failure));
+ senLevel = static_cast(supportedSensLevel - 1);
+ }
+ else if (err != CHIP_NO_ERROR)
+ {
+ return err;
+ }
+
+ ReturnErrorOnFailure(aEncoder.Encode(senLevel));
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BooleanStateConfigAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
+{
+ if (aPath.mClusterId != BooleanStateConfiguration::Id)
+ {
+ return CHIP_ERROR_INVALID_PATH_LIST;
+ }
+
+ switch (aPath.mAttributeId)
+ {
+ case CurrentSensitivityLevel::Id: {
+ return ReadCurrentSensitivityLevel(aPath, aEncoder);
+ }
+ default: {
+ break;
+ }
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BooleanStateConfigAttrAccess::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder)
+{
+ if (aPath.mClusterId != BooleanStateConfiguration::Id)
+ {
+ return CHIP_ERROR_INVALID_PATH_LIST;
+ }
+
+ switch (aPath.mAttributeId)
+ {
+ case CurrentSensitivityLevel::Id: {
+ return WriteCurrentSensitivityLevel(aPath, aDecoder);
+ }
+ default: {
+ break;
+ }
+ }
+
+ return CHIP_NO_ERROR;
+}
+} // namespace
+
+static bool emitAlarmsStateChangedEvent(EndpointId ep)
+{
+ if (!HasFeature(ep, BooleanStateConfiguration::Feature::kAudible) &&
+ !HasFeature(ep, BooleanStateConfiguration::Feature::kVisual))
+ {
+ return false;
+ }
+
+ BooleanStateConfiguration::Events::AlarmsStateChanged::Type event;
+ BitMask active;
+ VerifyOrReturnValue(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Get(ep, &active), false);
+ event.alarmsActive = active;
+
+ if (HasFeature(ep, BooleanStateConfiguration::Feature::kAlarmSuppress))
+ {
+ BitMask suppressed;
+ VerifyOrReturnValue(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Get(ep, &suppressed), false);
+ event.alarmsSuppressed.SetValue(suppressed);
+ }
+
+ EventNumber eventNumber;
+
+ CHIP_ERROR error = LogEvent(event, ep, eventNumber);
+
+ if (CHIP_NO_ERROR != error)
+ {
+ ChipLogError(Zcl, "Unable to emit AlarmsStateChanged event [ep=%d]", ep);
+ return false;
+ }
+
+ ChipLogProgress(Zcl, "Emit AlarmsStateChanged event [ep=%d]", ep);
+ return true;
+}
+
+static CHIP_ERROR emitSensorFaultEvent(EndpointId ep, BitMask fault)
+{
+ BooleanStateConfiguration::Events::SensorFault::Type event;
+ EventNumber eventNumber;
+
+ event.sensorFault = fault;
+
+ CHIP_ERROR error = LogEvent(event, ep, eventNumber);
+
+ if (CHIP_NO_ERROR != error)
+ {
+ ChipLogError(Zcl, "Unable to emit SensorFault event [ep=%d]", ep);
+ return error;
+ }
+
+ ChipLogProgress(Zcl, "Emit SensorFault event [ep=%d]", ep);
+ return CHIP_NO_ERROR;
+}
+
+static CHIP_ERROR StoreCurrentSensitivityLevel(EndpointId ep, uint8_t level)
+{
+ uint8_t supportedSensLevel;
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == SupportedSensitivityLevels::Get(ep, &supportedSensLevel),
+ CHIP_IM_GLOBAL_STATUS(Failure));
+ VerifyOrReturnError(supportedSensLevel >= kMinSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(ConstraintError));
+ VerifyOrReturnError(supportedSensLevel <= kMaxSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(ConstraintError));
+ VerifyOrReturnError(level < supportedSensLevel, CHIP_IM_GLOBAL_STATUS(ConstraintError));
+
+ ReturnErrorOnFailure(GetSafeAttributePersistenceProvider()->WriteScalarValue(
+ ConcreteAttributePath(ep, BooleanStateConfiguration::Id, CurrentSensitivityLevel::Id), level));
+
+ return CHIP_NO_ERROR;
+}
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace BooleanStateConfiguration {
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
+{
+ uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, BooleanStateConfiguration::Id,
+ EMBER_AF_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT);
+ // if endpoint is found
+ if (ep < kBooleanStateConfigurationDelegateTableSize)
+ {
+ gDelegateTable[ep] = delegate;
+ }
+}
+
+Delegate * GetDefaultDelegate(EndpointId endpoint)
+{
+ return GetDelegate(endpoint);
+}
+
+CHIP_ERROR SetAlarmsActive(EndpointId ep, BitMask alarms)
+{
+ VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
+ HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
+ CHIP_IM_GLOBAL_STATUS(Failure));
+
+ BitMask alarmsEnabled;
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsEnabled::Get(ep, &alarmsEnabled),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+ VerifyOrReturnError(alarmsEnabled.HasAll(alarms), CHIP_IM_GLOBAL_STATUS(Failure));
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Set(ep, alarms), CHIP_IM_GLOBAL_STATUS(Failure));
+ emitAlarmsStateChangedEvent(ep);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR SetAllEnabledAlarmsActive(EndpointId ep)
+{
+ VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
+ HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
+ CHIP_IM_GLOBAL_STATUS(Failure));
+
+ BitMask alarmsEnabled;
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsEnabled::Get(ep, &alarmsEnabled),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Set(ep, alarmsEnabled), CHIP_IM_GLOBAL_STATUS(Failure));
+ emitAlarmsStateChangedEvent(ep);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ClearAllAlarms(EndpointId ep)
+{
+ BitMask alarmsActive, alarmsSuppressed;
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Get(ep, &alarmsActive),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Get(ep, &alarmsSuppressed),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+
+ if (alarmsActive.HasAny() || alarmsSuppressed.HasAny())
+ {
+ alarmsActive.ClearAll();
+ alarmsSuppressed.ClearAll();
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Set(ep, alarmsActive),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Set(ep, alarmsSuppressed),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+ emitAlarmsStateChangedEvent(ep);
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR SuppressAlarms(EndpointId ep, BitMask alarm)
+{
+ CHIP_ERROR attribute_error = CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
+
+ VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kAlarmSuppress),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedCommand));
+ VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
+ HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
+ CHIP_IM_GLOBAL_STATUS(UnsupportedCommand));
+
+ BitMask alarmsActive, alarmsSuppressed, alarmsSupported;
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsSupported::Get(ep, &alarmsSupported), attribute_error);
+ VerifyOrReturnError(alarmsSupported.HasAll(alarm), CHIP_IM_GLOBAL_STATUS(ConstraintError));
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Get(ep, &alarmsActive), attribute_error);
+ VerifyOrReturnError(alarmsActive.HasAll(alarm), CHIP_IM_GLOBAL_STATUS(InvalidInState));
+
+ Delegate * delegate = GetDelegate(ep);
+ if (!isDelegateNull(delegate))
+ {
+ delegate->HandleSuppressAlarm(alarm);
+ }
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Get(ep, &alarmsSuppressed), attribute_error);
+ alarmsSuppressed.Set(alarm);
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Set(ep, alarmsSuppressed), attribute_error);
+
+ emitAlarmsStateChangedEvent(ep);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR SetCurrentSensitivityLevel(EndpointId ep, uint8_t level)
+{
+ return StoreCurrentSensitivityLevel(ep, level);
+}
+
+CHIP_ERROR EmitSensorFault(EndpointId ep, BitMask fault)
+{
+ ReturnErrorOnFailure(emitSensorFaultEvent(ep, fault));
+ return CHIP_NO_ERROR;
+}
+
+} // namespace BooleanStateConfiguration
+} // namespace Clusters
+} // namespace app
+} // namespace chip
+
+bool emberAfBooleanStateConfigurationClusterSuppressAlarmCallback(
+ CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
+ const BooleanStateConfiguration::Commands::SuppressAlarm::DecodableType & commandData)
+{
+ const auto & alarms = commandData.alarmsToSuppress;
+ CHIP_ERROR err = BooleanStateConfiguration::SuppressAlarms(commandPath.mEndpointId, alarms);
+ if (err == CHIP_NO_ERROR)
+ {
+ commandObj->AddStatus(commandPath, Status::Success);
+ }
+ else if (err == CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute))
+ {
+ commandObj->AddStatus(commandPath, Status::Failure);
+ }
+ else
+ {
+ commandObj->AddStatus(commandPath, StatusIB(err).mStatus);
+ }
+
+ return true;
+}
+
+bool emberAfBooleanStateConfigurationClusterEnableDisableAlarmCallback(
+ CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
+ const BooleanStateConfiguration::Commands::EnableDisableAlarm::DecodableType & commandData)
+{
+ const auto & alarms = commandData.alarmsToEnableDisable;
+ const auto & ep = commandPath.mEndpointId;
+ Optional status = Optional::Missing();
+
+ if (!HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) &&
+ !HasFeature(ep, BooleanStateConfiguration::Feature::kAudible))
+ {
+ commandObj->AddStatus(commandPath, Status::UnsupportedCommand);
+ return true;
+ }
+
+ BitMask alarmsActive, alarmsSuppressed, alarmsSupported, alarmsToDisable;
+ Delegate * delegate = GetDelegate(ep);
+ bool emit = false;
+ uint8_t rawAlarm = static_cast(~alarms.Raw() & 0x03); // 0x03 is the current max bitmap
+ alarmsToDisable = BitMask(rawAlarm);
+
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsSupported::Get(ep, &alarmsSupported), status.Emplace(Status::Failure));
+ VerifyOrExit(alarmsSupported.HasAll(alarms), status.Emplace(Status::ConstraintError));
+
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsEnabled::Set(ep, alarms), status.Emplace(Status::Failure));
+
+ if (!isDelegateNull(delegate))
+ {
+ delegate->HandleEnableDisableAlarms(alarms);
+ }
+
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Get(ep, &alarmsActive), status.Emplace(Status::Failure));
+ if (alarmsActive.HasAny(alarmsToDisable))
+ {
+ alarmsActive.Clear(alarmsToDisable);
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsActive::Set(ep, alarmsActive), status.Emplace(Status::Failure));
+ emit = true;
+ }
+
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Get(ep, &alarmsSuppressed), status.Emplace(Status::Failure));
+ if (alarmsSuppressed.HasAny(alarmsToDisable))
+ {
+ alarmsSuppressed.Clear(alarmsToDisable);
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == AlarmsSuppressed::Set(ep, alarmsSuppressed), status.Emplace(Status::Failure));
+ emit = true;
+ }
+
+ if (emit)
+ {
+ emitAlarmsStateChangedEvent(ep);
+ }
+
+exit:
+ if (status.HasValue())
+ {
+ commandObj->AddStatus(commandPath, status.Value());
+ }
+ else
+ {
+ commandObj->AddStatus(commandPath, Status::Success);
+ }
+
+ return true;
+}
+
+void MatterBooleanStateConfigurationPluginServerInitCallback()
+{
+ registerAttributeAccessOverride(&gAttrAccess);
+}
diff --git a/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.h b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.h
new file mode 100644
index 00000000000000..21813208c77249
--- /dev/null
+++ b/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-server.h
@@ -0,0 +1,56 @@
+/**
+ *
+ * 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.
+ */
+
+/**
+ * @file API declarations for boolean state configuration cluster.
+ */
+
+#pragma once
+
+#include "boolean-state-configuration-delegate.h"
+
+#include
+#include
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace BooleanStateConfiguration {
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate);
+Delegate * GetDefaultDelegate(EndpointId endpoint);
+
+CHIP_ERROR SetAlarmsActive(EndpointId ep, chip::BitMask alarms);
+CHIP_ERROR SetAllEnabledAlarmsActive(EndpointId ep);
+CHIP_ERROR ClearAllAlarms(EndpointId ep);
+CHIP_ERROR SuppressAlarms(EndpointId ep, chip::BitMask alarms);
+CHIP_ERROR SetCurrentSensitivityLevel(EndpointId ep, uint8_t level);
+CHIP_ERROR EmitSensorFault(EndpointId ep, chip::BitMask fault);
+
+inline bool HasFeature(EndpointId ep, Feature feature)
+{
+ uint32_t map;
+ bool success = (Attributes::FeatureMap::Get(ep, &map) == EMBER_ZCL_STATUS_SUCCESS);
+ return success ? (map & to_underlying(feature)) : false;
+}
+
+} // namespace BooleanStateConfiguration
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp
index 52990915d492dd..87edf85f5c06c9 100644
--- a/src/app/clusters/network-commissioning/network-commissioning.cpp
+++ b/src/app/clusters/network-commissioning/network-commissioning.cpp
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2021 Project CHIP Authors
+ * Copyright (c) 2021-2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include
+
#include "network-commissioning.h"
#include
@@ -54,8 +56,7 @@ namespace {
// For WiFi and Thread scan results, each item will cost ~60 bytes in TLV, thus 15 is a safe upper bound of scan results.
constexpr size_t kMaxNetworksInScanResponse = 15;
-// The maximum number of Wi-Fi bands a device can support.
-constexpr size_t kMaxWiFiBands = 6;
+constexpr uint16_t kCurrentClusterRevision = 2;
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
constexpr size_t kPossessionNonceSize = 32;
@@ -269,22 +270,31 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu
case Attributes::FeatureMap::Id:
return aEncoder.Encode(mFeatureFlags);
+ case Attributes::ClusterRevision::Id:
+ return aEncoder.Encode(kCurrentClusterRevision);
+
case Attributes::SupportedWiFiBands::Id:
- VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiNetworkInterface), CHIP_NO_ERROR);
- VerifyOrReturnError(mpDriver.Valid(), CHIP_NO_ERROR);
+#if (!CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION && !CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP)
+ return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
+#else
+ VerifyOrReturnError(mFeatureFlags.Has(Feature::kWiFiNetworkInterface), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
- return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR {
- WiFiBand bandsBuffer[kMaxWiFiBands];
- Span bands(bandsBuffer);
- ReturnErrorOnFailure(mpDriver.Get()->GetSupportedWiFiBands(bands));
+ return aEncoder.EncodeList([this](const auto & encoder) {
+ uint32_t bands = mpDriver.Get()->GetSupportedWiFiBandsMask();
- for (WiFiBand band : bands)
+ // Extract every band from the bitmap of supported bands, starting positionally on the right.
+ for (uint32_t band_bit_pos = 0; band_bit_pos < std::numeric_limits::digits; ++band_bit_pos)
{
- ReturnErrorOnFailure(encoder.Encode(band));
+ uint32_t band_mask = static_cast(1UL << band_bit_pos);
+ if ((bands & band_mask) != 0)
+ {
+ ReturnErrorOnFailure(encoder.Encode(static_cast(band_bit_pos)));
+ }
}
-
return CHIP_NO_ERROR;
});
+#endif
+ break;
case Attributes::SupportedThreadFeatures::Id:
VerifyOrReturnError(mFeatureFlags.Has(Feature::kThreadNetworkInterface), CHIP_NO_ERROR);
@@ -310,7 +320,7 @@ CHIP_ERROR Instance::Write(const ConcreteDataAttributePath & aPath, AttributeVal
ReturnErrorOnFailure(aDecoder.Decode(value));
return mpBaseDriver->SetEnabled(value);
default:
- return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+ return CHIP_IM_GLOBAL_STATUS(InvalidAction);
}
}
diff --git a/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.cpp b/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.cpp
index 82164afc2427b2..3f97c57a7171fe 100644
--- a/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.cpp
+++ b/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.cpp
@@ -73,3 +73,8 @@ CHIP_ERROR DefaultTimeSyncDelegate::UpdateTimeUsingNTPFallback(const CharSpan &
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}
+
+void DefaultTimeSyncDelegate::UTCTimeChanged(uint64_t time)
+{
+ // placeholder implementation
+}
diff --git a/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.h b/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.h
index a954f51954cb3c..826f1d22d82707 100644
--- a/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.h
+++ b/src/app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.h
@@ -36,6 +36,7 @@ class DefaultTimeSyncDelegate : public Delegate
CHIP_ERROR UpdateTimeFromPlatformSource(chip::Callback::Callback * callback) override;
CHIP_ERROR UpdateTimeUsingNTPFallback(const CharSpan & fallbackNTP,
chip::Callback::Callback * callback) override;
+ void UTCTimeChanged(uint64_t time) override;
};
} // namespace TimeSynchronization
diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-delegate.h b/src/app/clusters/time-synchronization-server/time-synchronization-delegate.h
index a80b3207aff992..1f424e31798c44 100644
--- a/src/app/clusters/time-synchronization-server/time-synchronization-delegate.h
+++ b/src/app/clusters/time-synchronization-server/time-synchronization-delegate.h
@@ -105,6 +105,11 @@ class Delegate
virtual CHIP_ERROR UpdateTimeUsingNTPFallback(const CharSpan & fallbackNTP,
chip::Callback::Callback * callback) = 0;
+ /**
+ * @brief Signals application that UTCTime has changed through the timesync cluster.
+ */
+ virtual void UTCTimeChanged(uint64_t time) = 0;
+
virtual ~Delegate() = default;
private:
diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp b/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp
index 8b285c4a1ad402..fae9565ef21599 100644
--- a/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp
+++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.cpp
@@ -776,6 +776,7 @@ CHIP_ERROR TimeSynchronizationServer::SetUTCTime(EndpointId ep, uint64_t utcTime
ChipLogError(Zcl, "Error setting UTC time on the device");
return err;
}
+ GetDelegate()->UTCTimeChanged(utcTime);
mGranularity = granularity;
EmberAfStatus status = TimeSource::Set(ep, source);
if (!(status == EMBER_ZCL_STATUS_SUCCESS || status == EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE))
diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.h b/src/app/clusters/time-synchronization-server/time-synchronization-server.h
index 200714d3cf7def..5eee8e52b000b8 100644
--- a/src/app/clusters/time-synchronization-server/time-synchronization-server.h
+++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.h
@@ -69,6 +69,9 @@ enum class TimeSyncEventFlag : uint8_t
kMissingTTSource = 16,
};
+void SetDefaultDelegate(Delegate * delegate);
+Delegate * GetDefaultDelegate();
+
class TimeSynchronizationServer : public FabricTable::Delegate
#if TIME_SYNC_ENABLE_TSC_FEATURE
,
diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-delegate.h b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-delegate.h
new file mode 100644
index 00000000000000..b0d3e5fd14a90d
--- /dev/null
+++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-delegate.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace ValveConfigurationAndControl {
+
+/** @brief
+ * Defines methods for implementing application-specific logic for the Valve Configuration and Control Cluster.
+ */
+class Delegate
+{
+public:
+ Delegate(){};
+
+ // shall return current level if supported, otherwise null
+ virtual DataModel::Nullable HandleOpenValve(DataModel::Nullable level) = 0;
+ virtual CHIP_ERROR HandleCloseValve() = 0;
+ virtual void HandleRemainingDurationTick(uint32_t duration) = 0;
+
+ virtual ~Delegate() = default;
+};
+
+} // namespace ValveConfigurationAndControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp
new file mode 100644
index 00000000000000..0f6968f98e5826
--- /dev/null
+++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.cpp
@@ -0,0 +1,521 @@
+/**
+ *
+ * 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.
+ *
+ */
+
+#include "valve-configuration-and-control-server.h"
+
+#include
+#ifdef ZCL_USING_TIME_SYNCHRONIZATION_CLUSTER_SERVER
+// Need the `nogncheck` because it's inter-cluster dependency and this
+// breaks GN deps checks since that doesn't know how to deal with #ifdef'd includes :(.
+#include "app/clusters/time-synchronization-server/time-synchronization-server.h" // nogncheck
+
+#endif // ZCL_USING_TIME_SYNCHRONIZATION_CLUSTER_SERVER
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::ValveConfigurationAndControl::Attributes;
+using chip::app::Clusters::ValveConfigurationAndControl::Delegate;
+using chip::Protocols::InteractionModel::Status;
+
+static constexpr size_t kValveConfigurationAndControlDelegateTableSize =
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
+
+static_assert(kValveConfigurationAndControlDelegateTableSize <= kEmberInvalidEndpointIndex,
+ "ValveConfigurationAndControl Delegate table size error");
+
+namespace {
+
+struct RemainingDurationTable
+{
+ EndpointId endpoint;
+ DataModel::Nullable remainingDuration;
+};
+
+RemainingDurationTable gRemainingDuration[kValveConfigurationAndControlDelegateTableSize];
+Delegate * gDelegateTable[kValveConfigurationAndControlDelegateTableSize] = { nullptr };
+
+bool GetRemainingDuration(EndpointId endpoint, DataModel::Nullable & duration)
+{
+ uint16_t epIdx = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ VerifyOrReturnValue(epIdx < kValveConfigurationAndControlDelegateTableSize, false);
+ duration = gRemainingDuration[epIdx].remainingDuration;
+ return true;
+}
+
+void SetRemainingDuration(EndpointId endpoint, DataModel::Nullable duration)
+{
+ uint16_t epIdx = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ if (epIdx < kValveConfigurationAndControlDelegateTableSize)
+ {
+ gRemainingDuration[epIdx].endpoint = endpoint;
+ gRemainingDuration[epIdx].remainingDuration = duration;
+ }
+}
+
+void SetRemainingDurationNull(EndpointId endpoint)
+{
+ uint16_t epIdx = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ if (epIdx < kValveConfigurationAndControlDelegateTableSize)
+ {
+ if (!gRemainingDuration[epIdx].remainingDuration.IsNull())
+ {
+ MatterReportingAttributeChangeCallback(endpoint, ValveConfigurationAndControl::Id, RemainingDuration::Id);
+ }
+ gRemainingDuration[epIdx].remainingDuration.SetNull();
+ }
+}
+
+RemainingDurationTable * GetRemainingDurationItem(EndpointId endpoint)
+{
+ uint16_t epIdx = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ if (epIdx < kValveConfigurationAndControlDelegateTableSize)
+ {
+ return &gRemainingDuration[epIdx];
+ }
+ return nullptr;
+}
+
+Delegate * GetDelegate(EndpointId endpoint)
+{
+ uint16_t epIdx = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ return (epIdx >= kValveConfigurationAndControlDelegateTableSize ? nullptr : gDelegateTable[epIdx]);
+}
+
+bool isDelegateNull(Delegate * delegate)
+{
+ if (delegate == nullptr)
+ {
+ return true;
+ }
+ return false;
+}
+
+class ValveConfigAndControlAttrAccess : public AttributeAccessInterface
+{
+public:
+ ValveConfigAndControlAttrAccess() : AttributeAccessInterface(Optional::Missing(), ValveConfigurationAndControl::Id)
+ {}
+
+ CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
+
+private:
+ CHIP_ERROR ReadRemainingDuration(EndpointId endpoint, AttributeValueEncoder & aEncoder);
+};
+
+ValveConfigAndControlAttrAccess gAttrAccess;
+
+CHIP_ERROR ValveConfigAndControlAttrAccess::ReadRemainingDuration(EndpointId endpoint, AttributeValueEncoder & aEncoder)
+{
+ DataModel::Nullable rDuration;
+ VerifyOrReturnError(GetRemainingDuration(endpoint, rDuration), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
+
+ return aEncoder.Encode(rDuration);
+}
+
+CHIP_ERROR ValveConfigAndControlAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ if (aPath.mClusterId != ValveConfigurationAndControl::Id)
+ {
+ return CHIP_ERROR_INVALID_PATH_LIST;
+ }
+
+ switch (aPath.mAttributeId)
+ {
+ case RemainingDuration::Id: {
+ return ReadRemainingDuration(aPath.mEndpointId, aEncoder);
+ }
+ default: {
+ break;
+ }
+ }
+
+ return err;
+}
+} // namespace
+
+static void startRemainingDurationTick(EndpointId ep);
+
+static bool emitValveStateChangedEvent(EndpointId ep, ValveConfigurationAndControl::ValveStateEnum state)
+{
+ ValveConfigurationAndControl::Events::ValveStateChanged::Type event;
+ EventNumber eventNumber;
+ event.valveState = state;
+
+ CHIP_ERROR error = LogEvent(event, ep, eventNumber);
+
+ if (CHIP_NO_ERROR != error)
+ {
+ ChipLogError(Zcl, "Unable to emit ValveStateChanged event [ep=%d]", ep);
+ return false;
+ }
+
+ ChipLogProgress(Zcl, "Emit ValveStateChanged event [ep=%d] %d", ep, to_underlying(state));
+ return true;
+}
+
+static CHIP_ERROR emitValveFaultEvent(EndpointId ep, BitMask fault)
+{
+ ValveConfigurationAndControl::Events::ValveFault::Type event;
+ EventNumber eventNumber;
+ event.valveFault = fault;
+
+ CHIP_ERROR error = LogEvent(event, ep, eventNumber);
+
+ if (CHIP_NO_ERROR != error)
+ {
+ ChipLogError(Zcl, "Unable to emit ValveFault event [ep=%d]", ep);
+ return error;
+ }
+
+ ChipLogProgress(Zcl, "Emit ValveFault event [ep=%d]", ep);
+ return CHIP_NO_ERROR;
+}
+
+static void onValveConfigurationAndControlTick(System::Layer * systemLayer, void * data)
+{
+ RemainingDurationTable * item = reinterpret_cast(data);
+ VerifyOrReturn(item != nullptr, ChipLogError(Zcl, "Error retrieving RemainingDuration item"));
+
+ DataModel::Nullable rDuration = item->remainingDuration;
+ VerifyOrReturn(!rDuration.IsNull());
+
+ EndpointId ep = item->endpoint;
+
+ if (rDuration.Value() > 0)
+ {
+ SetRemainingDuration(ep, DataModel::MakeNullable(--rDuration.Value()));
+ startRemainingDurationTick(ep);
+ }
+ else
+ {
+ SetRemainingDurationNull(ep);
+ }
+}
+
+void startRemainingDurationTick(EndpointId ep)
+{
+ RemainingDurationTable * item = GetRemainingDurationItem(ep);
+ VerifyOrReturn(item != nullptr, ChipLogError(Zcl, "Error retrieving RemainingDuration item"));
+
+ DataModel::Nullable rDuration = item->remainingDuration;
+ VerifyOrReturn(!rDuration.IsNull());
+ Delegate * delegate = GetDelegate(item->endpoint);
+ VerifyOrReturn(!isDelegateNull(delegate));
+
+ delegate->HandleRemainingDurationTick(rDuration.Value());
+ if (rDuration.Value() > 0)
+ {
+ (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onValveConfigurationAndControlTick, item);
+ }
+ else
+ {
+ ValveConfigurationAndControl::CloseValve(ep);
+ (void) DeviceLayer::SystemLayer().CancelTimer(onValveConfigurationAndControlTick, item);
+ }
+}
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace ValveConfigurationAndControl {
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
+{
+ uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, ValveConfigurationAndControl::Id,
+ EMBER_AF_VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
+ // if endpoint is found
+ if (ep < kValveConfigurationAndControlDelegateTableSize)
+ {
+ gDelegateTable[ep] = delegate;
+ }
+}
+
+Delegate * GetDefaultDelegate(EndpointId endpoint)
+{
+ return GetDelegate(endpoint);
+}
+
+CHIP_ERROR CloseValve(EndpointId ep)
+{
+ Delegate * delegate = GetDelegate(ep);
+ DataModel::Nullable rDuration;
+ CHIP_ERROR attribute_error = CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == TargetState::Set(ep, ValveConfigurationAndControl::ValveStateEnum::kClosed),
+ attribute_error);
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS ==
+ CurrentState::Set(ep, ValveConfigurationAndControl::ValveStateEnum::kTransitioning),
+ attribute_error);
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == OpenDuration::SetNull(ep), attribute_error);
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel))
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == TargetLevel::Set(ep, 0), attribute_error);
+ }
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kTimeSync))
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AutoCloseTime::SetNull(ep), attribute_error);
+ }
+ SetRemainingDurationNull(ep);
+ RemainingDurationTable * item = GetRemainingDurationItem(ep);
+ (void) DeviceLayer::SystemLayer().CancelTimer(onValveConfigurationAndControlTick, item);
+
+ emitValveStateChangedEvent(ep, ValveConfigurationAndControl::ValveStateEnum::kTransitioning);
+ if (!isDelegateNull(delegate))
+ {
+ delegate->HandleCloseValve();
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR SetValveLevel(EndpointId ep, DataModel::Nullable level, DataModel::Nullable openDuration)
+{
+ Delegate * delegate = GetDelegate(ep);
+ Optional status = Optional::Missing();
+ DataModel::Nullable openLevel;
+ DataModel::Nullable autoCloseTime;
+ CHIP_ERROR attribute_error = CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
+
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kTimeSync))
+ {
+#ifdef ZCL_USING_TIME_SYNCHRONIZATION_CLUSTER_SERVER
+ if (!openDuration.IsNull() &&
+ TimeSynchronization::TimeSynchronizationServer::Instance().GetGranularity() !=
+ TimeSynchronization::GranularityEnum::kNoTimeGranularity)
+ {
+ System::Clock::Microseconds64 utcTime;
+ uint64_t chipEpochTime;
+ ReturnErrorOnFailure(System::SystemClock().GetClock_RealTime(utcTime));
+ VerifyOrReturnError(UnixEpochToChipEpochMicros(utcTime.count(), chipEpochTime), CHIP_ERROR_INVALID_TIME);
+
+ uint64_t time = openDuration.Value() * chip::kMicrosecondsPerSecond;
+ autoCloseTime.SetNonNull(chipEpochTime + time);
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AutoCloseTime::Set(ep, autoCloseTime), attribute_error);
+ }
+ else
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == AutoCloseTime::SetNull(ep), attribute_error);
+ }
+#else
+ return CHIP_FAILURE;
+#endif // ZCL_USING_TIME_SYNCHRONIZATION_CLUSTER_SERVER
+ }
+
+ // level can only be null if LVL feature is not supported
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel) && !level.IsNull())
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == TargetLevel::Set(ep, level), attribute_error);
+ }
+
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == OpenDuration::Set(ep, openDuration), attribute_error);
+
+ SetRemainingDuration(ep, openDuration);
+ // Trigger report for remainingduration
+ MatterReportingAttributeChangeCallback(ep, ValveConfigurationAndControl::Id, RemainingDuration::Id);
+ // set targetstate to open
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == TargetState::Set(ep, ValveConfigurationAndControl::ValveStateEnum::kOpen),
+ attribute_error);
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS ==
+ CurrentState::Set(ep, ValveConfigurationAndControl::ValveStateEnum::kTransitioning),
+ attribute_error);
+
+ // start movement towards target
+ emitValveStateChangedEvent(ep, ValveConfigurationAndControl::ValveStateEnum::kTransitioning);
+ if (!isDelegateNull(delegate))
+ {
+ DataModel::Nullable cLevel = delegate->HandleOpenValve(level);
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel))
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == CurrentLevel::Set(ep, cLevel), attribute_error);
+ }
+ }
+ // start countdown
+ startRemainingDurationTick(ep);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR UpdateCurrentLevel(EndpointId ep, Percent currentLevel)
+{
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel))
+ {
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == CurrentLevel::Set(ep, currentLevel),
+ CHIP_IM_GLOBAL_STATUS(ConstraintError));
+ return CHIP_NO_ERROR;
+ }
+ return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
+}
+
+CHIP_ERROR UpdateCurrentState(EndpointId ep, ValveConfigurationAndControl::ValveStateEnum currentState)
+{
+ VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == CurrentState::Set(ep, currentState), CHIP_IM_GLOBAL_STATUS(ConstraintError));
+ emitValveStateChangedEvent(ep, currentState);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR EmitValveFault(EndpointId ep, BitMask fault)
+{
+ ReturnErrorOnFailure(emitValveFaultEvent(ep, fault));
+ return CHIP_NO_ERROR;
+}
+
+void UpdateAutoCloseTime(uint64_t time)
+{
+ for (auto & t : gRemainingDuration)
+ {
+ const auto & d = t.remainingDuration;
+ if (!d.IsNull() && d.Value() != 0)
+ {
+ uint64_t closingTime = d.Value() * chip::kMicrosecondsPerSecond + time;
+ if (EMBER_ZCL_STATUS_SUCCESS != AutoCloseTime::Set(t.endpoint, closingTime))
+ {
+ ChipLogError(Zcl, "Unable to update AutoCloseTime");
+ }
+ }
+ }
+}
+} // namespace ValveConfigurationAndControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
+
+bool emberAfValveConfigurationAndControlClusterOpenCallback(
+ CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
+ const ValveConfigurationAndControl::Commands::Open::DecodableType & commandData)
+{
+ const auto & openDuration = commandData.openDuration;
+ const auto & targetLevel = commandData.targetLevel;
+ const auto & ep = commandPath.mEndpointId;
+ DataModel::Nullable level;
+ DataModel::Nullable duration;
+ BitMask fault(0);
+ Optional status = Optional::Missing();
+
+ // if fault is registered return FailureDueToFault
+ if (EMBER_ZCL_STATUS_SUCCESS == ValveFault::Get(ep, &fault) && fault.HasAny())
+ {
+ commandObj->AddClusterSpecificFailure(commandPath,
+ to_underlying(ValveConfigurationAndControl::StatusCodeEnum::kFailureDueToFault));
+ return true;
+ }
+
+ // verify min 1 requirement
+ VerifyOrExit(targetLevel.HasValue() ? targetLevel.Value() > 0 : true, status.Emplace(Status::ConstraintError));
+ if (openDuration.HasValue())
+ {
+ bool validOpenDuration = openDuration.Value().IsNull() ? true : openDuration.Value().Value() > 0;
+ // verify min 1 requirement
+ VerifyOrExit(validOpenDuration, status.Emplace(Status::ConstraintError));
+
+ duration = openDuration.Value();
+ }
+ else
+ {
+ VerifyOrExit(EMBER_ZCL_STATUS_SUCCESS == DefaultOpenDuration::Get(ep, duration), status.Emplace(Status::Failure));
+ }
+
+ if (HasFeature(ep, ValveConfigurationAndControl::Feature::kLevel))
+ {
+ Percent defOpenLevel;
+ if (targetLevel.HasValue())
+ {
+ level.SetNonNull(targetLevel.Value());
+ }
+ else if (EMBER_ZCL_STATUS_SUCCESS == DefaultOpenLevel::Get(ep, &defOpenLevel))
+ {
+ level.SetNonNull(defOpenLevel);
+ }
+ else
+ {
+ level.SetNonNull(Percent(100));
+ }
+ }
+
+ VerifyOrExit(CHIP_NO_ERROR == ValveConfigurationAndControl::SetValveLevel(ep, level, duration),
+ status.Emplace(Status::Failure));
+
+exit:
+ if (status.HasValue())
+ {
+ BitMask gFault(
+ ValveConfigurationAndControl::ValveFaultBitmap::kGeneralFault);
+ emitValveFaultEvent(ep, gFault);
+ commandObj->AddStatus(commandPath, status.Value());
+ }
+ else
+ {
+ commandObj->AddStatus(commandPath, Status::Success);
+ }
+
+ return true;
+}
+
+bool emberAfValveConfigurationAndControlClusterCloseCallback(
+ CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
+ const ValveConfigurationAndControl::Commands::Close::DecodableType & commandData)
+{
+ const auto & ep = commandPath.mEndpointId;
+ BitMask fault(0);
+
+ // if fault is registered return FailureDueToFault
+ if (EMBER_ZCL_STATUS_SUCCESS == ValveFault::Get(ep, &fault) && fault.HasAny())
+ {
+ commandObj->AddClusterSpecificFailure(commandPath,
+ to_underlying(ValveConfigurationAndControl::StatusCodeEnum::kFailureDueToFault));
+ return true;
+ }
+
+ if (CHIP_NO_ERROR == ValveConfigurationAndControl::CloseValve(ep))
+ {
+ commandObj->AddStatus(commandPath, Status::Success);
+ }
+ else
+ {
+ commandObj->AddStatus(commandPath, Status::Failure);
+ }
+
+ return true;
+}
+
+void MatterValveConfigurationAndControlPluginServerInitCallback()
+{
+ registerAttributeAccessOverride(&gAttrAccess);
+}
diff --git a/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.h b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.h
new file mode 100644
index 00000000000000..6f46e8cc6356e4
--- /dev/null
+++ b/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-server.h
@@ -0,0 +1,59 @@
+/**
+ *
+ * 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.
+ */
+
+/**
+ * @file API declarations for valve configuration and control cluster.
+ */
+
+#pragma once
+
+#include "valve-configuration-and-control-delegate.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace ValveConfigurationAndControl {
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate);
+Delegate * GetDefaultDelegate(EndpointId endpoint);
+
+CHIP_ERROR CloseValve(chip::EndpointId ep);
+CHIP_ERROR SetValveLevel(chip::EndpointId ep, chip::Percent level, DataModel::Nullable openDuration);
+CHIP_ERROR UpdateCurrentLevel(chip::EndpointId ep, chip::Percent currentLevel);
+CHIP_ERROR UpdateCurrentState(chip::EndpointId ep, ValveConfigurationAndControl::ValveStateEnum currentState);
+CHIP_ERROR EmitValveFault(chip::EndpointId ep, chip::BitMask fault);
+void UpdateAutoCloseTime(uint64_t time);
+
+inline bool HasFeature(EndpointId ep, Feature feature)
+{
+ uint32_t map;
+ bool success = (Attributes::FeatureMap::Get(ep, &map) == EMBER_ZCL_STATUS_SUCCESS);
+ return success ? (map & to_underlying(feature)) : false;
+}
+
+} // namespace ValveConfigurationAndControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn
index 1c48851aa07b95..d0f9a73178ccb0 100644
--- a/src/app/tests/BUILD.gn
+++ b/src/app/tests/BUILD.gn
@@ -18,6 +18,7 @@ import("//build_overrides/nlunit_test.gni")
import("${chip_root}/build/chip/chip_test_suite.gni")
import("${chip_root}/src/app/icd/icd.gni")
+import("${chip_root}/src/crypto/crypto.gni")
import("${chip_root}/src/platform/device.gni")
static_library("helpers") {
@@ -162,7 +163,11 @@ chip_test_suite_using_nltest("tests") {
}
test_sources += [ "TestAclAttribute.cpp" ]
- test_sources += [ "TestDefaultICDClientStorage.cpp" ]
+
+ # DefaultICDClientStorage assumes that raw AES key is used by the application
+ if (chip_crypto != "psa") {
+ test_sources += [ "TestDefaultICDClientStorage.cpp" ]
+ }
#
# On NRF platforms, the allocation of a large number of pbufs in this test
diff --git a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml b/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml
index 0422d108ac71ff..b28b4fbb548f2a 100644
--- a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml
+++ b/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml
@@ -37,7 +37,7 @@ tests:
command: "readAttribute"
attribute: "ClusterRevision"
response:
- value: 1
+ value: 2
constraints:
type: int16u
diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp
index 98c475d608864e..e7fa8c2b2374d8 100644
--- a/src/app/util/util.cpp
+++ b/src/app/util/util.cpp
@@ -159,8 +159,6 @@ void MatterOperationalStatePluginServerInitCallback() {}
void MatterRvcOperationalStatePluginServerInitCallback() {}
void MatterOvenModePluginServerInitCallback() {}
void MatterDishwasherAlarmPluginServerInitCallback() {}
-void MatterBooleanStateConfigurationPluginServerInitCallback() {}
-void MatterValveConfigurationAndControlPluginServerInitCallback() {}
void MatterMicrowaveOvenModePluginServerInitCallback() {}
// ****************************************
// Print out information about each cluster
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 634f66606f6a60..ecbcea088f51b5 100644
--- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json
+++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json
@@ -559,7 +559,9 @@
"CumulativeEnergyExported",
"PeriodicEnergyImported",
"PeriodicEnergyExported"
- ]
+ ],
+ "Valve Configuration and Control": ["RemainingDuration"],
+ "Boolean State Configuration": ["CurrentSensitivityLevel"]
},
"defaultReportingPolicy": "mandatory",
"ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"],
diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json
index a0556e6da7ebb2..80b9ff7bbd84f9 100644
--- a/src/app/zap-templates/zcl/zcl.json
+++ b/src/app/zap-templates/zcl/zcl.json
@@ -557,7 +557,9 @@
"CumulativeEnergyExported",
"PeriodicEnergyImported",
"PeriodicEnergyExported"
- ]
+ ],
+ "Valve Configuration and Control": ["RemainingDuration"],
+ "Boolean State Configuration": ["CurrentSensitivityLevel"]
},
"defaultReportingPolicy": "mandatory",
"ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"],
diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json
index a7f1c8e58dca6f..4d38466edb17aa 100644
--- a/src/app/zap_cluster_list.json
+++ b/src/app/zap_cluster_list.json
@@ -148,7 +148,9 @@
"BINARY_INPUT_BASIC_CLUSTER": [],
"BINDING_CLUSTER": ["bindings"],
"BOOLEAN_STATE_CLUSTER": [],
- "BOOLEAN_STATE_CONFIGURATION_CLUSTER": [],
+ "BOOLEAN_STATE_CONFIGURATION_CLUSTER": [
+ "boolean-state-configuration-server"
+ ],
"BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER": [
"bridged-device-basic-information-server"
],
@@ -285,7 +287,9 @@
"UNIT_LOCALIZATION_CLUSTER": [],
"UNIT_TESTING_CLUSTER": ["test-cluster-server"],
"USER_LABEL_CLUSTER": ["user-label-server"],
- "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER": [],
+ "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER": [
+ "valve-configuration-and-control-server"
+ ],
"WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"],
"LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"],
"LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"],
diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py
index 25691bb826cf55..96a66f5706f174 100644
--- a/src/controller/python/chip/clusters/Attribute.py
+++ b/src/controller/python/chip/clusters/Attribute.py
@@ -24,7 +24,7 @@
import logging
import sys
from asyncio.futures import Future
-from ctypes import CFUNCTYPE, c_size_t, c_uint8, c_uint16, c_uint32, c_uint64, c_void_p, py_object
+from ctypes import CFUNCTYPE, POINTER, c_size_t, c_uint8, c_uint16, c_uint32, c_uint64, c_void_p, cast, py_object
from dataclasses import dataclass, field
from enum import Enum, unique
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
@@ -34,6 +34,7 @@
import chip.interaction_model
import chip.tlv
import construct
+from chip.interaction_model import PyWriteAttributeData
from chip.native import ErrorSDKPart, PyChipError
from rich.pretty import pprint
@@ -955,22 +956,22 @@ def WriteAttributes(future: Future, eventLoop, device,
interactionTimeoutMs: Union[None, int] = None, busyWaitMs: Union[None, int] = None) -> PyChipError:
handle = chip.native.GetLibraryHandle()
- writeargs = []
- for attr in attributes:
+ numberOfAttributes = len(attributes)
+ pyWriteAttributesArrayType = PyWriteAttributeData * numberOfAttributes
+ pyWriteAttributes = pyWriteAttributesArrayType()
+ for idx, attr in enumerate(attributes):
if attr.Attribute.must_use_timed_write and timedRequestTimeoutMs is None or timedRequestTimeoutMs == 0:
raise chip.interaction_model.InteractionModelError(chip.interaction_model.Status.NeedsTimedInteraction)
- path = chip.interaction_model.AttributePathIBstruct.parse(
- b'\x00' * chip.interaction_model.AttributePathIBstruct.sizeof())
- path.EndpointId = attr.EndpointId
- path.ClusterId = attr.Attribute.cluster_id
- path.AttributeId = attr.Attribute.attribute_id
- path.DataVersion = attr.DataVersion
- path.HasDataVersion = attr.HasDataVersion
- path = chip.interaction_model.AttributePathIBstruct.build(path)
+
tlv = attr.Attribute.ToTLV(None, attr.Data)
- writeargs.append(ctypes.c_char_p(path))
- writeargs.append(ctypes.c_char_p(bytes(tlv)))
- writeargs.append(ctypes.c_int(len(tlv)))
+
+ pyWriteAttributes[idx].attributePath.endpointId = c_uint16(attr.EndpointId)
+ pyWriteAttributes[idx].attributePath.clusterId = c_uint32(attr.Attribute.cluster_id)
+ pyWriteAttributes[idx].attributePath.attributeId = c_uint32(attr.Attribute.attribute_id)
+ pyWriteAttributes[idx].attributePath.dataVersion = c_uint32(attr.DataVersion)
+ pyWriteAttributes[idx].attributePath.hasDataVersion = c_uint8(attr.HasDataVersion)
+ pyWriteAttributes[idx].tlvData = cast(ctypes.c_char_p(bytes(tlv)), c_void_p)
+ pyWriteAttributes[idx].tlvLength = c_size_t(len(tlv))
transaction = AsyncWriteTransaction(future, eventLoop)
ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction))
@@ -980,7 +981,7 @@ def WriteAttributes(future: Future, eventLoop, device,
ctypes.c_size_t(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs),
ctypes.c_size_t(0 if interactionTimeoutMs is None else interactionTimeoutMs),
ctypes.c_size_t(0 if busyWaitMs is None else busyWaitMs),
- ctypes.c_size_t(len(attributes)), *writeargs)
+ pyWriteAttributes, ctypes.c_size_t(numberOfAttributes))
)
if not res.is_success:
ctypes.pythonapi.Py_DecRef(ctypes.py_object(transaction))
@@ -990,26 +991,26 @@ def WriteAttributes(future: Future, eventLoop, device,
def WriteGroupAttributes(groupId: int, devCtrl: c_void_p, attributes: List[AttributeWriteRequest], busyWaitMs: Union[None, int] = None) -> PyChipError:
handle = chip.native.GetLibraryHandle()
- writeargs = []
- for attr in attributes:
- path = chip.interaction_model.AttributePathIBstruct.parse(
- b'\x00' * chip.interaction_model.AttributePathIBstruct.sizeof())
- path.EndpointId = attr.EndpointId
- path.ClusterId = attr.Attribute.cluster_id
- path.AttributeId = attr.Attribute.attribute_id
- path.DataVersion = attr.DataVersion
- path.HasDataVersion = attr.HasDataVersion
- path = chip.interaction_model.AttributePathIBstruct.build(path)
+ numberOfAttributes = len(attributes)
+ pyWriteAttributesArrayType = PyWriteAttributeData * numberOfAttributes
+ pyWriteAttributes = pyWriteAttributesArrayType()
+ for idx, attr in enumerate(attributes):
+
tlv = attr.Attribute.ToTLV(None, attr.Data)
- writeargs.append(ctypes.c_char_p(path))
- writeargs.append(ctypes.c_char_p(bytes(tlv)))
- writeargs.append(ctypes.c_int(len(tlv)))
+
+ pyWriteAttributes[idx].attributePath.endpointId = c_uint16(attr.EndpointId)
+ pyWriteAttributes[idx].attributePath.clusterId = c_uint32(attr.Attribute.cluster_id)
+ pyWriteAttributes[idx].attributePath.attributeId = c_uint32(attr.Attribute.attribute_id)
+ pyWriteAttributes[idx].attributePath.dataVersion = c_uint32(attr.DataVersion)
+ pyWriteAttributes[idx].attributePath.hasDataVersion = c_uint8(attr.HasDataVersion)
+ pyWriteAttributes[idx].tlvData = cast(ctypes.c_char_p(bytes(tlv)), c_void_p)
+ pyWriteAttributes[idx].tlvLength = c_size_t(len(tlv))
return builtins.chipStack.Call(
lambda: handle.pychip_WriteClient_WriteGroupAttributes(
ctypes.c_size_t(groupId), devCtrl,
ctypes.c_size_t(0 if busyWaitMs is None else busyWaitMs),
- ctypes.c_size_t(len(attributes)), *writeargs)
+ pyWriteAttributes, ctypes.c_size_t(numberOfAttributes))
)
@@ -1037,10 +1038,12 @@ def Read(future: Future, eventLoop, device, devCtrl,
transaction = AsyncReadTransaction(
future, eventLoop, devCtrl, returnClusterObject)
- readargs = []
-
+ attributePathsForCffi = None
if attributes is not None:
- for attr in attributes:
+ numberOfAttributePaths = len(attributes)
+ attributePathsForCffiArrayType = c_void_p * numberOfAttributePaths
+ attributePathsForCffi = attributePathsForCffiArrayType()
+ for idx, attr in enumerate(attributes):
path = chip.interaction_model.AttributePathIBstruct.parse(
b'\xff' * chip.interaction_model.AttributePathIBstruct.sizeof())
if attr.EndpointId is not None:
@@ -1050,10 +1053,14 @@ def Read(future: Future, eventLoop, device, devCtrl,
if attr.AttributeId is not None:
path.AttributeId = attr.AttributeId
path = chip.interaction_model.AttributePathIBstruct.build(path)
- readargs.append(ctypes.c_char_p(path))
+ attributePathsForCffi[idx] = cast(ctypes.c_char_p(path), c_void_p)
+ dataVersionFiltersForCffi = None
if dataVersionFilters is not None:
- for f in dataVersionFilters:
+ numberOfDataVersionFilters = len(dataVersionFilters)
+ dataVersionFiltersForCffiArrayType = c_void_p * numberOfDataVersionFilters
+ dataVersionFiltersForCffi = dataVersionFiltersForCffiArrayType()
+ for idx, f in enumerate(dataVersionFilters):
filter = chip.interaction_model.DataVersionFilterIBstruct.parse(
b'\xff' * chip.interaction_model.DataVersionFilterIBstruct.sizeof())
if f.EndpointId is not None:
@@ -1073,10 +1080,14 @@ def Read(future: Future, eventLoop, device, devCtrl,
"DataVersionFilter must provide DataVersion.")
filter = chip.interaction_model.DataVersionFilterIBstruct.build(
filter)
- readargs.append(ctypes.c_char_p(filter))
+ dataVersionFiltersForCffi[idx] = cast(ctypes.c_char_p(filter), c_void_p)
+ eventPathsForCffi = None
if events is not None:
- for event in events:
+ numberOfEvents = len(events)
+ eventPathsForCffiArrayType = c_void_p * numberOfEvents
+ eventPathsForCffi = eventPathsForCffiArrayType()
+ for idx, event in enumerate(events):
path = chip.interaction_model.EventPathIBstruct.parse(
b'\xff' * chip.interaction_model.EventPathIBstruct.sizeof())
if event.EndpointId is not None:
@@ -1090,7 +1101,7 @@ def Read(future: Future, eventLoop, device, devCtrl,
else:
path.Urgent = 0
path = chip.interaction_model.EventPathIBstruct.build(path)
- readargs.append(ctypes.c_char_p(path))
+ eventPathsForCffi[idx] = cast(ctypes.c_char_p(path), c_void_p)
readClientObj = ctypes.POINTER(c_void_p)()
readCallbackObj = ctypes.POINTER(c_void_p)()
@@ -1116,12 +1127,14 @@ def Read(future: Future, eventLoop, device, devCtrl,
ctypes.byref(readCallbackObj),
device,
ctypes.c_char_p(params),
+ attributePathsForCffi,
ctypes.c_size_t(0 if attributes is None else len(attributes)),
+ dataVersionFiltersForCffi,
ctypes.c_size_t(
0 if dataVersionFilters is None else len(dataVersionFilters)),
+ eventPathsForCffi,
ctypes.c_size_t(0 if events is None else len(events)),
- eventNumberFilterPtr,
- *readargs))
+ eventNumberFilterPtr))
transaction.SetClientObjPointers(readClientObj, readCallbackObj)
@@ -1168,8 +1181,10 @@ def Init():
# attribute information we want written using a vector. This possibility was not implemented at the
# time where simply specified the argtypes, because of time constraints. This solution was quicker
# to fix the crash on ARM64 Apple platforms without a refactor.
- handle.pychip_WriteClient_WriteAttributes.argtypes = [py_object, c_void_p, c_size_t, c_size_t, c_size_t, c_size_t]
- handle.pychip_WriteClient_WriteGroupAttributes.argtypes = [c_size_t, c_void_p, c_size_t, c_size_t]
+ handle.pychip_WriteClient_WriteAttributes.argtypes = [py_object, c_void_p,
+ c_size_t, c_size_t, c_size_t, POINTER(PyWriteAttributeData), c_size_t]
+ handle.pychip_WriteClient_WriteGroupAttributes.argtypes = [
+ c_size_t, c_void_p, c_size_t, POINTER(PyWriteAttributeData), c_size_t]
setter.Set('pychip_WriteClient_InitCallbacks', None, [
_OnWriteResponseCallbackFunct, _OnWriteErrorCallbackFunct, _OnWriteDoneCallbackFunct])
diff --git a/src/controller/python/chip/clusters/Command.py b/src/controller/python/chip/clusters/Command.py
index d3dcc5bba913ff..6e25a76d50230f 100644
--- a/src/controller/python/chip/clusters/Command.py
+++ b/src/controller/python/chip/clusters/Command.py
@@ -21,12 +21,13 @@
import logging
import sys
from asyncio.futures import Future
-from ctypes import CFUNCTYPE, c_bool, c_char_p, c_size_t, c_uint8, c_uint16, c_uint32, c_void_p, py_object
+from ctypes import CFUNCTYPE, POINTER, c_bool, c_char_p, c_size_t, c_uint8, c_uint16, c_uint32, c_void_p, cast, py_object
from dataclasses import dataclass
from typing import List, Optional, Type, Union
import chip.exceptions
import chip.interaction_model
+from chip.interaction_model import PyInvokeRequestData
from chip.native import PyChipError
from .ClusterObjects import ClusterCommand
@@ -313,8 +314,10 @@ def SendBatchCommands(future: Future, eventLoop, device, commands: List[InvokeRe
handle = chip.native.GetLibraryHandle()
responseTypes = []
- commandargs = []
- for command in commands:
+ numberOfCommands = len(commands)
+ pyBatchCommandsDataArrayType = PyInvokeRequestData * numberOfCommands
+ pyBatchCommandsData = pyBatchCommandsDataArrayType()
+ for idx, command in enumerate(commands):
clusterCommand = command.Command
responseType = command.ResponseType
if (responseType is not None) and (not issubclass(responseType, ClusterCommand)):
@@ -322,15 +325,13 @@ def SendBatchCommands(future: Future, eventLoop, device, commands: List[InvokeRe
if clusterCommand.must_use_timed_invoke and timedRequestTimeoutMs is None or timedRequestTimeoutMs == 0:
raise chip.interaction_model.InteractionModelError(chip.interaction_model.Status.NeedsTimedInteraction)
- commandPath = chip.interaction_model.CommandPathIBStruct.build({
- "EndpointId": command.EndpointId,
- "ClusterId": clusterCommand.cluster_id,
- "CommandId": clusterCommand.command_id})
payloadTLV = clusterCommand.ToTLV()
- commandargs.append(c_char_p(commandPath))
- commandargs.append(c_char_p(bytes(payloadTLV)))
- commandargs.append(c_size_t(len(payloadTLV)))
+ pyBatchCommandsData[idx].commandPath.endpointId = c_uint16(command.EndpointId)
+ pyBatchCommandsData[idx].commandPath.clusterId = c_uint32(clusterCommand.cluster_id)
+ pyBatchCommandsData[idx].commandPath.commandId = c_uint32(clusterCommand.command_id)
+ pyBatchCommandsData[idx].tlvData = cast(c_char_p(bytes(payloadTLV)), c_void_p)
+ pyBatchCommandsData[idx].tlvLength = c_size_t(len(payloadTLV))
responseTypes.append(responseType)
@@ -344,7 +345,7 @@ def SendBatchCommands(future: Future, eventLoop, device, commands: List[InvokeRe
c_uint16(0 if interactionTimeoutMs is None else interactionTimeoutMs),
c_uint16(0 if busyWaitMs is None else busyWaitMs),
c_bool(False if suppressResponse is None else suppressResponse),
- c_size_t(len(commands)), *commandargs)
+ pyBatchCommandsData, c_size_t(numberOfCommands))
)
@@ -375,7 +376,7 @@ def Init():
setter.Set('pychip_CommandSender_SendCommand',
PyChipError, [py_object, c_void_p, c_uint16, c_uint32, c_uint32, c_char_p, c_size_t, c_uint16, c_bool])
setter.Set('pychip_CommandSender_SendBatchCommands',
- PyChipError, [py_object, c_void_p, c_uint16, c_uint16, c_uint16, c_bool, c_size_t])
+ PyChipError, [py_object, c_void_p, c_uint16, c_uint16, c_uint16, c_bool, POINTER(PyInvokeRequestData), c_size_t])
setter.Set('pychip_CommandSender_TestOnlySendCommandTimedRequestNoTimedInvoke',
PyChipError, [py_object, c_void_p, c_uint32, c_uint32, c_char_p, c_size_t, c_uint16, c_bool])
setter.Set('pychip_CommandSender_SendGroupCommand',
diff --git a/src/controller/python/chip/clusters/attribute.cpp b/src/controller/python/chip/clusters/attribute.cpp
index d85d132b36bf8a..8abaaab18e1ed9 100644
--- a/src/controller/python/chip/clusters/attribute.cpp
+++ b/src/controller/python/chip/clusters/attribute.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
@@ -256,13 +257,14 @@ struct __attribute__((packed)) PyReadAttributeParams
bool autoResubscribe;
};
-// Encodes n attribute write requests, follows 3 * n arguments, in the (AttributeWritePath*=void *, uint8_t*, size_t) order.
PyChipError pychip_WriteClient_WriteAttributes(void * appContext, DeviceProxy * device, size_t timedWriteTimeoutMsSizeT,
- size_t interactionTimeoutMsSizeT, size_t busyWaitMsSizeT, size_t n, ...);
+ size_t interactionTimeoutMsSizeT, size_t busyWaitMsSizeT,
+ chip::python::PyWriteAttributeData * writeAttributesData,
+ size_t attributeDataLength);
PyChipError pychip_WriteClient_WriteGroupAttributes(size_t groupIdSizeT, chip::Controller::DeviceCommissioner * devCtrl,
- size_t busyWaitMsSizeT, size_t n, ...);
-PyChipError pychip_ReadClient_ReadAttributes(void * appContext, ReadClient ** pReadClient, ReadClientCallback ** pCallback,
- DeviceProxy * device, uint8_t * readParamsBuf, size_t n, size_t total, ...);
+ size_t busyWaitMsSizeT,
+ chip::python::PyWriteAttributeData * writeAttributesData,
+ size_t attributeDataLength);
}
using OnWriteResponseCallback = void (*)(PyObject * appContext, chip::EndpointId endpointId, chip::ClusterId clusterId,
@@ -337,7 +339,8 @@ void pychip_ReadClient_InitCallbacks(OnReadAttributeDataCallback onReadAttribute
}
PyChipError pychip_WriteClient_WriteAttributes(void * appContext, DeviceProxy * device, size_t timedWriteTimeoutMsSizeT,
- size_t interactionTimeoutMsSizeT, size_t busyWaitMsSizeT, size_t n, ...)
+ size_t interactionTimeoutMsSizeT, size_t busyWaitMsSizeT,
+ python::PyWriteAttributeData * writeAttributesData, size_t attributeDataLength)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -352,35 +355,27 @@ PyChipError pychip_WriteClient_WriteAttributes(void * appContext, DeviceProxy *
app::InteractionModelEngine::GetInstance()->GetExchangeManager(), callback->GetChunkedCallback(),
timedWriteTimeoutMs != 0 ? Optional(timedWriteTimeoutMs) : Optional::Missing());
- va_list args;
- va_start(args, n);
-
VerifyOrExit(device != nullptr && device->GetSecureSession().HasValue(), err = CHIP_ERROR_MISSING_SECURE_SESSION);
+ for (size_t i = 0; i < attributeDataLength; i++)
{
- for (size_t i = 0; i < n; i++)
+ python::PyAttributePath path = writeAttributesData[i].attributePath;
+ void * tlv = writeAttributesData[i].tlvData;
+ size_t length = writeAttributesData[i].tlvLength;
+
+ uint8_t * tlvBuffer = reinterpret_cast(tlv);
+
+ TLV::TLVReader reader;
+ reader.Init(tlvBuffer, static_cast(length));
+ reader.Next();
+ Optional dataVersion;
+ if (path.hasDataVersion == 1)
{
- void * path = va_arg(args, void *);
- void * tlv = va_arg(args, void *);
- int length = va_arg(args, int);
-
- python::AttributePath pathObj;
- memcpy(&pathObj, path, sizeof(python::AttributePath));
- uint8_t * tlvBuffer = reinterpret_cast(tlv);
-
- TLV::TLVReader reader;
- reader.Init(tlvBuffer, static_cast(length));
- reader.Next();
- Optional dataVersion;
- if (pathObj.hasDataVersion == 1)
- {
- dataVersion.SetValue(pathObj.dataVersion);
- }
- SuccessOrExit(
- err = client->PutPreencodedAttribute(
- chip::app::ConcreteDataAttributePath(pathObj.endpointId, pathObj.clusterId, pathObj.attributeId, dataVersion),
- reader));
+ dataVersion.SetValue(path.dataVersion);
}
+ SuccessOrExit(
+ err = client->PutPreencodedAttribute(
+ chip::app::ConcreteDataAttributePath(path.endpointId, path.clusterId, path.attributeId, dataVersion), reader));
}
SuccessOrExit(err = client->SendWriteRequest(device->GetSecureSession().Value(),
@@ -396,12 +391,12 @@ PyChipError pychip_WriteClient_WriteAttributes(void * appContext, DeviceProxy *
}
exit:
- va_end(args);
return ToPyChipError(err);
}
PyChipError pychip_WriteClient_WriteGroupAttributes(size_t groupIdSizeT, chip::Controller::DeviceCommissioner * devCtrl,
- size_t busyWaitMsSizeT, size_t n, ...)
+ size_t busyWaitMsSizeT, python::PyWriteAttributeData * writeAttributesData,
+ size_t attributeDataLength)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -417,34 +412,26 @@ PyChipError pychip_WriteClient_WriteGroupAttributes(size_t groupIdSizeT, chip::C
std::unique_ptr client = std::make_unique(
app::InteractionModelEngine::GetInstance()->GetExchangeManager(), nullptr /* callback */, Optional::Missing());
- va_list args;
- va_start(args, n);
-
+ for (size_t i = 0; i < attributeDataLength; i++)
{
- for (size_t i = 0; i < n; i++)
+ python::PyAttributePath path = writeAttributesData[i].attributePath;
+ void * tlv = writeAttributesData[i].tlvData;
+ size_t length = writeAttributesData[i].tlvLength;
+
+ uint8_t * tlvBuffer = reinterpret_cast(tlv);
+
+ TLV::TLVReader reader;
+ reader.Init(tlvBuffer, static_cast(length));
+ reader.Next();
+ Optional dataVersion;
+ if (path.hasDataVersion == 1)
{
- void * path = va_arg(args, void *);
- void * tlv = va_arg(args, void *);
- int length = va_arg(args, int);
-
- python::AttributePath pathObj;
- memcpy(&pathObj, path, sizeof(python::AttributePath));
- uint8_t * tlvBuffer = reinterpret_cast(tlv);
-
- TLV::TLVReader reader;
- reader.Init(tlvBuffer, static_cast(length));
- reader.Next();
- Optional dataVersion;
- if (pathObj.hasDataVersion == 1)
- {
- dataVersion.SetValue(pathObj.dataVersion);
- }
- // Using kInvalidEndpointId as that used when sending group write requests.
- SuccessOrExit(
- err = client->PutPreencodedAttribute(
- chip::app::ConcreteDataAttributePath(kInvalidEndpointId, pathObj.clusterId, pathObj.attributeId, dataVersion),
- reader));
+ dataVersion.SetValue(path.dataVersion);
}
+ // Using kInvalidEndpointId as that used when sending group write requests.
+ SuccessOrExit(
+ err = client->PutPreencodedAttribute(
+ chip::app::ConcreteDataAttributePath(kInvalidEndpointId, path.clusterId, path.attributeId, dataVersion), reader));
}
{
@@ -460,7 +447,6 @@ PyChipError pychip_WriteClient_WriteGroupAttributes(size_t groupIdSizeT, chip::C
}
exit:
- va_end(args);
return ToPyChipError(err);
}
@@ -487,8 +473,9 @@ PyChipError pychip_ReadClient_GetReportingIntervals(ReadClient * pReadClient, ui
}
PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient, ReadClientCallback ** pCallback,
- DeviceProxy * device, uint8_t * readParamsBuf, size_t numAttributePaths,
- size_t numDataversionFilters, size_t numEventPaths, uint64_t * eventNumberFilter, ...)
+ DeviceProxy * device, uint8_t * readParamsBuf, void ** attributePathsFromPython,
+ size_t numAttributePaths, void ** dataversionFiltersFromPython, size_t numDataversionFilters,
+ void ** eventPathsFromPython, size_t numEventPaths, uint64_t * eventNumberFilter)
{
CHIP_ERROR err = CHIP_NO_ERROR;
PyReadAttributeParams pyParams = {};
@@ -497,9 +484,6 @@ PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient,
std::unique_ptr callback = std::make_unique(appContext);
- va_list args;
- va_start(args, eventNumberFilter);
-
std::unique_ptr attributePaths(new AttributePathParams[numAttributePaths]);
std::unique_ptr dataVersionFilters(new chip::app::DataVersionFilter[numDataversionFilters]);
std::unique_ptr eventPaths(new EventPathParams[numEventPaths]);
@@ -507,7 +491,7 @@ PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient,
for (size_t i = 0; i < numAttributePaths; i++)
{
- void * path = va_arg(args, void *);
+ void * path = attributePathsFromPython[i];
python::AttributePath pathObj;
memcpy(&pathObj, path, sizeof(python::AttributePath));
@@ -517,7 +501,7 @@ PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient,
for (size_t i = 0; i < numDataversionFilters; i++)
{
- void * filter = va_arg(args, void *);
+ void * filter = dataversionFiltersFromPython[i];
python::DataVersionFilter filterObj;
memcpy(&filterObj, filter, sizeof(python::DataVersionFilter));
@@ -527,7 +511,7 @@ PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient,
for (size_t i = 0; i < numEventPaths; i++)
{
- void * path = va_arg(args, void *);
+ void * path = eventPathsFromPython[i];
python::EventPath pathObj;
memcpy(&pathObj, path, sizeof(python::EventPath));
@@ -599,7 +583,6 @@ PyChipError pychip_ReadClient_Read(void * appContext, ReadClient ** pReadClient,
callback.release();
exit:
- va_end(args);
return ToPyChipError(err);
}
}
diff --git a/src/controller/python/chip/clusters/command.cpp b/src/controller/python/chip/clusters/command.cpp
index c920a82c53fb54..7195cefe16eba1 100644
--- a/src/controller/python/chip/clusters/command.cpp
+++ b/src/controller/python/chip/clusters/command.cpp
@@ -41,7 +41,7 @@ PyChipError pychip_CommandSender_SendCommand(void * appContext, DeviceProxy * de
PyChipError pychip_CommandSender_SendBatchCommands(void * appContext, DeviceProxy * device, uint16_t timedRequestTimeoutMs,
uint16_t interactionTimeoutMs, uint16_t busyWaitMs, bool suppressResponse,
- size_t n, ...);
+ chip::python::PyInvokeRequestData * batchCommandData, size_t length);
PyChipError pychip_CommandSender_TestOnlySendCommandTimedRequestNoTimedInvoke(
void * appContext, DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, chip::CommandId commandId,
@@ -68,13 +68,6 @@ OnCommandSenderResponseCallback gOnCommandSenderResponseCallback = nullptr;
OnCommandSenderErrorCallback gOnCommandSenderErrorCallback = nullptr;
OnCommandSenderDoneCallback gOnCommandSenderDoneCallback = nullptr;
-struct __attribute__((packed)) CommandPath
-{
- chip::EndpointId endpointId;
- chip::ClusterId clusterId;
- chip::CommandId commandId;
-};
-
class CommandSenderCallback : public CommandSender::ExtendableCallback
{
public:
@@ -256,7 +249,7 @@ PyChipError pychip_CommandSender_SendCommand(void * appContext, DeviceProxy * de
PyChipError pychip_CommandSender_SendBatchCommands(void * appContext, DeviceProxy * device, uint16_t timedRequestTimeoutMs,
uint16_t interactionTimeoutMs, uint16_t busyWaitMs, bool suppressResponse,
- size_t n, ...)
+ python::PyInvokeRequestData * batchCommandData, size_t length)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -279,47 +272,41 @@ PyChipError pychip_CommandSender_SendBatchCommands(void * appContext, DeviceProx
std::make_unique(callback.get(), device->GetExchangeManager(),
/* is timed request */ timedRequestTimeoutMs != 0, suppressResponse);
- // TODO(#30986): Move away from passing these command through variadic arguments.
- va_list args;
- va_start(args, n);
-
SuccessOrExit(err = sender->SetCommandSenderConfig(config));
+ for (size_t i = 0; i < length; i++)
{
- for (size_t i = 0; i < n; i++)
- {
- void * commandPath = va_arg(args, void *);
- void * tlv = va_arg(args, void *);
- int length = va_arg(args, int);
+ chip::EndpointId endpointId = batchCommandData[i].commandPath.endpointId;
+ chip::ClusterId clusterId = batchCommandData[i].commandPath.clusterId;
+ chip::CommandId commandId = batchCommandData[i].commandPath.commandId;
+ void * tlv = batchCommandData[i].tlvData;
+ size_t tlvLength = batchCommandData[i].tlvLength;
- python::CommandPath invokeRequestInfoObj;
- memcpy(&invokeRequestInfoObj, commandPath, sizeof(python::CommandPath));
- const uint8_t * tlvBuffer = reinterpret_cast(tlv);
+ const uint8_t * tlvBuffer = reinterpret_cast(tlv);
- app::CommandPathParams cmdParams = { invokeRequestInfoObj.endpointId, /* group id */ 0, invokeRequestInfoObj.clusterId,
- invokeRequestInfoObj.commandId, (app::CommandPathFlags::kEndpointIdValid) };
+ app::CommandPathParams cmdParams = { endpointId, /* group id */ 0, clusterId, commandId,
+ (app::CommandPathFlags::kEndpointIdValid) };
- CommandSender::AdditionalCommandParameters additionalParams;
+ CommandSender::AdditionalCommandParameters additionalParams;
- SuccessOrExit(err = sender->PrepareCommand(cmdParams, additionalParams));
- {
- auto writer = sender->GetCommandDataIBTLVWriter();
- VerifyOrExit(writer != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
- TLV::TLVReader reader;
- reader.Init(tlvBuffer, static_cast(length));
- reader.Next();
- SuccessOrExit(err = writer->CopyContainer(TLV::ContextTag(CommandDataIB::Tag::kFields), reader));
- }
+ SuccessOrExit(err = sender->PrepareCommand(cmdParams, additionalParams));
+ {
+ auto writer = sender->GetCommandDataIBTLVWriter();
+ VerifyOrExit(writer != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
+ TLV::TLVReader reader;
+ reader.Init(tlvBuffer, static_cast(tlvLength));
+ reader.Next();
+ SuccessOrExit(err = writer->CopyContainer(TLV::ContextTag(CommandDataIB::Tag::kFields), reader));
+ }
- SuccessOrExit(err = sender->FinishCommand(timedRequestTimeoutMs != 0 ? Optional(timedRequestTimeoutMs)
- : Optional::Missing(),
- additionalParams));
+ SuccessOrExit(err = sender->FinishCommand(timedRequestTimeoutMs != 0 ? Optional(timedRequestTimeoutMs)
+ : Optional::Missing(),
+ additionalParams));
- // CommandSender provides us with the CommandReference for this associated command. In order to match responses
- // we have to add CommandRef to index lookup.
- VerifyOrExit(additionalParams.commandRef.HasValue(), err = CHIP_ERROR_INVALID_ARGUMENT);
- SuccessOrExit(err = callback->AddCommandRefToIndexLookup(additionalParams.commandRef.Value(), i));
- }
+ // CommandSender provides us with the CommandReference for this associated command. In order to match responses
+ // we have to add CommandRef to index lookup.
+ VerifyOrExit(additionalParams.commandRef.HasValue(), err = CHIP_ERROR_INVALID_ARGUMENT);
+ SuccessOrExit(err = callback->AddCommandRefToIndexLookup(additionalParams.commandRef.Value(), i));
}
SuccessOrExit(err = sender->SendCommandRequest(device->GetSecureSession().Value(),
@@ -338,7 +325,6 @@ PyChipError pychip_CommandSender_SendBatchCommands(void * appContext, DeviceProx
}
exit:
- va_end(args);
return ToPyChipError(err);
}
diff --git a/src/controller/python/chip/interaction_model/Delegate.h b/src/controller/python/chip/interaction_model/Delegate.h
index c92d0d042459c7..f11f4931fc4c1d 100644
--- a/src/controller/python/chip/interaction_model/Delegate.h
+++ b/src/controller/python/chip/interaction_model/Delegate.h
@@ -23,8 +23,45 @@
namespace chip {
namespace python {
+
static constexpr ClusterStatus kUndefinedClusterStatus = 0xFF;
-}
+
+// This needs to match the python definition that uses the same name.
+struct PyCommandPath
+{
+ chip::EndpointId endpointId;
+ chip::ClusterId clusterId;
+ chip::CommandId commandId;
+};
+
+// This needs to match the python definition that uses the same name.
+struct PyInvokeRequestData
+{
+ PyCommandPath commandPath;
+ void * tlvData;
+ size_t tlvLength;
+};
+
+// This needs to match the python definition that uses the same name.
+struct PyAttributePath
+{
+ chip::EndpointId endpointId;
+ chip::ClusterId clusterId;
+ chip::AttributeId attributeId;
+ chip::DataVersion dataVersion;
+ uint8_t hasDataVersion;
+};
+
+// This needs to match the python definition that uses the same name.
+struct PyWriteAttributeData
+{
+ PyAttributePath attributePath;
+ void * tlvData;
+ size_t tlvLength;
+};
+
+} // namespace python
+
namespace Controller {
// The command status will be used for python script.
diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py
index 97c185bdcd96e5..78568563a73475 100644
--- a/src/controller/python/chip/interaction_model/__init__.py
+++ b/src/controller/python/chip/interaction_model/__init__.py
@@ -26,12 +26,12 @@
from chip.exceptions import ChipStackException
-from .delegate import (AttributePath, AttributePathIBstruct, CommandPathIBStruct, DataVersionFilterIBstruct, EventPath,
- EventPathIBstruct, SessionParameters, SessionParametersStruct)
+from .delegate import (AttributePath, AttributePathIBstruct, DataVersionFilterIBstruct, EventPath, EventPathIBstruct,
+ PyInvokeRequestData, PyWriteAttributeData, SessionParameters, SessionParametersStruct)
-__all__ = ["AttributePath", "AttributePathIBstruct", "CommandPathIBStruct",
- "DataVersionFilterIBstruct", "EventPath", "EventPathIBstruct",
- "InteractionModelError", "SessionParameters", "SessionParametersStruct", "Status"]
+__all__ = ["AttributePath", "AttributePathIBstruct", "DataVersionFilterIBstruct",
+ "EventPath", "EventPathIBstruct", "InteractionModelError", "PyInvokeRequestData",
+ "PyWriteAttributeData", "SessionParameters", "SessionParametersStruct", "Status"]
# defined src/controller/python/chip/interaction_model/Delegate.h
diff --git a/src/controller/python/chip/interaction_model/delegate.py b/src/controller/python/chip/interaction_model/delegate.py
index 6ce577b94580de..a9a9c04c4365a9 100644
--- a/src/controller/python/chip/interaction_model/delegate.py
+++ b/src/controller/python/chip/interaction_model/delegate.py
@@ -46,12 +46,6 @@
"AttributeId" / Int32ul,
)
-CommandPathIBStruct = Struct(
- "EndpointId" / Int16ul,
- "ClusterId" / Int32ul,
- "CommandId" / Int32ul,
-)
-
# AttributePath should not contain padding
AttributePathIBstruct = Struct(
"EndpointId" / Int16ul,
@@ -134,6 +128,77 @@ class SessionParameters:
maxPathsPerInvoke: int
+class PyCommandPath(ctypes.Structure):
+ ''' InvokeRequest Path struct that has c++ counterpart for CFFI.
+
+ We are using the following struct for passing the information of InvokeRequest between Python and C++:
+
+ ```c
+ struct PyCommandPath
+ {
+ chip::EndpointId endpointId;
+ chip::ClusterId clusterId;
+ chip::CommandId commandId;
+ };
+ ```
+ '''
+ _fields_ = [('endpointId', ctypes.c_uint16), ('clusterId', ctypes.c_uint32), ('commandId', ctypes.c_uint32)]
+
+
+class PyInvokeRequestData(ctypes.Structure):
+ ''' InvokeRequest struct that has c++ counterpart for CFFI.
+
+ We are using the following struct for passing the information of InvokeRequest between Python and C++:
+
+ ```c
+ struct PyInvokeRequestData
+ {
+ PyCommandPath commandPath;
+ void * tlvData;
+ size_t tlvLength;
+ };
+ ```
+ '''
+ _fields_ = [('commandPath', PyCommandPath), ('tlvData', ctypes.c_void_p), ('tlvLength', ctypes.c_size_t)]
+
+
+class PyAttributePath(ctypes.Structure):
+ ''' Attributed Path struct that has c++ counterpart for CFFI.
+
+ We are using the following struct for passing the information of WriteAttributes between Python and C++:
+
+ ```c
+ struct PyAttributePath
+ {
+ chip::EndpointId endpointId;
+ chip::ClusterId clusterId;
+ chip::AttributeId attributeId;
+ chip::DataVersion dataVersion;
+ uint8_t hasDataVersion;
+ };
+ ```
+ '''
+ _fields_ = [('endpointId', ctypes.c_uint16), ('clusterId', ctypes.c_uint32), ('attributeId',
+ ctypes.c_uint32), ('dataVersion', ctypes.c_uint32), ('hasDataVersion', ctypes.c_uint8)]
+
+
+class PyWriteAttributeData(ctypes.Structure):
+ ''' WriteAttribute struct that has c++ counterpart for CFFI.
+
+ We are using the following struct for passing the information of WriteAttributes between Python and C++:
+
+ ```c
+ struct PyWriteAttributeData
+ {
+ PyAttributePath attributePath;
+ void * tlvData;
+ size_t tlvLength;
+ };
+ ```
+ '''
+ _fields_ = [('attributePath', PyAttributePath), ('tlvData', ctypes.c_void_p), ('tlvLength', ctypes.c_size_t)]
+
+
# typedef void (*PythonInteractionModelDelegate_OnCommandResponseStatusCodeReceivedFunct)(uint64_t commandSenderPtr,
# void * commandStatusBuf);
# typedef void (*PythonInteractionModelDelegate_OnCommandResponseProtocolErrorFunct)(uint64_t commandSenderPtr,
diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp
index 74b339abad9877..4a3af662853172 100644
--- a/src/crypto/tests/CHIPCryptoPALTest.cpp
+++ b/src/crypto/tests/CHIPCryptoPALTest.cpp
@@ -52,10 +52,6 @@
#include
-#if CHIP_CRYPTO_MBEDTLS
-#include
-#endif
-
#include
#include
#include
@@ -71,6 +67,10 @@
#include
#include
+#if CHIP_CRYPTO_MBEDTLS || CHIP_CRYPTO_PSA
+#include
+#endif
+
#if CHIP_CRYPTO_PSA
#include
#endif
@@ -88,7 +88,7 @@ using TestHKDF_sha = HKDF_sha;
using TestHMAC_sha = HMAC_sha;
// Helper class to verify that all mbedTLS heap objects are released at the end of a test.
-#if CHIP_CRYPTO_MBEDTLS && defined(MBEDTLS_MEMORY_DEBUG)
+#if defined(MBEDTLS_MEMORY_DEBUG)
class HeapChecker
{
public:
diff --git a/src/include/platform/NetworkCommissioning.h b/src/include/platform/NetworkCommissioning.h
index be33a98779ed58..6c2741d81201c5 100644
--- a/src/include/platform/NetworkCommissioning.h
+++ b/src/include/platform/NetworkCommissioning.h
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -36,6 +37,7 @@
#include
#include
+#include
namespace chip {
namespace DeviceLayer {
@@ -129,9 +131,13 @@ using NetworkIterator = Iterator;
using WiFiScanResponseIterator = Iterator;
using ThreadScanResponseIterator = Iterator;
using Status = app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum;
-using WiFiBand = app::Clusters::NetworkCommissioning::WiFiBandEnum;
-using WiFiSecurity = app::Clusters::NetworkCommissioning::WiFiSecurityBitmap;
-using ThreadCapabilities = app::Clusters::NetworkCommissioning::ThreadCapabilitiesBitmap;
+using WiFiBandEnum = app::Clusters::NetworkCommissioning::WiFiBandEnum;
+// For backwards compatibility with pre-rename enum values.
+using WiFiBand = WiFiBandEnum;
+using WiFiSecurityBitmap = app::Clusters::NetworkCommissioning::WiFiSecurityBitmap;
+// For backwards compatibility with pre-rename bitmap values.
+using WiFiSecurity = WiFiSecurityBitmap;
+using ThreadCapabilities = app::Clusters::NetworkCommissioning::ThreadCapabilitiesBitmap;
// BaseDriver and WirelessDriver are the common interfaces for a network driver, platform drivers should not implement this
// directly, instead, users are expected to implement WiFiDriver, ThreadDriver and EthernetDriver.
@@ -352,24 +358,26 @@ class WiFiDriver : public Internal::WirelessDriver
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
/**
- * @brief Provide all the frequency bands supported by the Wi-Fi interface
+ * @brief Provide all the frequency bands supported by the Wi-Fi interface.
*
* The default implementation returns the 2.4 GHz band support.
- * Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities
+ * Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities.
*
- * @param bands Reference to a span that is used to return the supported bands.
- * The span is initialized with a fixed-size buffer.
- * The implementation is expected to resize the span to match the number of returned results.
+ * The returned bit mask has values of WiFiBandEnum packed into the bits. For example:
*
- * @return CHIP_NO_ERROR on success or a CHIP_ERROR on failure.
+ * - Bit 0 = (WiFiBandEnum::k2g4 == 0) --> (1 << 0) == (1 << WiFiBandEnum::k2g4)
+ * - Bit 2 = (WiFiBandEnum::k5g == 2) --> (1 << 2) == (1 << WiFiBandEnum::k5g)
+ * - If both 2.4G and 5G are supported --> ((1 << k2g4) || (1 << k5g)) == (1 || 4) == 5
+ *
+ * On error, return 0 (no bands supported). This should never happen... Note that
+ * certification tests will REQUIRE at least one bit set in the set.
+ *
+ * @return a bitmask of supported Wi-Fi bands where each bit is associated with a WiFiBandEnum value.
*/
- virtual CHIP_ERROR GetSupportedWiFiBands(Span & bands)
+ virtual uint32_t GetSupportedWiFiBandsMask() const
{
- ReturnErrorCodeIf(bands.empty(), CHIP_ERROR_BUFFER_TOO_SMALL);
- bands.front() = WiFiBand::k2g4;
- bands.reduce_size(1);
-
- return CHIP_NO_ERROR;
+ // Default to 2.4G support (100% example platform coverage as of Matter 1.3) listed.
+ return static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4));
}
~WiFiDriver() override = default;
diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
index d8eb9b17d473b3..1efe5c863f8753 100644
--- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
+++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
@@ -17,10 +17,13 @@
#include "NrfWiFiDriver.h"
+#include
+
#include
#include
#include
+#include
#include
using namespace ::chip;
@@ -276,20 +279,13 @@ void NrfWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callb
}
}
-CHIP_ERROR NrfWiFiDriver::GetSupportedWiFiBands(Span & bands)
+uint32_t NrfWiFiDriver::GetSupportedWiFiBandsMask() const
{
- static constexpr WiFiBand kBands[] = {
- WiFiBand::k2g4,
+ uint32_t bands = static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4));
#ifndef CONFIG_BOARD_NRF7001
- WiFiBand::k5g,
+ bands |= static_cast(1UL << chip::to_underlying(WiFiBandEnum::k5g));
#endif
- };
-
- VerifyOrReturnError(ArraySize(kBands) <= bands.size(), CHIP_ERROR_BUFFER_TOO_SMALL);
- memcpy(bands.data(), kBands, sizeof(kBands));
- bands.reduce_size(ArraySize(kBands));
-
- return CHIP_NO_ERROR;
+ return bands;
}
} // namespace NetworkCommissioning
diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
index 1dd73a967d1f3e..7fe1ff1695351d 100644
--- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
+++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
@@ -86,7 +86,7 @@ class NrfWiFiDriver final : public WiFiDriver
Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText,
uint8_t & outNetworkIndex) override;
void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override;
- CHIP_ERROR GetSupportedWiFiBands(Span & bands) override;
+ uint32_t GetSupportedWiFiBandsMask() const override;
static NrfWiFiDriver & Instance()
{
diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp
index 5d20035aa99940..d6aa5f2e939251 100644
--- a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp
+++ b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp
@@ -1174,9 +1174,14 @@ void BLEManagerCommon::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectio
if (pConnectionEvent->eventType == gConnEvtConnected_c)
{
+#if CHIP_DEVICE_K32W1
#if defined(chip_with_low_power) && (chip_with_low_power == 1)
+ /* Disallow must be called here for K32W1, otherwise an assert will be reached.
+ * Disclaimer: this is a workaround until a better cross platform solution is found. */
PWR_DisallowDeviceToSleep();
#endif
+#endif
+
#if CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ
ChipLogProgress(DeviceLayer, "BLE K32W: Trying to set the PHY to 2M");
diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp b/src/platform/nxp/k32w/common/FactoryDataProvider.cpp
index 315811cbf32442..1770cf22c659f0 100644
--- a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp
+++ b/src/platform/nxp/k32w/common/FactoryDataProvider.cpp
@@ -44,31 +44,6 @@ uint32_t FactoryDataProvider::kFactoryDataStart = (uint32_t) __MATTER_FAC
uint32_t FactoryDataProvider::kFactoryDataSize = (uint32_t) __MATTER_FACTORY_DATA_SIZE;
uint32_t FactoryDataProvider::kFactoryDataPayloadStart = kFactoryDataStart + sizeof(FactoryDataProvider::Header);
-FactoryDataProvider::FactoryDataProvider()
-{
- maxLengths[FactoryDataId::kVerifierId] = kSpake2pSerializedVerifier_MaxBase64Len;
- maxLengths[FactoryDataId::kSaltId] = kSpake2pSalt_MaxBase64Len;
- maxLengths[FactoryDataId::kIcId] = sizeof(uint32_t);
- maxLengths[FactoryDataId::kDacPrivateKeyId] = Crypto::kP256_PrivateKey_Length;
- maxLengths[FactoryDataId::kDacCertificateId] = Credentials::kMaxDERCertLength;
- maxLengths[FactoryDataId::kPaiCertificateId] = Credentials::kMaxDERCertLength;
- maxLengths[FactoryDataId::kDiscriminatorId] = sizeof(uint32_t);
- maxLengths[FactoryDataId::kSetupPasscodeId] = sizeof(uint32_t);
- maxLengths[FactoryDataId::kVidId] = sizeof(uint16_t);
- maxLengths[FactoryDataId::kPidId] = sizeof(uint16_t);
- maxLengths[FactoryDataId::kCertDeclarationId] = Credentials::kMaxCMSSignedCDMessage;
- maxLengths[FactoryDataId::kVendorNameId] = ConfigurationManager::kMaxVendorNameLength;
- maxLengths[FactoryDataId::kProductNameId] = ConfigurationManager::kMaxProductNameLength;
- maxLengths[FactoryDataId::kSerialNumberId] = ConfigurationManager::kMaxSerialNumberLength;
- maxLengths[FactoryDataId::kManufacturingDateId] = ConfigurationManager::kMaxManufacturingDateLength;
- maxLengths[FactoryDataId::kHardwareVersionId] = sizeof(uint16_t);
- maxLengths[FactoryDataId::kHardwareVersionStrId] = ConfigurationManager::kMaxHardwareVersionStringLength;
- maxLengths[FactoryDataId::kUniqueId] = ConfigurationManager::kMaxUniqueIDLength;
- maxLengths[FactoryDataId::kPartNumber] = ConfigurationManager::kMaxPartNumberLength;
- maxLengths[FactoryDataId::kProductURL] = ConfigurationManager::kMaxProductURLLength;
- maxLengths[FactoryDataId::kProductLabel] = ConfigurationManager::kMaxProductLabelLength;
-}
-
FactoryDataProvider::~FactoryDataProvider() {}
CHIP_ERROR FactoryDataProvider::Validate()
@@ -97,12 +72,6 @@ CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf
if (searchedType == type)
{
- if ((type >= FactoryDataProvider::kNumberOfIds) || (length > maxLengths[type]))
- {
- ChipLogError(DeviceLayer, "Failed validity check for factory data with: id=%d, length=%d", type, length);
- break;
- }
-
ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL);
memcpy(pBuf, (void *) (addr + kValueOffset), length);
@@ -367,5 +336,29 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un
return err;
}
+CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish)
+{
+ uint8_t productFinish;
+ uint16_t length = 0;
+ auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length);
+ ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED);
+
+ *finish = static_cast(productFinish);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor)
+{
+ uint8_t color;
+ uint16_t length = 0;
+ auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length);
+ ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED);
+
+ *primaryColor = static_cast(color);
+
+ return CHIP_NO_ERROR;
+}
+
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.h b/src/platform/nxp/k32w/common/FactoryDataProvider.h
index 99b9a1e039cf34..2bad3e7934482f 100644
--- a/src/platform/nxp/k32w/common/FactoryDataProvider.h
+++ b/src/platform/nxp/k32w/common/FactoryDataProvider.h
@@ -88,17 +88,11 @@ class FactoryDataProvider : public DeviceInstanceInfoProvider,
kPartNumber,
kProductURL,
kProductLabel,
+ kProductFinish,
+ kProductPrimaryColor,
kMaxId
};
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
-#if !CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS
-#error "CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS must be > 0 if custom provider is enabled."
-#endif
- static constexpr uint16_t kNumberOfIds = FactoryDataId::kMaxId + CHIP_DEVICE_CONFIG_CUSTOM_PROVIDER_NUMBER_IDS;
-#else
- static constexpr uint16_t kNumberOfIds = FactoryDataId::kMaxId;
-#endif
static uint32_t kFactoryDataStart;
static uint32_t kFactoryDataSize;
static uint32_t kFactoryDataPayloadStart;
@@ -107,11 +101,13 @@ class FactoryDataProvider : public DeviceInstanceInfoProvider,
static constexpr uint32_t kHashLen = 4;
static constexpr size_t kHashId = 0xCE47BA5E;
- FactoryDataProvider();
virtual ~FactoryDataProvider();
virtual CHIP_ERROR Init() = 0;
virtual CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) = 0;
+ CHIP_ERROR Validate();
+
+ CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * offset = nullptr);
// ===== Members functions that implement the CommissionableDataProvider
CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override;
@@ -142,12 +138,10 @@ class FactoryDataProvider : public DeviceInstanceInfoProvider,
CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override;
CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override;
CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override;
+ CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override;
+ CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override;
protected:
- CHIP_ERROR Validate();
- CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * offset = nullptr);
-
- uint16_t maxLengths[kNumberOfIds];
Header mHeader;
};
diff --git a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp
index c80bf64eaa357b..946c0c37f83d87 100644
--- a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp
+++ b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp
@@ -148,6 +148,16 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessPayload(ByteSpan & block)
mAccumulator.Init(sizeof(OTATlvHeader));
mCurrentProcessor = nullptr;
+
+ // If the block size is 0, it means that the processed data was a multiple of
+ // received BDX block size (e.g. 8 blocks of 1024 bytes were transferred).
+ // After state for selecting next processor is reset, a request for fetching next
+ // data must be sent.
+ if (block.size() == 0)
+ {
+ status = CHIP_NO_ERROR;
+ break;
+ }
}
else
{
@@ -380,7 +390,11 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
// queued actions, e.g. sending events to a subscription
SystemLayer().StartTimer(
chip::System::Clock::Milliseconds32(CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY),
- [](chip::System::Layer *, void *) { OtaHookReset(); }, nullptr);
+ [](chip::System::Layer *, void *) {
+ PlatformMgr().HandleServerShuttingDown();
+ OtaHookReset();
+ },
+ nullptr);
}
CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock()
diff --git a/src/platform/nxp/k32w/common/OTATlvProcessor.cpp b/src/platform/nxp/k32w/common/OTATlvProcessor.cpp
index 7571e693728c00..d9d2ccba6f28e3 100644
--- a/src/platform/nxp/k32w/common/OTATlvProcessor.cpp
+++ b/src/platform/nxp/k32w/common/OTATlvProcessor.cpp
@@ -45,7 +45,7 @@ CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block)
if (mProcessedLength == mLength)
{
status = ExitAction();
- if (!IsError(status) && (block.size() > 0))
+ if (!IsError(status))
{
// If current block was processed fully and the block still contains data, it
// means that the block contains another TLV's data and the current processor
@@ -106,7 +106,7 @@ CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block)
CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block)
{
uint8_t iv[16];
- uint8_t key[16];
+ uint8_t key[kOTAEncryptionKeyLength];
uint8_t dataOut[16] = { 0 };
uint32_t u32IVCount;
uint32_t Offset = 0;
@@ -124,18 +124,13 @@ CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & bloc
iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff);
iv[15] = (uint8_t) (u32IVCount & 0xff);
- size_t len = strlen(OTA_ENCRYPTION_KEY);
-
- if (len != 32)
+ if (Encoding::HexToBytes(OTA_ENCRYPTION_KEY, strlen(OTA_ENCRYPTION_KEY), key, kOTAEncryptionKeyLength) !=
+ kOTAEncryptionKeyLength)
{
- return CHIP_ERROR_INVALID_ARGUMENT;
+ // Failed to convert the OTAEncryptionKey string to octstr type value
+ return CHIP_ERROR_INVALID_STRING_LENGTH;
}
- for (size_t i = 0; i < len; i += 2)
- {
- char hex[3] = { OTA_ENCRYPTION_KEY[i], OTA_ENCRYPTION_KEY[i + 1], '\0' };
- key[i / 2] = (uint8_t) strtol(hex, NULL, 16);
- }
ByteSpan KEY = ByteSpan(key);
Encoding::LittleEndian::Reader reader_key(KEY.data(), KEY.size());
ReturnErrorOnFailure(reader_key.Read32(&sKey.u32register0)
diff --git a/src/platform/nxp/k32w/common/OTATlvProcessor.h b/src/platform/nxp/k32w/common/OTATlvProcessor.h
index e412e1cdd1c5fa..13a2df115d90d9 100644
--- a/src/platform/nxp/k32w/common/OTATlvProcessor.h
+++ b/src/platform/nxp/k32w/common/OTATlvProcessor.h
@@ -127,6 +127,8 @@ class OTATlvProcessor
#if OTA_ENCRYPTION_ENABLE
/*ota decryption*/
uint32_t mIVOffset = 0;
+ /* Expected byte size of the OTAEncryptionKeyLength */
+ static constexpr size_t kOTAEncryptionKeyLength = 16;
#endif
uint32_t mLength = 0;
uint32_t mProcessedLength = 0;
diff --git a/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h b/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h
index 2f582b28171996..830024033fc0e7 100644
--- a/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h
+++ b/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h
@@ -79,13 +79,13 @@
#if NXP_ICD_ENABLED
-#ifndef CHIP_CONFIG_ICD_IDLE_MODE_INTERVAL_SEC
-#define CHIP_CONFIG_ICD_IDLE_MODE_INTERVAL_SEC NXP_IDLE_MODE_INTERVAL
-#endif // CHIP_CONFIG_ICD_IDLE_MODE_INTERVAL_SEC
+#ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC
+#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_INTERVAL
+#endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC
-#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_INTERVAL_MS
-#define CHIP_CONFIG_ICD_ACTIVE_MODE_INTERVAL_MS NXP_ACTIVE_MODE_INTERVAL
-#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_INTERVAL_MS
+#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS
+#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_INTERVAL
+#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS
#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS
#define CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS NXP_ACTIVE_MODE_THRESHOLD
diff --git a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp
index df51c774712281..c595bf9cf31033 100644
--- a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp
@@ -39,22 +39,6 @@ FactoryDataProviderImpl::FactoryDataProviderImpl()
CHIP_ERROR FactoryDataProviderImpl::Init()
{
CHIP_ERROR error = CHIP_NO_ERROR;
- uint32_t sum = 0;
-
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
- ReturnErrorOnFailure(SetCustomIds());
-#endif
-
- for (uint8_t i = 1; i < FactoryDataProvider::kNumberOfIds; i++)
- {
- sum += maxLengths[i];
- }
-
- if (sum > kFactoryDataSize)
- {
- ChipLogError(DeviceLayer, "Max size of factory data: %lu is bigger than reserved factory data size: %lu", sum,
- kFactoryDataSize);
- }
#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR
error = ValidateWithRestore();
diff --git a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h b/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h
index f8d51573f6c488..b359a6d3f196cd 100644
--- a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h
+++ b/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h
@@ -24,7 +24,6 @@ namespace DeviceLayer {
/**
* This class provides K32W0 specific factory data features.
- * CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER - application defined factory data provider
* CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR - enables factory data OTA
*/
@@ -36,13 +35,6 @@ class FactoryDataProviderImpl : public FactoryDataProvider
CHIP_ERROR Init() override;
CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override;
-#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER
- virtual ~FactoryDataProviderImpl() {}
- // Custom factory data providers must implement this method in order to define
- // their own custom IDs.
- virtual CHIP_ERROR SetCustomIds() = 0;
-#endif
-
#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR
using RestoreMechanism = CHIP_ERROR (*)(void);
diff --git a/src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp b/src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp
index 5d98fc1f0c6b67..b01854c964296d 100644
--- a/src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp
+++ b/src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp
@@ -34,9 +34,6 @@
#include "app_dual_mode_low_power.h"
#include "app_dual_mode_switch.h"
#include "k32w0-chip-mbedtls-config.h"
-#include // nogncheck
-
-#include "app_config.h"
using namespace ::chip;
using namespace ::chip::Inet;
@@ -107,22 +104,6 @@ uint32_t dm_switch_get15_4InitWakeUpTime(void)
return dualModeStates.threadWarmBootInitTime;
}
-extern "C" bleResult_t App_PostCallbackMessage(appCallbackHandler_t handler, appCallbackParam_t param)
-{
- AppEvent event;
- event.Type = AppEvent::kEventType_Lp;
- event.Handler = handler;
- event.param = param;
-
-#if ENABLE_LOW_POWER_LOGS
- K32W_LOG("App_PostCallbackMessage %d", (uint32_t) param);
-#endif
-
- GetAppTask().PostEvent(&event);
-
- return gBleSuccess_c;
-}
-
WEAK void dm_switch_wakeupCallBack(void)
{
BOARD_SetClockForWakeup();
diff --git a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp b/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp
index 438623dbc97d2f..d40d2ae3c17f5a 100644
--- a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp
+++ b/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp
@@ -73,7 +73,8 @@ CHIP_ERROR OTAFactoryDataProcessor::ProcessInternal(ByteSpan & block)
CHIP_ERROR OTAFactoryDataProcessor::ApplyAction()
{
- CHIP_ERROR error = CHIP_NO_ERROR;
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ FactoryProvider * provider = nullptr;
ReturnErrorOnFailure(Read());
ReturnErrorOnFailure(Backup());
@@ -83,7 +84,16 @@ CHIP_ERROR OTAFactoryDataProcessor::ApplyAction()
SuccessOrExit(error = Update((uint8_t) Tags::kPaiCertificateId, mPayload.mCertPai));
SuccessOrExit(error = Update((uint8_t) Tags::kCertDeclarationId, mPayload.mCertDeclaration));
- error = FactoryProviderImpl::UpdateData(mFactoryData);
+ SuccessOrExit(error = FactoryProviderImpl::UpdateData(mFactoryData));
+
+ /* Check integrity of freshly copied data. If validation fails, OTA will be aborted
+ * and factory data will be restored to the previous version. Use device instance info
+ * provider getter to access the factory data provider instance. The instance is created
+ * by the application, so it's easier to access it this way.*/
+ provider = static_cast(DeviceLayer::GetDeviceInstanceInfoProvider());
+ SuccessOrExit(error = ((provider != nullptr) ? CHIP_NO_ERROR : CHIP_ERROR_INVALID_ADDRESS));
+
+ error = provider->Validate();
exit:
if (error != CHIP_NO_ERROR)
diff --git a/src/platform/nxp/k32w/k32w1/BUILD.gn b/src/platform/nxp/k32w/k32w1/BUILD.gn
index 187a7360cd27d2..8ad11928178bb7 100644
--- a/src/platform/nxp/k32w/k32w1/BUILD.gn
+++ b/src/platform/nxp/k32w/k32w1/BUILD.gn
@@ -58,6 +58,8 @@ static_library("k32w1") {
"ram_storage.h",
]
+ public = [ "${chip_root}/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h" ]
+
public_deps = [ "${chip_root}/src/platform:platform_base" ]
if (chip_with_low_power != 0) {
@@ -65,6 +67,8 @@ static_library("k32w1") {
}
if (chip_enable_ota_requestor) {
+ public += [ "../common/OTAImageProcessorImpl.h" ]
+
sources += [
"../common/OTAImageProcessorImpl.cpp",
"../common/OTAImageProcessorImpl.h",
diff --git a/src/test_driver/nrfconnect/main/include/app_mbedtls_config.h b/src/test_driver/nrfconnect/main/include/app_mbedtls_config.h
index c676d725837aea..b28420c41828e8 100644
--- a/src/test_driver/nrfconnect/main/include/app_mbedtls_config.h
+++ b/src/test_driver/nrfconnect/main/include/app_mbedtls_config.h
@@ -17,24 +17,7 @@
*/
// Enable cryptographic functions needed by CHIP which can't be enabled via Kconfig
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECDH_C
#define MBEDTLS_HKDF_C
-#define MBEDTLS_BIGNUM_C
-#define MBEDTLS_PKCS5_C
-#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_X509_CREATE_C
#define MBEDTLS_X509_CSR_PARSE_C
#define MBEDTLS_X509_CSR_WRITE_C
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_PEM_WRITE_C
-
-// Define mbedtls_error()
-#define MBEDTLS_ERROR_C
-
-// Use /dev/urandom as entropy generator
-#undef MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
-#undef MBEDTLS_NO_PLATFORM_ENTROPY
-
-// Configure heap usage monitoring
-#define MBEDTLS_MEMORY_DEBUG
diff --git a/src/test_driver/nrfconnect/prj.conf b/src/test_driver/nrfconnect/prj.conf
index 4a49d837a1d56a..8c9c4433d56086 100644
--- a/src/test_driver/nrfconnect/prj.conf
+++ b/src/test_driver/nrfconnect/prj.conf
@@ -17,60 +17,46 @@
# Application stack size
CONFIG_MAIN_STACK_SIZE=8704
-# Turn on the logger
+# Logging configuration
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
-# Set up IPv4/6 networking over BSD socket API
-CONFIG_NETWORKING=y
-CONFIG_NET_IPV6=y
-CONFIG_NET_UDP=y
-CONFIG_NET_SOCKETS=y
+# Zephyr networking configuration
CONFIG_NET_SOCKETS_POSIX_NAMES=n
-
CONFIG_NET_IPV4=y
-CONFIG_NET_CONFIG_NEED_IPV6=y
-CONFIG_NET_CONFIG_NEED_IPV4=y
-
CONFIG_ETH_NATIVE_POSIX=y
-
-# disable certain parts of Zephyr IPv6 stack
-CONFIG_NET_IPV6_NBR_CACHE=n
-CONFIG_NET_IPV6_MLD=n
-
-# Configure settings
-CONFIG_FLASH_SIMULATOR=y
-
-# Network buffers
CONFIG_NET_PKT_RX_COUNT=16
CONFIG_NET_PKT_TX_COUNT=16
CONFIG_NET_BUF_RX_COUNT=80
CONFIG_NET_BUF_TX_COUNT=80
CONFIG_NET_CONTEXT_NET_PKT_POOL=y
-
-# Thread by default registers quite a lot addresses.
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=8
-CONFIG_NET_MAX_CONTEXTS=10
-# mbedTLS tweaks
+# Configure settings
+CONFIG_FLASH_SIMULATOR=y
+
+# mbedTLS configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
-CONFIG_MBEDTLS_BUILTIN=y
-CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=768
CONFIG_MBEDTLS_HEAP_SIZE=65536
+CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=768
+CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y
+CONFIG_MBEDTLS_USER_CONFIG_FILE="app_mbedtls_config.h"
+CONFIG_MBEDTLS_ZEPHYR_ENTROPY=y
CONFIG_MBEDTLS_ENTROPY_ENABLED=y
CONFIG_MBEDTLS_CTR_DRBG_ENABLED=y
-CONFIG_MBEDTLS_CIPHER_MODE_CTR_ENABLED=y
+CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y
CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
-CONFIG_MBEDTLS_CFG_FILE="config-tls-generic.h"
-CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y
-CONFIG_MBEDTLS_USER_CONFIG_FILE="app_mbedtls_config.h"
CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
CONFIG_MBEDTLS_ECDH_C=y
CONFIG_MBEDTLS_ECDSA_C=y
CONFIG_MBEDTLS_ECP_C=y
-CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y
+CONFIG_MBEDTLS_PK_WRITE_C=y
+CONFIG_MBEDTLS_PKCS5_C=y
+CONFIG_MBEDTLS_PSA_CRYPTO_C=y
+CONFIG_MBEDTLS_MEMORY_DEBUG=y
+CONFIG_MBEDTLS_DEBUG=y
# Enable entropy
CONFIG_ENTROPY_GENERATOR=y
@@ -83,16 +69,14 @@ CONFIG_THREAD_NAME=y
CONFIG_INIT_STACKS=y
CONFIG_REBOOT=n
-# Build as C++14
+# Build as C++17
CONFIG_STD_CPP17=y
# CHIP configuration
CONFIG_CHIP=y
+CONFIG_CHIP_CRYPTO_PSA=y
CONFIG_CHIP_BUILD_TESTS=y
-CONFIG_CHIP_ENABLE_DNSSD_SRP=n
+CONFIG_CHIP_ENABLE_READ_CLIENT=y
CONFIG_CHIP_DEVICE_VENDOR_ID=65521
CONFIG_CHIP_DEVICE_PRODUCT_ID=32768
CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h"
-
-# Enable the Read Client
-CONFIG_CHIP_ENABLE_READ_CLIENT=y
diff --git a/third_party/libwebsockets/repo b/third_party/libwebsockets/repo
index f18fc2316f9743..49bfef2ecd51b8 160000
--- a/third_party/libwebsockets/repo
+++ b/third_party/libwebsockets/repo
@@ -1 +1 @@
-Subproject commit f18fc2316f9743624ced9ba934595f7b9ba8cd05
+Subproject commit 49bfef2ecd51b854b63e35d913849b6bb518a7f6
diff --git a/third_party/mbedtls/repo b/third_party/mbedtls/repo
index ffb18d2012909c..56fd26cee97531 160000
--- a/third_party/mbedtls/repo
+++ b/third_party/mbedtls/repo
@@ -1 +1 @@
-Subproject commit ffb18d2012909c05277a1e16dc6ba23dc8ba2854
+Subproject commit 56fd26cee97531f223071b91ed108dc1e22e7a85
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 bb8bea1d96e7f9..7f8664022616bb 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
@@ -9316,37 +9316,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
namespace BooleanStateConfiguration {
namespace Attributes {
-namespace CurrentSensitivityLevel {
-
-EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
-{
- using Traits = NumericAttributeTraits;
- Traits::StorageType temp;
- uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
- EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::BooleanStateConfiguration::Id, Id, readable, sizeof(temp));
- VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
- if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
- {
- return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
- }
- *value = Traits::StorageToWorking(temp);
- return status;
-}
-EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
-{
- using Traits = NumericAttributeTraits;
- if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
- {
- return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
- }
- Traits::StorageType storageValue;
- Traits::WorkingToStorage(value, storageValue);
- uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
- return emberAfWriteAttribute(endpoint, Clusters::BooleanStateConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
-}
-
-} // namespace CurrentSensitivityLevel
-
namespace SupportedSensitivityLevels {
EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
@@ -9792,59 +9761,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullabl
} // namespace AutoCloseTime
-namespace RemainingDuration {
-
-EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value)
-{
- using Traits = NumericAttributeTraits;
- Traits::StorageType temp;
- uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
- EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, readable, sizeof(temp));
- VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
- if (Traits::IsNullValue(temp))
- {
- value.SetNull();
- }
- else
- {
- value.SetNonNull() = Traits::StorageToWorking(temp);
- }
- return status;
-}
-EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
-{
- using Traits = NumericAttributeTraits;
- if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
- {
- return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
- }
- Traits::StorageType storageValue;
- Traits::WorkingToStorage(value, storageValue);
- uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
- return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
-}
-
-EmberAfStatus SetNull(chip::EndpointId endpoint)
-{
- using Traits = NumericAttributeTraits;
- Traits::StorageType value;
- Traits::SetNull(value);
- uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
- return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
-}
-
-EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value)
-{
- if (value.IsNull())
- {
- return SetNull(endpoint);
- }
-
- return Set(endpoint, value.Value());
-}
-
-} // namespace RemainingDuration
-
namespace CurrentState {
EmberAfStatus Get(chip::EndpointId endpoint,
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 8eac5af1be7ff0..c80c58fe04468c 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
@@ -1827,11 +1827,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value);
namespace BooleanStateConfiguration {
namespace Attributes {
-namespace CurrentSensitivityLevel {
-EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u
-EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value);
-} // namespace CurrentSensitivityLevel
-
namespace SupportedSensitivityLevels {
EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value);
@@ -1910,13 +1905,6 @@ EmberAfStatus SetNull(chip::EndpointId endpoint);
EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value);
} // namespace AutoCloseTime
-namespace RemainingDuration {
-EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // elapsed_s
-EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value);
-EmberAfStatus SetNull(chip::EndpointId endpoint);
-EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value);
-} // namespace RemainingDuration
-
namespace CurrentState {
EmberAfStatus Get(chip::EndpointId endpoint,
DataModel::Nullable & value); // ValveStateEnum
diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
index a69442a3e058a9..fcffb2ec55a525 100644
--- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
+++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
@@ -46111,7 +46111,7 @@ class Test_TC_CNET_1_3 : public TestCommandBridge {
{
id actualValue = value;
- VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 1U));
+ VerifyOrReturn(CheckValue("ClusterRevision", actualValue, 2U));
}
VerifyOrReturn(CheckConstraintType("clusterRevision", "int16u", "int16u"));