From d2c356cafabe0c4768f36a06ead21d8c570874f2 Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho <116586593+rquidute@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:37:35 -0300 Subject: [PATCH 01/70] Increase timeout in per_endpoint_runner (#35323) --- src/python_testing/matter_testing_support.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 9b5a30e326e4ce..ea937306cad925 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -2127,7 +2127,7 @@ def per_endpoint_test(accept_function: EndpointCheckFunction): def per_endpoint_test_internal(body): def per_endpoint_runner(self: MatterBaseTest, *args, **kwargs): asserts.assert_false(self.get_test_pics(self.current_test_info.name), "pics_ method supplied for per_endpoint_test.") - runner_with_timeout = asyncio.wait_for(get_accepted_endpoints_for_test(self, accept_function), timeout=30) + runner_with_timeout = asyncio.wait_for(get_accepted_endpoints_for_test(self, accept_function), timeout=60) endpoints = asyncio.run(runner_with_timeout) if not endpoints: logging.info("No matching endpoints found - skipping test") From 8da30ca70eff50ffa341c63251be10572b908e4f Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Mon, 2 Sep 2024 11:20:16 -0400 Subject: [PATCH 02/70] Fix crash in fabric-admin (#35353) * Fix crash in fabric-admin * Address nit comment --- .../fabric-admin/device_manager/DeviceSynchronization.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index adbe0c0213448d..0ca2e270826c9e 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -74,6 +74,12 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, VerifyOrDie(path.mEndpointId == kRootEndpointId); VerifyOrDie(path.mClusterId == Clusters::BasicInformation::Id); + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + switch (path.mAttributeId) { case Clusters::BasicInformation::Attributes::UniqueID::Id: From 51cb7163b4394723797931e60cd0ff52d8084ee2 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Mon, 2 Sep 2024 17:09:57 -0400 Subject: [PATCH 03/70] Fix remaining post-TE2 TC-SWTCH issues (#35291) * Fix remaining post-TE2 TC-SWTCH issues - Fixes #34556 (-2.2, -2.3 and -2.4 to better match test plan) - Fixes #28620 (Better bound checks) - Fixes #35241 * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Fix step 2 of TC-SWTCH--2.4 --------- Co-authored-by: Restyled.io --- .../linux/AllClustersCommandDelegate.cpp | 37 ++++++ src/python_testing/TC_SWTCH.py | 110 +++++++++++------- src/python_testing/matter_testing_support.py | 26 ++++- 3 files changed, 133 insertions(+), 40 deletions(-) diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index 6e5008a38685d8..0d665509407744 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -57,6 +57,17 @@ bool HasNumericField(Json::Value & jsonValue, const std::string & field) return jsonValue.isMember(field) && jsonValue[field].isNumeric(); } +uint8_t GetNumberOfSwitchPositions(EndpointId endpointId) +{ + // TODO: Move to using public API of cluster. + uint8_t numPositions = 0; + + // On failure, the numPositions won't be changed, so 0 returned. + (void) Switch::Attributes::NumberOfPositions::Get(endpointId, &numPositions); + + return numPositions; +} + /** * Named pipe handler for simulated long press * @@ -99,6 +110,15 @@ void HandleSimulateLongPress(Json::Value & jsonValue) EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); uint8_t buttonId = static_cast(jsonValue["ButtonId"].asUInt()); + + uint8_t numPositions = GetNumberOfSwitchPositions(endpointId); + if (buttonId >= numPositions) + { + std::string inputJson = jsonValue.toStyledString(); + ChipLogError(NotSpecified, "Invalid ButtonId (out of range) in %s", inputJson.c_str()); + return; + } + System::Clock::Milliseconds32 longPressDelayMillis{ static_cast(jsonValue["LongPressDelayMillis"].asUInt()) }; System::Clock::Milliseconds32 longPressDurationMillis{ static_cast(jsonValue["LongPressDurationMillis"].asUInt()) }; uint32_t featureMap = static_cast(jsonValue["FeatureMap"].asUInt()); @@ -169,6 +189,15 @@ void HandleSimulateMultiPress(Json::Value & jsonValue) EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); uint8_t buttonId = static_cast(jsonValue["ButtonId"].asUInt()); + + uint8_t numPositions = GetNumberOfSwitchPositions(endpointId); + if (buttonId >= numPositions) + { + std::string inputJson = jsonValue.toStyledString(); + ChipLogError(NotSpecified, "Invalid ButtonId (out of range) in %s", inputJson.c_str()); + return; + } + System::Clock::Milliseconds32 multiPressPressedTimeMillis{ static_cast( jsonValue["MultiPressPressedTimeMillis"].asUInt()) }; System::Clock::Milliseconds32 multiPressReleasedTimeMillis{ static_cast( @@ -227,6 +256,14 @@ void HandleSimulateLatchPosition(Json::Value & jsonValue) EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); uint8_t positionId = static_cast(jsonValue["PositionId"].asUInt()); + uint8_t numPositions = GetNumberOfSwitchPositions(endpointId); + if (positionId >= numPositions) + { + std::string inputJson = jsonValue.toStyledString(); + ChipLogError(NotSpecified, "Invalid PositionId (out of range) in %s", inputJson.c_str()); + return; + } + uint8_t previousPositionId = 0; Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Get(endpointId, &previousPositionId); VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, diff --git a/src/python_testing/TC_SWTCH.py b/src/python_testing/TC_SWTCH.py index 1001402ea2d2de..3db2b213428b39 100644 --- a/src/python_testing/TC_SWTCH.py +++ b/src/python_testing/TC_SWTCH.py @@ -38,8 +38,8 @@ from chip.clusters import ClusterObjects as ClusterObjects from chip.clusters.Attribute import EventReadResult from chip.tlv import uint -from matter_testing_support import (ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, TestStep, - await_sequence_of_reports, default_matter_test_main, has_feature, per_endpoint_test) +from matter_testing_support import (AttributeValue, ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, + TestStep, await_sequence_of_reports, default_matter_test_main, has_feature, per_endpoint_test) from mobly import asserts logger = logging.getLogger(__name__) @@ -70,6 +70,10 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._default_pressed_position = self.user_params.get("default_pressed_position", 1) + def setup_test(self): + super().setup_test() + self.is_ci = self._use_button_simulator() + def _send_named_pipe_command(self, command_dict: dict[str, Any]): app_pid = self.matter_test_config.app_pid if app_pid == 0: @@ -259,32 +263,39 @@ def _received_event(self, event_listener: EventChangeCallback, target_event: Clu def steps_TC_SWTCH_2_2(self): return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), - TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), + TestStep(2, "Set up subscription to all events and attributes of Switch cluster on the endpoint"), TestStep(3, "Operator sets switch to first position on the DUT"), - TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(4, "TH reads the CurrentPosition attribute from the DUT.", "Verify that the value is 0."), TestStep(5, "Operator sets switch to second position (one) on the DUT", - "Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT"), - TestStep(6, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1"), + "Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT."), + TestStep(6, "TH reads the CurrentPosition attribute from the DUT", + "Verify that the value is 1, and that a subscription report was received for that change."), TestStep(7, "If there are more than 2 positions, test subsequent positions of the DUT"), TestStep(8, "Operator sets switch to first position on the DUT."), TestStep(9, "Wait 10 seconds for event reports stable." "Verify that last SwitchLatched event received is for NewPosition 0."), - TestStep(10, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(10, "TH reads the CurrentPosition attribute from the DUT", + "Verify that the value is 0, and that a subscription report was received for that change."), ] @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kLatchingSwitch)) async def test_TC_SWTCH_2_2(self): post_prompt_settle_delay_seconds = 10.0 + cluster = Clusters.Switch + endpoint_id = self.matter_test_config.endpoint # Step 1: Commissioning - already done self.step(1) - cluster = Clusters.Switch - endpoint_id = self.matter_test_config.endpoint - # Step 2: Set up subscription to all events of Switch cluster on the endpoint. self.step(2) event_listener = EventChangeCallback(cluster) await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + attrib_listener = ClusterAttributeChangeAccumulator(cluster) + await attrib_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + # Pre-get number of positions for step 7 later. + num_positions = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.NumberOfPositions) + asserts.assert_greater(num_positions, 1, "Latching switch has only 1 position, this is impossible.") # Step 3: Operator sets switch to first position on the DUT. self.step(3) @@ -296,25 +307,39 @@ async def test_TC_SWTCH_2_2(self): button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) asserts.assert_equal(button_val, 0, "Switch position value is not 0") - # Step 5: Operator sets switch to second position (one) on the DUT", - # Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT - self.step(5) - expected_switch_position = 1 - self._ask_for_switch_position(endpoint_id, expected_switch_position) - - data = event_listener.wait_for_event_report(cluster.Events.SwitchLatched, timeout_sec=post_prompt_settle_delay_seconds) - logging.info(f"-> SwitchLatched event last received: {data}") - asserts.assert_equal(data, cluster.Events.SwitchLatched( - newPosition=expected_switch_position), "Did not get expected switch position") - - # Step 6: TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1 - self.step(6) - button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) - asserts.assert_equal(button_val, expected_switch_position, f"Switch position is not {expected_switch_position}") - - # Step 7: If there are more than 2 positions, test subsequent positions of the DUT - # # TODO(#34656): Implement loop for > 2 total positions - self.skip_step(7) + attrib_listener.reset() + event_listener.reset() + + for expected_switch_position in range(1, num_positions): + # Step 5: Operator sets switch to second position (one) on the DUT", + # Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT + if expected_switch_position == 1: + self.step(5) + self._ask_for_switch_position(endpoint_id, expected_switch_position) + + data = event_listener.wait_for_event_report(cluster.Events.SwitchLatched, timeout_sec=post_prompt_settle_delay_seconds) + logging.info(f"-> SwitchLatched event last received: {data}") + asserts.assert_equal(data, cluster.Events.SwitchLatched( + newPosition=expected_switch_position), "Did not get expected switch position") + + # Step 6: TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1 + if expected_switch_position == 1: # Indicate step 7 only once + self.step(6) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(button_val, expected_switch_position, f"Switch position is not {expected_switch_position}") + logging.info(f"Checking to see if a report for {expected_switch_position} is received") + attrib_listener.await_sequence_of_reports(attribute=cluster.Attributes.CurrentPosition, sequence=[ + expected_switch_position], timeout_sec=post_prompt_settle_delay_seconds) + + # Step 7: If there are more than 2 positions, test subsequent positions of the DUT + if expected_switch_position == 1: + if num_positions > 2: # Indicate step 7 only once + self.step(7) + else: + self.skip_step(7) + + if num_positions > 2: + logging.info("Looping for the other positions") # Step 8: Operator sets switch to first position on the DUT. self.step(8) @@ -324,7 +349,7 @@ async def test_TC_SWTCH_2_2(self): # Step 9: Wait 10 seconds for event reports stable. # Verify that last SwitchLatched event received is for NewPosition 0. self.step(9) - time.sleep(10.0) + time.sleep(10.0 if not self.is_ci else 1.0) expected_switch_position = 0 last_event = event_listener.get_last_event() @@ -337,15 +362,21 @@ async def test_TC_SWTCH_2_2(self): # Step 10: TH reads the CurrentPosition attribute from the DUT. # Verify that the value is 0 self.step(10) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) asserts.assert_equal(button_val, 0, "Button value is not 0") + logging.info(f"Checking to see if a report for {expected_switch_position} is received") + expected_final_value = [AttributeValue( + endpoint_id, attribute=cluster.Attributes.CurrentPosition, value=expected_switch_position)] + attrib_listener.await_all_final_values_reported(expected_final_value, timeout_sec=post_prompt_settle_delay_seconds) + def steps_TC_SWTCH_2_3(self): return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), TestStep(3, "Operator does not operate switch on the DUT"), TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), - TestStep(5, "Operator operates switch (keep it pressed)", + TestStep(5, "Operator operates switch (keep it pressed, and wait at least 5 seconds)", "Verify that the TH receives InitialPress event with NewPosition set to 1 on the DUT"), TestStep(6, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1"), TestStep(7, "Operator releases switch on the DUT"), @@ -421,15 +452,15 @@ def desc_TC_SWTCH_2_4(self) -> str: def steps_TC_SWTCH_2_4(self): return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), - TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), + TestStep(2, "Set up subscription to all events and attributes of Switch cluster on the endpoint"), TestStep(3, "Operator does not operate switch on the DUT"), TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), - TestStep(5, "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it", + TestStep(5, "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, then release it", """ * TH expects receiving a subscription report of CurrentPosition 1, followed by a report of Current Position 0. * TH expects receiving at InitialPress event with NewPosition = 1. - * if MSL or AS feature is supported, TH expect receiving LongPress/LongRelease in that order. - * if MS & (!MSL & !AS & !MSR) features present, TH expects receiving no further events for 10 seconds after release. + * if MSL feature is supported, TH expect receiving LongPress/LongRelease in that order. + * if MS & (!MSL & !AS & !MSR & !MSM) features present, TH expects receiving no further events for 10 seconds after release. * if (MSR & !MSL) features present, TH expects receiving ShortRelease event. """) ] @@ -451,17 +482,18 @@ async def test_TC_SWTCH_2_4(self): has_ms_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitch) != 0 has_msr_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchRelease) != 0 has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) != 0 + has_msm_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchMultiPress) != 0 has_as_feature = (feature_map & cluster.Bitmaps.Feature.kActionSwitch) != 0 if not has_ms_feature: logging.info("Skipping rest of test: SWTCH.S.F01(MS) feature not present") self.skip_all_remaining_steps("2") - # Step 2: Set up subscription to all events of Switch cluster on the endpoint + # Step 2: Set up subscription to all events and attributes of Switch cluster on the endpoint self.step(2) event_listener = EventChangeCallback(cluster) - attrib_listener = ClusterAttributeChangeAccumulator(cluster) await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + attrib_listener = ClusterAttributeChangeAccumulator(cluster) await attrib_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) # Step 3: Operator does not operate switch on the DUT @@ -503,8 +535,8 @@ async def test_TC_SWTCH_2_4(self): self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) - # - if MS & (!MSL & !AS & !MSR) features present, expect no further events for 10 seconds after release. - if not has_msl_feature and not has_as_feature and not has_msr_feature: + # - if MS & (!MSL & !AS & !MSR & !MSM) features present, expect no further events for 10 seconds after release. + if not has_msl_feature and not has_as_feature and not has_msr_feature and not has_msm_feature: self._expect_no_events_for_cluster(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, expected_cluster=cluster, timeout_sec=10.0) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index ea937306cad925..1e0fa26ae8d722 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -301,6 +301,10 @@ def flush_events(self) -> None: _ = self.get_last_event() return + def reset(self) -> None: + """Resets state as if no events had ever been received.""" + self.flush_events() + @property def event_queue(self) -> queue.Queue: return self._q @@ -356,7 +360,7 @@ class AttributeValue: timestamp_utc: Optional[datetime] = None -def await_sequence_of_reports(report_queue: queue.Queue, endpoint_id: int, attribute: TypedAttributePath, sequence: list[Any], timeout_sec: float): +def await_sequence_of_reports(report_queue: queue.Queue, endpoint_id: int, attribute: TypedAttributePath, sequence: list[Any], timeout_sec: float) -> None: """Given a queue.Queue hooked-up to an attribute change accumulator, await a given expected sequence of attribute reports. Args: @@ -418,6 +422,7 @@ def __init__(self, expected_cluster: ClusterObjects.Cluster): self._subscription = None self._lock = threading.Lock() self._q = queue.Queue() + self._endpoint_id = 0 self.reset() def reset(self): @@ -441,6 +446,7 @@ async def start(self, dev_ctrl, node_id: int, endpoint: int, fabric_filtered: bo fabricFiltered=fabric_filtered, keepSubscriptions=keepSubscriptions ) + self._endpoint_id = endpoint self._subscription.SetAttributeUpdateCallback(self.__call__) return self._subscription @@ -513,6 +519,24 @@ def await_all_final_values_reported(self, expected_final_values: Iterable[Attrib logging.info(f" -> {expected_element} found: {last_report_matches.get(expected_idx)}") asserts.fail("Did not find all expected last report values before time-out") + def await_sequence_of_reports(self, attribute: TypedAttributePath, sequence: list[Any], timeout_sec: float) -> None: + """Await a given expected sequence of attribute reports in the accumulator for the endpoint associated. + + Args: + - attribute: attribute to match for reports to check. + - sequence: list of attribute values in order that are expected. + - timeout_sec: number of seconds to wait for. + + *** WARNING: The queue contains every report since the sub was established. Use + self.reset() to make it empty. *** + + This will fail current Mobly test with assertion failure if the data is not as expected in order. + + Returns nothing on success so the test can go on. + """ + await_sequence_of_reports(report_queue=self.attribute_queue, endpoint_id=self._endpoint_id, + attribute=attribute, sequence=sequence, timeout_sec=timeout_sec) + @property def attribute_queue(self) -> queue.Queue: return self._q From 1d7477934bbfaaaba3556d60a617c071830acf42 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 2 Sep 2024 14:54:04 -0700 Subject: [PATCH 04/70] Remove duplicated attribute read override mechnism (#35359) --- .../fabric-bridge-common/BUILD.gn | 1 - .../src/BridgedDeviceManager.cpp | 3 ++ .../fabric-bridge-common/src/ZCLCallbacks.cpp | 50 ------------------- 3 files changed, 3 insertions(+), 51 deletions(-) delete mode 100644 examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp diff --git a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 157032f8f93c19..3db4f1ebb13425 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -50,7 +50,6 @@ source_set("fabric-bridge-lib") { "src/BridgedDevice.cpp", "src/BridgedDeviceBasicInformationImpl.cpp", "src/BridgedDeviceManager.cpp", - "src/ZCLCallbacks.cpp", ] deps = [ diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index 5caa4459bf1d1e..7101918f9f5385 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -58,6 +58,8 @@ constexpr int kSoftwareVersionSize = 64; // Current ZCL implementation of Struct uses a max-size array of 254 bytes constexpr int kDescriptorAttributeArraySize = 254; +#define ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION (1u) + // ENDPOINT DEFINITIONS: // ================================================================================= // @@ -125,6 +127,7 @@ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(AdministratorCommissioningAttrs) DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1, 0), DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminFabricIndex::Id, FABRIC_IDX, 1, 0), DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminVendorId::Id, VENDOR_ID, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::ClusterRevision::Id, INT16U, ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION, 0), DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); // clang-format on diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp deleted file mode 100644 index d4da982cfa45a5..00000000000000 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2024 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BridgedDeviceManager.h" - -#include -#include -#include -#include - -using namespace ::chip; -using namespace ::chip::app::Clusters; - -#define ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION (1u) - -// External attribute read callback function -Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength) -{ - if (clusterId == AdministratorCommissioning::Id) - { - // TODO(#34791) This is a workaround to prevent crash. CADMIN is still reading incorrect - // Attribute values on dynamic endpoint as it only reads the root node and not the actual bridge - // device we are representing here, when addressing the issue over there we can more easily - // resolve this workaround. - if ((attributeMetadata->attributeId == AdministratorCommissioning::Attributes::ClusterRevision::Id) && (maxReadLength == 2)) - { - uint16_t rev = ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION; - memcpy(buffer, &rev, sizeof(rev)); - return Protocols::InteractionModel::Status::Success; - } - } - - return Protocols::InteractionModel::Status::Failure; -} From c552dda703424acbc1485cdf9c03769f67bcd99b Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk <66371704+kkasperczyk-no@users.noreply.github.com> Date: Tue, 3 Sep 2024 08:41:22 +0200 Subject: [PATCH 05/70] [icd] Introduced define to configure the slow poll limit for SIT (#35350) The slow poll interval limit for SIT is by spec set to 15 s. This value is used for LIT device working as a SIT, but in some cases it could be beneficial to be able to change this limit to the smaller value. --- config/nrfconnect/chip-module/CMakeLists.txt | 1 + config/zephyr/Kconfig | 9 +++++++++ src/app/icd/server/ICDConfigurationData.h | 4 +++- src/include/platform/CHIPDeviceConfig.h | 13 +++++++++++++ src/platform/nrfconnect/CHIPDevicePlatformConfig.h | 6 ++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 20c5c692b68633..ee169106ffc8f9 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -147,6 +147,7 @@ if (CONFIG_CHIP_ENABLE_ICD_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_lit" CONFIG_CHIP_ICD_LIT_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_checkin" CONFIG_CHIP_ICD_CHECK_IN_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_user_active_mode_trigger" CONFIG_CHIP_ICD_UAT_SUPPORT) + matter_add_gn_arg_bool ("icd_enforce_sit_slow_poll_limit" TRUE) endif() if (CONFIG_CHIP_FACTORY_DATA OR CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index fb06e106e29a38..62efe30c07fda4 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -354,6 +354,15 @@ config CHIP_ICD_SLOW_POLL_INTERVAL device is in the idle mode. It determines the fastest frequency at which the device will be able to receive the messages in the idle mode. +config CHIP_ICD_SIT_SLOW_POLL_LIMIT + int "Intermittently Connected Device slow polling interval limit for device in SIT mode (ms)" + default 15000 + range 0 15000 + help + Provides the limit for Intermittently Connected Device slow polling interval in milliseconds while the + device is in the SIT mode. By spec, this value cannot exceed 15 s (spec 9.16.1.5). This value can be + used for the LIT device, to limit the slow poll interval used while temporarily working in the SIT mode. + config CHIP_ICD_FAST_POLLING_INTERVAL int "Intermittently Connected Device fast polling interval (ms)" default 200 diff --git a/src/app/icd/server/ICDConfigurationData.h b/src/app/icd/server/ICDConfigurationData.h index 937b08b99e0e45..0d6e17e55efca2 100644 --- a/src/app/icd/server/ICDConfigurationData.h +++ b/src/app/icd/server/ICDConfigurationData.h @@ -159,7 +159,9 @@ class ICDConfigurationData System::Clock::Seconds32 mMaximumCheckInBackOff = System::Clock::Seconds32(CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC); // SIT ICDs should have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) - static constexpr System::Clock::Milliseconds32 kSITPollingThreshold = System::Clock::Milliseconds32(15000); + static_assert((CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT).count() <= 15000, + "Spec requires the maximum slow poll interval for the SIT device to be smaller or equal than 15 s."); + static constexpr System::Clock::Milliseconds32 kSITPollingThreshold = CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT; System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; System::Clock::Milliseconds32 mFastPollingInterval = CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL; diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index bc13696c8c36a2..f4b5fbdc41789c 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -146,6 +146,19 @@ #define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL System::Clock::Milliseconds32(5000) #endif +/** + * CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT + * + * The maximum value of time in milliseconds that the sleepy end device can use as an idle interval in the SIT mode. + * The Matter spec does not allow this value to exceed 15s (spec 9.16.1.5). + * For the SIT device, the usability of this value is arguable, as slow poll interval can be configured using + * CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL. This value can be used for the LIT device, to limit the slow poll interval used while + * temporarily working in the SIT mode. + */ +#ifndef CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT +#define CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT System::Clock::Milliseconds32(15000) +#endif + /** * CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL * diff --git a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h index d0d31252f99368..c05dfb11845605 100644 --- a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h +++ b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h @@ -221,6 +221,12 @@ #endif // CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL #endif // CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL +#ifndef CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT +#ifdef CONFIG_CHIP_ICD_SIT_SLOW_POLL_LIMIT +#define CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT chip::System::Clock::Milliseconds32(CONFIG_CHIP_ICD_SIT_SLOW_POLL_LIMIT) +#endif // CONFIG_CHIP_ICD_SIT_SLOW_POLL_LIMIT +#endif // CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT + #ifndef CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL #ifdef CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL) From 57c9f4960e7de1875edf28ed698de1fac96445cb Mon Sep 17 00:00:00 2001 From: tianrking Date: Tue, 3 Sep 2024 19:26:10 +0800 Subject: [PATCH 06/70] Update setup_idf_chip.md (#34664) * Update setup_idf_chip.md * Update setup_idf_chip.md --- docs/guides/esp32/setup_idf_chip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/esp32/setup_idf_chip.md b/docs/guides/esp32/setup_idf_chip.md index 035964bdfab1b5..ae507631e463f5 100644 --- a/docs/guides/esp32/setup_idf_chip.md +++ b/docs/guides/esp32/setup_idf_chip.md @@ -16,7 +16,7 @@ step. - [Linux](https://docs.espressif.com/projects/esp-idf/en/v5.3/esp32/get-started/linux-macos-setup.html#for-linux-users) - [macOS](https://docs.espressif.com/projects/esp-idf/en/v5.3/esp32/get-started/linux-macos-setup.html#for-macos-users) -### Get IDF v5.1.2 +### Get ESP-IDF v5.3 - Clone ESP-IDF [v5.3 release](https://github.com/espressif/esp-idf/releases/tag/v5.3 From 30bc3259549e984769049a6a864c219c98d296d3 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:30:55 +1200 Subject: [PATCH 07/70] Add TBRM cluster to placeholder app1 (#35362) Fixes #35330 --- examples/placeholder/linux/apps/app1/BUILD.gn | 1 + .../placeholder/linux/apps/app1/config.matter | 65 +++++ .../placeholder/linux/apps/app1/config.zap | 245 ++++++++++++++++++ .../linux/thread-border-router-management.cpp | 85 ++++++ 4 files changed, 396 insertions(+) create mode 100644 examples/placeholder/linux/thread-border-router-management.cpp diff --git a/examples/placeholder/linux/apps/app1/BUILD.gn b/examples/placeholder/linux/apps/app1/BUILD.gn index f16b9301ce3a90..aba1e870f7a041 100644 --- a/examples/placeholder/linux/apps/app1/BUILD.gn +++ b/examples/placeholder/linux/apps/app1/BUILD.gn @@ -30,6 +30,7 @@ source_set("app1") { "../../resource-monitoring-delegates.cpp", "../../src/bridged-actions-stub.cpp", "../../static-supported-modes-manager.cpp", + "../../thread-border-router-management.cpp", ] public_deps = [ ":configuration" ] diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index a92f0a495885f3..96c3b7220841be 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -6716,6 +6716,50 @@ cluster OccupancySensing = 1030 { readonly attribute int16u clusterRevision = 65533; } +/** Manage the Thread network of Thread Border Router */ +provisional cluster ThreadBorderRouterManagement = 1106 { + revision 1; + + bitmap Feature : bitmap32 { + kPANChange = 0x1; + } + + provisional readonly attribute char_string<63> borderRouterName = 0; + provisional readonly attribute octet_string<254> borderAgentID = 1; + provisional readonly attribute int16u threadVersion = 2; + provisional readonly attribute boolean interfaceEnabled = 3; + provisional readonly attribute nullable int64u activeDatasetTimestamp = 4; + provisional readonly attribute nullable int64u pendingDatasetTimestamp = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + response struct DatasetResponse = 2 { + octet_string<254> dataset = 0; + } + + request struct SetActiveDatasetRequestRequest { + octet_string<254> activeDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct SetPendingDatasetRequestRequest { + octet_string<254> pendingDataset = 0; + } + + /** Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetActiveDatasetRequest(): DatasetResponse = 0; + /** Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; + /** Command to set or update the active Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; + /** Command set or update the pending Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; +} + /** This cluster provides an interface for controlling the current Channel on a device. */ cluster Channel = 1284 { revision 2; @@ -9619,6 +9663,27 @@ endpoint 1 { callback attribute featureMap; callback attribute clusterRevision default = 5; } + + server cluster ThreadBorderRouterManagement { + callback attribute borderRouterName; + callback attribute borderAgentID; + callback attribute threadVersion; + callback attribute interfaceEnabled; + callback attribute activeDatasetTimestamp; + callback attribute pendingDatasetTimestamp; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command GetActiveDatasetRequest; + handle command GetPendingDatasetRequest; + handle command DatasetResponse; + handle command SetActiveDatasetRequest; + handle command SetPendingDatasetRequest; + } } diff --git a/examples/placeholder/linux/apps/app1/config.zap b/examples/placeholder/linux/apps/app1/config.zap index d7cad4f031e5c3..21f2a00eb50e9b 100644 --- a/examples/placeholder/linux/apps/app1/config.zap +++ b/examples/placeholder/linux/apps/app1/config.zap @@ -15107,6 +15107,251 @@ "reportableChange": 0 } ] + }, + { + "name": "Thread Border Router Management", + "code": 1106, + "mfgCode": null, + "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "GetActiveDatasetRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetPendingDatasetRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DatasetResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetActiveDatasetRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetPendingDatasetRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BorderRouterName", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BorderAgentID", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveDatasetTimestamp", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PendingDatasetTimestamp", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] } ] } diff --git a/examples/placeholder/linux/thread-border-router-management.cpp b/examples/placeholder/linux/thread-border-router-management.cpp new file mode 100644 index 00000000000000..3ab7dbd707567f --- /dev/null +++ b/examples/placeholder/linux/thread-border-router-management.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip; +using namespace chip::literals; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +class FakeBorderRouterDelegate final : public ThreadBorderRouterManagement::Delegate +{ + CHIP_ERROR Init(AttributeChangeCallback * attributeChangeCallback) override { return CHIP_NO_ERROR; } + + bool GetPanChangeSupported() override { return true; } + + void GetBorderRouterName(MutableCharSpan & borderRouterName) override + { + CopyCharSpanToMutableCharSpan("netman-br"_span, borderRouterName); + } + + CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) override + { + static constexpr uint8_t kBorderAgentId[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + VerifyOrReturnError(borderAgentId.size() == 16, CHIP_ERROR_INVALID_ARGUMENT); + return CopySpanToMutableSpan(ByteSpan(kBorderAgentId), borderAgentId); + } + + uint16_t GetThreadVersion() override { return /* Thread 1.3.1 */ 5; } + + bool GetInterfaceEnabled() override { return false; } + + CHIP_ERROR GetDataset(Thread::OperationalDataset & dataset, DatasetType type) override { return CHIP_ERROR_NOT_FOUND; } + + void SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNum, + ActivateDatasetCallback * callback) override + { + ChipLogAutomation("SetActiveDataset"); + callback->OnActivateDatasetComplete(sequenceNum, CHIP_NO_ERROR); + } + + CHIP_ERROR CommitActiveDataset() override { return CHIP_NO_ERROR; } + CHIP_ERROR RevertActiveDataset() override { return CHIP_NO_ERROR; } + + CHIP_ERROR SetPendingDataset(const Thread::OperationalDataset & pendingDataset) override + { + ChipLogAutomation("SetPendingDataset"); + return CHIP_NO_ERROR; + } +}; + +FakeBorderRouterDelegate gBorderRouterDelegate{}; +} // namespace + +std::optional gThreadBorderRouterManagementServer; +void emberAfThreadBorderRouterManagementClusterInitCallback(EndpointId endpoint) +{ + VerifyOrDie(!gThreadBorderRouterManagementServer); + gThreadBorderRouterManagementServer.emplace(endpoint, &gBorderRouterDelegate, Server::GetInstance().GetFailSafeContext()) + .Init(); +} From e2b5d7a185121b6716bb47f721d5fdaacc2541f8 Mon Sep 17 00:00:00 2001 From: William Date: Tue, 3 Sep 2024 12:34:35 +0100 Subject: [PATCH 08/70] Enabled SEAR tests in CI. (#35326) --- src/python_testing/TC_SEAR_1_3.py | 2 +- src/python_testing/execute_python_tests.py | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/python_testing/TC_SEAR_1_3.py b/src/python_testing/TC_SEAR_1_3.py index 80b6404bd1bd19..df4a1ddb5123ba 100644 --- a/src/python_testing/TC_SEAR_1_3.py +++ b/src/python_testing/TC_SEAR_1_3.py @@ -25,7 +25,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --json-arg PIXIT.SEAR.VALID_AREAS:'[7, 1234567]' --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/execute_python_tests.py b/src/python_testing/execute_python_tests.py index 7e7d7d501e81b2..8249be9b7c8ef3 100644 --- a/src/python_testing/execute_python_tests.py +++ b/src/python_testing/execute_python_tests.py @@ -79,11 +79,6 @@ def main(search_directory, env_file): "TC_OCC_3_1.py", "TC_OCC_3_2.py", "TC_BRBINFO_4_1.py", - "TC_SEAR_1_2.py", - "TC_SEAR_1_3.py", - "TC_SEAR_1_4.py", - "TC_SEAR_1_5.py", - "TC_SEAR_1_6.py", "TestCommissioningTimeSync.py", "TestConformanceSupport.py", "TestChoiceConformanceSupport.py", From 76491d9904809b9dbb0cffb0d9cf84e5e1dd2d4b Mon Sep 17 00:00:00 2001 From: chirag-silabs <100861685+chirag-silabs@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:06:42 +0530 Subject: [PATCH 09/70] [Silabs] Moving to CMSIS OS and fixing task priorities (#35289) * moving to cmsis os and correcting the priority of all tasks * fixing the build for rs9116 * merging the wfx_rsi_host.cpp files * fixing the build of efr32 * fixing the build for the rs9116 * removing commented code and adding comments * Restyled by whitespace * Restyled by clang-format * fixing rs9116 and removing the unused code * Restyled by clang-format * renaming drv_task to drv_thread * Update src/platform/silabs/rs911x/BLEManagerImpl.cpp Co-authored-by: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> * Update src/platform/silabs/efr32/BLEManagerImpl.cpp Co-authored-by: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> * moving rsi_if.c to cpp * removing the osThread from the struct and adding them to there owner file * Restyled by clang-format * adding a length check compare for the scan * Restyled by clang-format * fixing the build --------- Co-authored-by: Restyled.io Co-authored-by: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> --- examples/platform/silabs/SiWx917/BUILD.gn | 2 +- .../silabs/SiWx917/SiWx917/sl_wifi_if.cpp | 12 +- .../platform/silabs/efr32/rs911x/rs9117.gni | 2 +- .../platform/silabs/efr32/rs911x/rs911x.gni | 4 +- .../efr32/rs911x/{rsi_if.c => rsi_if.cpp} | 95 ++-- .../silabs/efr32/rs911x/wfx_rsi_host.cpp | 429 ------------------ examples/platform/silabs/uart.cpp | 8 +- examples/platform/silabs/wfx_rsi.h | 16 +- .../SiWx917 => wifi}/wfx_rsi_host.cpp | 52 ++- src/platform/silabs/BLEManagerImpl.h | 2 +- src/platform/silabs/efr32/BLEManagerImpl.cpp | 25 +- src/platform/silabs/rs911x/BLEManagerImpl.cpp | 52 +-- 12 files changed, 149 insertions(+), 550 deletions(-) rename examples/platform/silabs/efr32/rs911x/{rsi_if.c => rsi_if.cpp} (93%) delete mode 100644 examples/platform/silabs/efr32/rs911x/wfx_rsi_host.cpp rename examples/platform/silabs/{SiWx917/SiWx917 => wifi}/wfx_rsi_host.cpp (89%) diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 2780e2ecbcc16e..f2ddfd59a4347c 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -192,11 +192,11 @@ source_set("siwx917-common") { "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", "${silabs_common_plat_dir}/wifi/wfx_notify.cpp", + "${silabs_common_plat_dir}/wifi/wfx_rsi_host.cpp", "${silabs_plat_si91x_wifi_dir}/dhcp_client.cpp", "${silabs_plat_si91x_wifi_dir}/ethernetif.cpp", "${silabs_plat_si91x_wifi_dir}/lwip_netif.cpp", "SiWx917/sl_wifi_if.cpp", - "SiWx917/wfx_rsi_host.cpp", ] if (chip_enable_pw_rpc || chip_build_libshell || sl_uart_log_output) { diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp index 92d5ca4808195c..ad3e15f6715c43 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp @@ -90,10 +90,11 @@ bool ps_requirement_added = false; // TODO: Figure out why we actually need this, we are already handling failure and retries somewhere else. #define WIFI_SCAN_TIMEOUT_TICK 10000 -WfxRsi_t wfx_rsi; +#if !defined(MIN) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif -/* Declare a variable to hold the data associated with the created event group. */ -StaticEventGroup_t rsiDriverEventGroup; +WfxRsi_t wfx_rsi; bool hasNotifiedIPV6 = false; #if (CHIP_DEVICE_CONFIG_ENABLE_IPV4) @@ -451,7 +452,6 @@ static sl_status_t wfx_rsi_init(void) } #endif // SL_MBEDTLS_USE_TINYCRYPT - wfx_rsi.events = xEventGroupCreateStatic(&rsiDriverEventGroup); wfx_rsi.dev_state |= WFX_RSI_ST_DEV_READY; osSemaphoreRelease(sl_rs_ble_init_sem); return status; @@ -537,7 +537,9 @@ sl_status_t show_scan_results(sl_wifi_scan_result_t * scan_result) strncpy(cur_scan_result.ssid, (char *) &scan_result->scan_info[idx].ssid, WFX_MAX_SSID_LENGTH); // if user has provided ssid, then check if the current scan result ssid matches the user provided ssid - if (wfx_rsi.scan_ssid != NULL && strcmp(wfx_rsi.scan_ssid, cur_scan_result.ssid) != CMP_SUCCESS) + if (wfx_rsi.scan_ssid != NULL && + (strncmp(wfx_rsi.scan_ssid, cur_scan_result.ssid, MIN(strlen(wfx_rsi.scan_ssid), strlen(cur_scan_result.ssid))) == + CMP_SUCCESS)) { continue; } diff --git a/examples/platform/silabs/efr32/rs911x/rs9117.gni b/examples/platform/silabs/efr32/rs911x/rs9117.gni index 356b72f55f75d4..cff3e3da1fea8c 100644 --- a/examples/platform/silabs/efr32/rs911x/rs9117.gni +++ b/examples/platform/silabs/efr32/rs911x/rs9117.gni @@ -4,11 +4,11 @@ import("${efr32_sdk_build_root}/efr32_sdk.gni") rs911x_src_plat = [ "${examples_plat_dir}/rs911x/sl_wifi_if.cpp", - "${examples_plat_dir}/rs911x/wfx_rsi_host.cpp", "${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_interrupt.c", "${examples_plat_dir}/rs911x/hal/sl_si91x_ncp_utility.c", "${examples_plat_dir}/rs911x/hal/efx32_ncp_host.c", "${silabs_common_plat_dir}/wifi/wfx_notify.cpp", + "${silabs_common_plat_dir}/wifi/wfx_rsi_host.cpp", ] rs9117_inc_plat = [ diff --git a/examples/platform/silabs/efr32/rs911x/rs911x.gni b/examples/platform/silabs/efr32/rs911x/rs911x.gni index 54507de66e0ced..b25fbefc8e43b6 100644 --- a/examples/platform/silabs/efr32/rs911x/rs911x.gni +++ b/examples/platform/silabs/efr32/rs911x/rs911x.gni @@ -3,13 +3,13 @@ import("//build_overrides/efr32_sdk.gni") import("${efr32_sdk_build_root}/efr32_sdk.gni") rs911x_src_plat = [ - "${examples_plat_dir}/rs911x/rsi_if.c", - "${examples_plat_dir}/rs911x/wfx_rsi_host.cpp", + "${examples_plat_dir}/rs911x/rsi_if.cpp", "${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_interrupt.c", "${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_ioports.c", "${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_timer.c", "${examples_plat_dir}/rs911x/hal/efx_spi.c", "${silabs_common_plat_dir}/wifi/wfx_notify.cpp", + "${silabs_common_plat_dir}/wifi/wfx_rsi_host.cpp", ] # diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.c b/examples/platform/silabs/efr32/rs911x/rsi_if.cpp similarity index 93% rename from examples/platform/silabs/efr32/rs911x/rsi_if.c rename to examples/platform/silabs/efr32/rs911x/rsi_if.cpp index f0121285383d00..d5560d69e97219 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.c +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.cpp @@ -30,6 +30,9 @@ // TODO Fix include order issue #33120 #include "wfx_host_events.h" +#ifdef __cplusplus +extern "C" { +#endif #include "rsi_bootup_config.h" #include "rsi_common_apis.h" #include "rsi_data_types.h" @@ -42,10 +45,13 @@ #include "rsi_wlan_apis.h" #include "rsi_wlan_config.h" #include "rsi_wlan_non_rom.h" -#include "silabs_utils.h" +#ifdef __cplusplus +} +#endif #include "dhcp_client.h" #include "lwip/nd6.h" +#include "silabs_utils.h" #include "wfx_rsi.h" // TODO convert this file to cpp and use CodeUtils.h @@ -55,14 +61,17 @@ #define WFX_QUEUE_SIZE 10 -/* Rsi driver Task will use as its stack */ -StackType_t driverRsiTaskStack[WFX_RSI_WLAN_TASK_SZ] = { 0 }; - -/* Structure that will hold the TCB of the wfxRsi Task being created. */ -StaticTask_t driverRsiTaskBuffer; - -/* Declare a variable to hold the data associated with the created event group. */ -StaticEventGroup_t rsiDriverEventGroup; +static osThreadId_t sDrvThread; +constexpr uint32_t kDrvTaskSize = 1792; +static uint8_t drvStack[kDrvTaskSize]; +static osThread_t sDrvTaskControlBlock; +osThreadAttr_t kDrvTaskAttr = { .name = "drv_rsi", + .attr_bits = osThreadDetached, + .cb_mem = &sDrvTaskControlBlock, + .cb_size = osThreadCbSize, + .stack_mem = drvStack, + .stack_size = kDrvTaskSize, + .priority = osPriorityHigh }; bool hasNotifiedIPV6 = false; #if (CHIP_DEVICE_CONFIG_ENABLE_IPV4) @@ -83,6 +92,19 @@ static osMessageQueueId_t sWifiEventQueue = NULL; static uint8_t wfx_rsi_drv_buf[WFX_RSI_BUF_SZ]; static wfx_wifi_scan_ext_t temp_reset; +/****************************************************************** + * @fn void rsi_wireless_driver_task_wrapper(void * argument) + * @brief + * wrapper thread for the driver task + * @param[in] argument: argument + * @return + * None + *********************************************************************/ +static void rsi_wireless_driver_task_wrapper(void * argument) +{ + rsi_wireless_driver_task(); +} + static void DHCPTimerEventHandler(void * arg) { WfxEvent_t event; @@ -359,11 +381,10 @@ static int32_t wfx_rsi_init(void) } SILABS_LOG("wfx_rsi_init: start wireless drv task", __func__); /* - * Create the driver task + * Create the driver wrapper thread */ - wfx_rsi.drv_task = xTaskCreateStatic((TaskFunction_t) rsi_wireless_driver_task, "rsi_drv", WFX_RSI_WLAN_TASK_SZ, NULL, - WLAN_TASK_PRIORITY, driverRsiTaskStack, &driverRsiTaskBuffer); - if (NULL == wfx_rsi.drv_task) + sDrvThread = osThreadNew(rsi_wireless_driver_task_wrapper, NULL, &kDrvTaskAttr); + if (NULL == sDrvThread) { SILABS_LOG("wfx_rsi_init: error: rsi_wireless_driver_task failed", __func__); return RSI_ERROR_INVALID_PARAM; @@ -605,7 +626,8 @@ void HandleDHCPPolling() sta_netif = wfx_get_netif(SL_WFX_STA_INTERFACE); if (sta_netif == NULL) { - // TODO: Notify the application that the interface is not set up or Chipdie here because we are in an unkonwn state + // TODO: Notify the application that the interface is not set up or Chipdie here because we + // are in an unkonwn state SILABS_LOG("HandleDHCPPolling: failed to get STA netif"); return; } @@ -664,7 +686,8 @@ void WfxPostEvent(WfxEvent_t * event) if (status != osOK) { SILABS_LOG("WfxPostEvent: failed to post event with status: %d", status); - // TODO: Handle error, requeue event depending on queue size or notify relevant task, Chipdie, etc. + // TODO: Handle error, requeue event depending on queue size or notify relevant task, + // Chipdie, etc. } } @@ -673,7 +696,7 @@ void ProcessEvent(WfxEvent_t inEvent) // Process event switch (inEvent.eventType) { - case WFX_EVT_STA_CONN: + case WFX_EVT_STA_CONN: { SILABS_LOG("Starting LwIP STA"); wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTED; ResetDHCPNotificationFlags(); @@ -683,8 +706,9 @@ void ProcessEvent(WfxEvent_t inEvent) // of AP connectivity. // wfx_connected_notify(0, &wfx_rsi.ap_mac); // This // is independant of IP connectivity. - break; - case WFX_EVT_STA_DISCONN: + } + break; + case WFX_EVT_STA_DISCONN: { // TODO: This event is not being posted anywhere, seems to be a dead code or we are missing something wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_READY | WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED | WFX_RSI_ST_STA_DHCP_DONE); @@ -697,14 +721,15 @@ void ProcessEvent(WfxEvent_t inEvent) wfx_ip_changed_notify(IP_STATUS_FAIL); #endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ wfx_ipv6_notify(GET_IPV6_FAIL); - break; + } + break; case WFX_EVT_AP_START: // TODO: Currently unimplemented break; case WFX_EVT_AP_STOP: // TODO: Currently unimplemented break; - case WFX_EVT_SCAN: + case WFX_EVT_SCAN: { #ifdef SL_WFX_CONFIG_SCAN rsi_rsp_scan_t scan_rsp = { 0 }; int32_t status = rsi_wlan_bgscan_profile(1, &scan_rsp, sizeof(scan_rsp)); @@ -721,10 +746,12 @@ void ProcessEvent(WfxEvent_t inEvent) { scan = &scan_rsp.scan_info[x]; // is it a scan all or target scan - if (!wfx_rsi.scan_ssid || (wfx_rsi.scan_ssid && strcmp(wfx_rsi.scan_ssid, (char *) scan->ssid) == CMP_SUCCESS)) + if (wfx_rsi.scan_ssid != NULL && + (strncmp(wfx_rsi.scan_ssid, (char *) scan->ssid, MIN(strlen(wfx_rsi.scan_ssid), sizeof(scan->ssid))) == + CMP_SUCCESS)) { strncpy(ap.ssid, (char *) scan->ssid, MIN(sizeof(ap.ssid), sizeof(scan->ssid))); - ap.security = scan->security_mode; + ap.security = static_cast(scan->security_mode); ap.rssi = (-1) * scan->rssi_val; configASSERT(sizeof(ap.bssid) >= BSSID_LEN); configASSERT(sizeof(scan->bssid) >= BSSID_LEN); @@ -748,22 +775,28 @@ void ProcessEvent(WfxEvent_t inEvent) vPortFree(wfx_rsi.scan_ssid); wfx_rsi.scan_ssid = (char *) 0; } - break; #endif /* SL_WFX_CONFIG_SCAN */ - case WFX_EVT_STA_START_JOIN: + } + break; + case WFX_EVT_STA_START_JOIN: { // saving the AP related info wfx_rsi_save_ap_info(); // Joining to the network wfx_rsi_do_join(); - break; - case WFX_EVT_STA_DO_DHCP: + } + break; + case WFX_EVT_STA_DO_DHCP: { StartDHCPTimer(WFX_RSI_DHCP_POLL_INTERVAL); - break; - case WFX_EVT_STA_DHCP_DONE: + } + break; + case WFX_EVT_STA_DHCP_DONE: { CancelDHCPTimer(); - break; - case WFX_EVT_DHCP_POLL: + } + break; + case WFX_EVT_DHCP_POLL: { HandleDHCPPolling(); + } + break; default: break; } @@ -893,7 +926,7 @@ void wfx_rsi_pkt_add_data(void * p, uint8_t * buf, uint16_t len, uint16_t off) int32_t wfx_rsi_send_data(void * p, uint16_t len) { int32_t status; - register uint8_t * host_desc; + uint8_t * host_desc; rsi_pkt_t * pkt; pkt = (rsi_pkt_t *) p; diff --git a/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.cpp b/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.cpp deleted file mode 100644 index 8d92c0e3dc5c3e..00000000000000 --- a/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/* - * - * Copyright (c) 2022 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 - -#include "em_bus.h" -#include "em_cmu.h" -#include "em_gpio.h" -#include "em_ldma.h" -#include "em_usart.h" -#include "sl_status.h" - -#include "silabs_utils.h" - -#include "FreeRTOS.h" -#include "event_groups.h" -#include "task.h" - -#include "wfx_host_events.h" -#include "wfx_rsi.h" - -/* wfxRsi Task will use as its stack */ -StackType_t wfxRsiTaskStack[WFX_RSI_TASK_SZ] = { 0 }; - -/* Structure that will hold the TCB of the wfxRsi Task being created. */ -StaticTask_t wfxRsiTaskBuffer; - -/********************************************************************* - * @fn sl_status_t wfx_wifi_start(void) - * @brief - * Called from ConnectivityManagerImpl.cpp - to enable the device - * Create the RSI task and let it deal with life. - * @param[in] None - * @return Returns SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_wifi_start(void) -{ - if (wfx_rsi.dev_state & WFX_RSI_ST_STARTED) - { - return SL_STATUS_OK; - } - wfx_rsi.dev_state |= WFX_RSI_ST_STARTED; - /* - * Create the Wifi driver task - */ - wfx_rsi.wlan_task = xTaskCreateStatic(wfx_rsi_task, "wfx_rsi", WFX_RSI_TASK_SZ, NULL, WLAN_DRIVER_TASK_PRIORITY, - wfxRsiTaskStack, &wfxRsiTaskBuffer); - - if (NULL == wfx_rsi.wlan_task) - { - return SL_STATUS_FAIL; - } - return SL_STATUS_OK; -} - -/********************************************************************* - * @fn void wfx_enable_sta_mode(void) - * @brief - * driver enable the STA mode - * @param[in] None - * @return None - ***********************************************************************/ -void wfx_enable_sta_mode(void) -{ - wfx_rsi.dev_state |= WFX_RSI_ST_STA_MODE; -} - -/********************************************************************* - * @fn bool wfx_is_sta_mode_enabled(void) - * @brief - * driver enabled the STA mode - * @param[in] None - * @return mode - ***********************************************************************/ -bool wfx_is_sta_mode_enabled(void) -{ - bool mode; - mode = !!(wfx_rsi.dev_state & WFX_RSI_ST_STA_MODE); - return mode; -} - -/********************************************************************* - * @fn wfx_get_wifi_mac_addr(sl_wfx_interface_t interface, sl_wfx_mac_address_t * addr) - * @brief - * get the wifi mac address - * @param[in] Interface: - * @param[in] addr : address - * @return - * None - ***********************************************************************/ -void wfx_get_wifi_mac_addr(sl_wfx_interface_t interface, sl_wfx_mac_address_t * addr) -{ - if (addr) - { -#ifdef SL_WFX_CONFIG_SOFTAP - *addr = (interface == SL_WFX_SOFTAP_INTERFACE) ? wfx_rsi.softap_mac : wfx_rsi.sta_mac; -#else - *addr = wfx_rsi.sta_mac; -#endif - } -} - -/********************************************************************* - * @fn void wfx_set_wifi_provision(wfx_wifi_provision_t *cfg) - * @brief - * Driver set the wifi provision - * @param[in] cfg: wifi configuration - * @return - * None - ***********************************************************************/ -void wfx_set_wifi_provision(wfx_wifi_provision_t * cfg) -{ - if (cfg) - { - wfx_rsi.sec = *cfg; - wfx_rsi.dev_state |= WFX_RSI_ST_STA_PROVISIONED; - } -} - -/********************************************************************* - * @fn bool wfx_get_wifi_provision(wfx_wifi_provision_t *wifiConfig) - * @brief - * Driver get the wifi provision - * @param[in] wifiConfig: wifi configuration - * @return return false if successful, - * true otherwise - ***********************************************************************/ -bool wfx_get_wifi_provision(wfx_wifi_provision_t * wifiConfig) -{ - if (wifiConfig != NULL) - { - if (wfx_rsi.dev_state & WFX_RSI_ST_STA_PROVISIONED) - { - *wifiConfig = wfx_rsi.sec; - return true; - } - } - return false; -} - -/********************************************************************* - * @fn void wfx_clear_wifi_provision(void) - * @brief - * Driver is clear the wifi provision - * @param[in] None - * @return None - ***********************************************************************/ -void wfx_clear_wifi_provision(void) -{ - memset(&wfx_rsi.sec, 0, sizeof(wfx_rsi.sec)); - wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_PROVISIONED; -} - -/************************************************************************* - * @fn sl_status_t wfx_connect_to_ap(void) - * @brief - * Start a JOIN command to the AP - Done by the wfx_rsi task - * @param[in] None - * @return returns SL_STATUS_OK if successful, - * SL_STATUS_INVALID_CONFIGURATION otherwise - ****************************************************************************/ -sl_status_t wfx_connect_to_ap(void) -{ - WfxEvent_t event; - if (wfx_rsi.dev_state & WFX_RSI_ST_STA_PROVISIONED) - { - SILABS_LOG("Connecting to access point -> SSID: %s", &wfx_rsi.sec.ssid[0]); - event.eventType = WFX_EVT_STA_START_JOIN; - WfxPostEvent(&event); - } - else - { - SILABS_LOG("Error: access point not provisioned."); - return SL_STATUS_INVALID_CONFIGURATION; - } - return SL_STATUS_OK; -} - -#if SL_ICD_ENABLED -#if SLI_SI917 -/********************************************************************* - * @fn sl_status_t wfx_power_save() - * @brief - * Implements the power save in sleepy application - * @param[in] sl_si91x_ble_state : State to set for the BLE - sl_si91x_wifi_state : State to set for the WiFi - * @return SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) -{ - return (wfx_rsi_power_save(sl_si91x_ble_state, sl_si91x_wifi_state) ? SL_STATUS_FAIL : SL_STATUS_OK); -} -#else // For RS9116 -/********************************************************************* - * @fn sl_status_t wfx_power_save() - * @brief - * Implements the power save in sleepy application - * @param[in] None - * @return SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_power_save() -{ - return (wfx_rsi_power_save() ? SL_STATUS_FAIL : SL_STATUS_OK); -} -#endif /* SLI_SI917 */ -#endif /* SL_ICD_ENABLED */ - -/********************************************************************* - * @fn void wfx_setup_ip6_link_local(sl_wfx_interface_t whichif) - * @brief - * Implement the ipv6 setup - * @param[in] whichif: - * @return None - ***********************************************************************/ -void wfx_setup_ip6_link_local(sl_wfx_interface_t whichif) -{ - /* - * TODO: Implement IPV6 setup, currently in wfx_rsi_task() - * This is hooked with MATTER code. - */ -} - -/********************************************************************* - * @fn bool wfx_is_sta_connected(void) - * @brief - * called fuction when driver is connected to STA - * @param[in] None - * @return returns ture if successful, - * false otherwise - ***********************************************************************/ -bool wfx_is_sta_connected(void) -{ - bool status; - status = (wfx_rsi.dev_state & WFX_RSI_ST_STA_CONNECTED) ? true : false; - return status; -} - -/********************************************************************* - * @fn wifi_mode_t wfx_get_wifi_mode() - * @brief - * get the wifi mode - * @param[in] None - * @return return WIFI_MODE_NULL if successful, - * WIFI_MODE_STA otherwise - ***********************************************************************/ -wifi_mode_t wfx_get_wifi_mode() -{ - if (wfx_rsi.dev_state & WFX_RSI_ST_DEV_READY) - return WIFI_MODE_STA; - return WIFI_MODE_NULL; -} - -/********************************************************************* - * @fn sl_status_t wfx_sta_discon(void) - * @brief - * called fuction when STA disconnected - * @param[in] None - * @return return SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_sta_discon(void) -{ - int32_t status; - status = wfx_rsi_disconnect(); - wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTED; - return status; -} -#if CHIP_DEVICE_CONFIG_ENABLE_IPV4 -/********************************************************************* - * @fn bool wfx_have_ipv4_addr(sl_wfx_interface_t which_if) - * @brief - * called fuction when driver have ipv4 address - * @param[in] which_if: - * @return returns ture if successful, - * false otherwise - ***********************************************************************/ -bool wfx_have_ipv4_addr(sl_wfx_interface_t which_if) -{ - bool status = false; - if (which_if == SL_WFX_STA_INTERFACE) - { - status = (wfx_rsi.dev_state & WFX_RSI_ST_STA_DHCP_DONE) ? true : false; - } - else - { - status = false; /* TODO */ - } - return status; -} -#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ - -/********************************************************************* - * @fn bool wfx_have_ipv6_addr(sl_wfx_interface_t which_if) - * @brief - * called fuction when driver have ipv6 address - * @param[in] which_if: - * @return returns ture if successful, - * false otherwise - ***********************************************************************/ -bool wfx_have_ipv6_addr(sl_wfx_interface_t which_if) -{ - bool status = false; - if (which_if == SL_WFX_STA_INTERFACE) - { - status = (wfx_rsi.dev_state & WFX_RSI_ST_STA_CONNECTED) ? true : false; - } - else - { - status = false; /* TODO */ - } - return status; -} - -/********************************************************************* - * @fn bool wfx_hw_ready(void) - * @brief - * called fuction when driver ready - * @param[in] None - * @return returns ture if successful, - * false otherwise - ***********************************************************************/ -bool wfx_hw_ready(void) -{ - return (wfx_rsi.dev_state & WFX_RSI_ST_DEV_READY) ? true : false; -} - -/********************************************************************* - * @fn int32_t wfx_get_ap_info(wfx_wifi_scan_result_t *ap) - * @brief - * get the access point information - * @param[in] ap: access point - * @return - * access point information - ***********************************************************************/ -int32_t wfx_get_ap_info(wfx_wifi_scan_result_t * ap) -{ - return wfx_rsi_get_ap_info(ap); -} - -/********************************************************************* - * @fn int32_t wfx_get_ap_ext(wfx_wifi_scan_ext_t *extra_info) - * @brief - * get the access point extra information - * @param[in] extra_info:access point extra information - * @return - * access point extra information - ***********************************************************************/ -int32_t wfx_get_ap_ext(wfx_wifi_scan_ext_t * extra_info) -{ - return wfx_rsi_get_ap_ext(extra_info); -} - -/*************************************************************************** - * @fn int32_t wfx_reset_counts(){ - * @brief - * get the driver reset count - * @param[in] None - * @return - * reset count - *****************************************************************************/ -int32_t wfx_reset_counts() -{ - return wfx_rsi_reset_count(); -} - -#ifdef SL_WFX_CONFIG_SCAN -/******************************************************************************* - * @fn bool wfx_start_scan(char *ssid, void (*callback)(wfx_wifi_scan_result_t *)) - * @brief - * called fuction when driver start scaning - * @param[in] ssid: - * @return returns ture if successful, - * false otherwise - *******************************************************************************/ -bool wfx_start_scan(char * ssid, void (*callback)(wfx_wifi_scan_result_t *)) -{ - int sz; - WfxEvent_t event; - if (wfx_rsi.scan_cb) - return false; /* Already in progress */ - if (ssid) - { - sz = strlen(ssid); - if ((wfx_rsi.scan_ssid = (char *) pvPortMalloc(sz + 1)) == (char *) 0) - { - return false; - } - strcpy(wfx_rsi.scan_ssid, ssid); - } - wfx_rsi.scan_cb = callback; - - event.eventType = WFX_EVT_SCAN; - WfxPostEvent(&event); - - return true; -} - -/*************************************************************************** - * @fn void wfx_cancel_scan(void) - * @brief - * called function when driver cancel scaning - * @param[in] None - * @return - * None - *****************************************************************************/ -void wfx_cancel_scan(void) -{ - /* Not possible */ -} -#endif /* SL_WFX_CONFIG_SCAN */ diff --git a/examples/platform/silabs/uart.cpp b/examples/platform/silabs/uart.cpp index 7d6dad912314db..a05dd706e3a82f 100644 --- a/examples/platform/silabs/uart.cpp +++ b/examples/platform/silabs/uart.cpp @@ -138,7 +138,13 @@ constexpr osThreadAttr_t kUartTaskAttr = { .name = "UART", .cb_size = osThreadCbSize, .stack_mem = uartStack, .stack_size = kUartTaskSize, - .priority = osPriorityRealtime }; +#if SLI_SI91X_MCU_INTERFACE + // Reducing the priority of the UART task to avoid priority inversion + .priority = osPriorityNormal +#else + .priority = osPriorityRealtime +#endif // SLI_SI91X_MCU_INTERFACE +}; typedef struct { diff --git a/examples/platform/silabs/wfx_rsi.h b/examples/platform/silabs/wfx_rsi.h index 502dd1a96e772d..5e7358e0d02cb1 100644 --- a/examples/platform/silabs/wfx_rsi.h +++ b/examples/platform/silabs/wfx_rsi.h @@ -17,7 +17,9 @@ #pragma once #include +#include #include +#include #include #ifndef RSI_BLE_ENABLE @@ -28,10 +30,8 @@ * Interface to RSI Sapis */ -#define WFX_RSI_WLAN_TASK_SZ (1024 + 512 + 256) /* Stack for the WLAN task */ -#define WFX_RSI_TASK_SZ (1024 + 1024) /* Stack for the WFX/RSI task */ -#define WFX_RSI_BUF_SZ (1024 * 10) /* May need tweak */ -// TODO: Default values are usually in minutes, but this is in ms. Confirm if this is correct +#define WFX_RSI_WLAN_TASK_SZ (1024 + 512 + 256) /* Stack for the WLAN task */ // TODO: For rs9116 +#define WFX_RSI_BUF_SZ (1024 * 10) #define WFX_RSI_DHCP_POLL_INTERVAL (250) /* Poll interval in ms for DHCP */ #define WFX_RSI_NUM_TIMERS (2) /* Number of RSI timers to alloc */ @@ -71,14 +71,6 @@ typedef struct WfxEvent_s typedef struct wfx_rsi_s { - // TODO: Change tp WfxEventType_e once the event queue is implemented - EventGroupHandle_t events; - TaskHandle_t drv_task; - TaskHandle_t wlan_task; - TaskHandle_t init_task; -#ifdef RSI_BLE_ENABLE - TaskHandle_t ble_task; -#endif uint16_t dev_state; uint16_t ap_chan; /* The chan our STA is using */ wfx_wifi_provision_t sec; diff --git a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.cpp b/examples/platform/silabs/wifi/wfx_rsi_host.cpp similarity index 89% rename from examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.cpp rename to examples/platform/silabs/wifi/wfx_rsi_host.cpp index 83c3a95ec0caf7..921ec82587fe77 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.cpp +++ b/examples/platform/silabs/wifi/wfx_rsi_host.cpp @@ -28,11 +28,20 @@ #include "wfx_host_events.h" #include "wfx_rsi.h" -/* wfxRsi Task will use as its stack */ -StackType_t wfxRsiTaskStack[WFX_RSI_TASK_SZ] = { 0 }; +#include -/* Structure that will hold the TCB of the wfxRsi Task being created. */ -StaticTask_t wfxRsiTaskBuffer; +// Thread for the WLAN RSI +static osThreadId_t sWlanThread; +constexpr uint32_t kWlanTaskSize = 2048; +static uint8_t wlanStack[kWlanTaskSize]; +static osThread_t sWlanTaskControlBlock; +constexpr osThreadAttr_t kWlanTaskAttr = { .name = "wlan_rsi", + .attr_bits = osThreadDetached, + .cb_mem = &sWlanTaskControlBlock, + .cb_size = osThreadCbSize, + .stack_mem = wlanStack, + .stack_size = kWlanTaskSize, + .priority = osPriorityAboveNormal7 }; /********************************************************************* * @fn sl_status_t wfx_wifi_start(void) @@ -47,22 +56,20 @@ sl_status_t wfx_wifi_start(void) { if (wfx_rsi.dev_state & WFX_RSI_ST_STARTED) { - SILABS_LOG("%s: already started.", __func__); return SL_STATUS_OK; } + wfx_rsi.dev_state |= WFX_RSI_ST_STARTED; SILABS_LOG("%s: starting..", __func__); + /* * Create the Wifi driver task */ - wfx_rsi.wlan_task = xTaskCreateStatic(wfx_rsi_task, "wfx_rsi", WFX_RSI_TASK_SZ, NULL, WLAN_DRIVER_TASK_PRIORITY, - wfxRsiTaskStack, &wfxRsiTaskBuffer); + // Creating a Wi-Fi driver thread + sWlanThread = osThreadNew(wfx_rsi_task, NULL, &kWlanTaskAttr); + + VerifyOrReturnError(sWlanThread != NULL, SL_STATUS_FAIL); - if (NULL == wfx_rsi.wlan_task) - { - SILABS_LOG("%s: error: failed to create task.", __func__); - return SL_STATUS_FAIL; - } return SL_STATUS_OK; } @@ -191,6 +198,7 @@ sl_status_t wfx_connect_to_ap(void) } #if SL_ICD_ENABLED +#if SLI_SI917 /********************************************************************* * @fn sl_status_t wfx_power_save() * @brief @@ -202,12 +210,22 @@ sl_status_t wfx_connect_to_ap(void) ***********************************************************************/ sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) { - if (wfx_rsi_power_save(sl_si91x_ble_state, sl_si91x_wifi_state) != SL_STATUS_OK) - { - return SL_STATUS_FAIL; - } - return SL_STATUS_OK; + return (wfx_rsi_power_save(sl_si91x_ble_state, sl_si91x_wifi_state) ? SL_STATUS_FAIL : SL_STATUS_OK); +} +#else // For RS9116 +/********************************************************************* + * @fn sl_status_t wfx_power_save() + * @brief + * Implements the power save in sleepy application + * @param[in] None + * @return SL_STATUS_OK if successful, + * SL_STATUS_FAIL otherwise + ***********************************************************************/ +sl_status_t wfx_power_save() +{ + return (wfx_rsi_power_save() ? SL_STATUS_FAIL : SL_STATUS_OK); } +#endif /* SLI_SI917 */ #endif /* SL_ICD_ENABLED */ /********************************************************************* diff --git a/src/platform/silabs/BLEManagerImpl.h b/src/platform/silabs/BLEManagerImpl.h index 86d1b05a887869..4ff6d9d85413bf 100644 --- a/src/platform/silabs/BLEManagerImpl.h +++ b/src/platform/silabs/BLEManagerImpl.h @@ -196,7 +196,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla void CancelBleAdvTimeoutTimer(void); CHIPoBLEConState * GetConnectionState(uint8_t conId, bool allocate = false); static void DriveBLEState(intptr_t arg); - static void BleAdvTimeoutHandler(TimerHandle_t xTimer); + static void BleAdvTimeoutHandler(void * arg); uint8_t GetTimerHandle(uint8_t connectionHandle, bool allocate); #if (SLI_SI91X_ENABLE_BLE || RSI_BLE_ENABLE) diff --git a/src/platform/silabs/efr32/BLEManagerImpl.cpp b/src/platform/silabs/efr32/BLEManagerImpl.cpp index 2fcceefa37b90a..e29e34e31af16e 100644 --- a/src/platform/silabs/efr32/BLEManagerImpl.cpp +++ b/src/platform/silabs/efr32/BLEManagerImpl.cpp @@ -101,7 +101,7 @@ namespace { #define BLE_CONFIG_MIN_CE_LENGTH (0) // Leave to min value #define BLE_CONFIG_MAX_CE_LENGTH (0xFFFF) // Leave to max value -TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. +osTimerId_t sbleAdvTimeoutTimer; // SW timer const uint8_t UUID_CHIPoBLEService[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xF6, 0xFF, 0x00, 0x00 }; @@ -122,13 +122,8 @@ CHIP_ERROR BLEManagerImpl::_Init() memset(mIndConfId, kUnusedIndex, sizeof(mIndConfId)); mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; - // Create FreeRTOS sw timer for BLE timeouts and interval change. - sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel - pdMS_TO_TICKS(1), // == default timer period - false, // no timer reload (==one-shot) - (void *) this, // init timer id = ble obj context - BleAdvTimeoutHandler // timer callback handler - ); + // SW timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = osTimerNew(BleAdvTimeoutHandler, osTimerOnce, NULL, NULL); mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); mFlags.Set(Flags::kFastAdvertisingEnabled, true); @@ -991,7 +986,7 @@ uint8_t BLEManagerImpl::GetTimerHandle(uint8_t connectionHandle, bool allocate) return freeIndex; } -void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +void BLEManagerImpl::BleAdvTimeoutHandler(void * arg) { if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) { @@ -1016,7 +1011,7 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) { - if (xTimerStop(sbleAdvTimeoutTimer, pdMS_TO_TICKS(0)) == pdFAIL) + if (osTimerStop(sbleAdvTimeoutTimer) != osOK) { ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); } @@ -1024,15 +1019,7 @@ void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) { - if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) - { - CancelBleAdvTimeoutTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs), pdMS_TO_TICKS(100)) != pdPASS) + if (osTimerStart(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs)) != osOK) { ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); } diff --git a/src/platform/silabs/rs911x/BLEManagerImpl.cpp b/src/platform/silabs/rs911x/BLEManagerImpl.cpp index 75853c8dce5155..6fea061de76ab8 100644 --- a/src/platform/silabs/rs911x/BLEManagerImpl.cpp +++ b/src/platform/silabs/rs911x/BLEManagerImpl.cpp @@ -71,13 +71,22 @@ extern "C" { extern sl_wfx_msg_t event_msg; -StaticTask_t rsiBLETaskStruct; - osSemaphoreId_t sl_ble_event_sem; osSemaphoreId_t sl_rs_ble_init_sem; -/* wfxRsi Task will use as its stack */ -StackType_t wfxBLETaskStack[WFX_RSI_TASK_SZ] = { 0 }; +osTimerId_t sbleAdvTimeoutTimer; + +static osThreadId_t sBleThread; +constexpr uint32_t kBleTaskSize = 2048; +static uint8_t bleStack[kBleTaskSize]; +static osThread_t sBleTaskControlBlock; +constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", + .attr_bits = osThreadDetached, + .cb_mem = &sBleTaskControlBlock, + .cb_size = osThreadCbSize, + .stack_mem = bleStack, + .stack_size = kBleTaskSize, + .priority = osPriorityHigh }; using namespace ::chip; using namespace ::chip::Ble; @@ -110,7 +119,7 @@ void sl_ble_init() chip::DeviceLayer::Internal::BLEMgrImpl().HandleBootEvent(); } -void sl_ble_event_handling_task(void) +void sl_ble_event_handling_task(void * args) { int32_t event_id; @@ -236,8 +245,6 @@ namespace { #define BLE_CONFIG_MIN_CE_LENGTH (0) // Leave to min value #define BLE_CONFIG_MAX_CE_LENGTH (0xFFFF) // Leave to max value -TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. - const uint8_t UUID_CHIPoBLEService[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xF6, 0xFF, 0x00, 0x00 }; const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; @@ -253,13 +260,9 @@ CHIP_ERROR BLEManagerImpl::_Init() sl_rs_ble_init_sem = osSemaphoreNew(1, 0, NULL); sl_ble_event_sem = osSemaphoreNew(1, 0, NULL); - wfx_rsi.ble_task = xTaskCreateStatic((TaskFunction_t) sl_ble_event_handling_task, "rsi_ble", WFX_RSI_TASK_SZ, NULL, - BLE_DRIVER_TASK_PRIORITY, wfxBLETaskStack, &rsiBLETaskStruct); + sBleThread = osThreadNew(sl_ble_event_handling_task, NULL, &kBleTaskAttr); - if (wfx_rsi.ble_task == NULL) - { - ChipLogError(DeviceLayer, "%s: error: failed to create ble task.", __func__); - } + VerifyOrReturnError(sBleThread != nullptr, CHIP_ERROR_INCORRECT_STATE); // Initialize the CHIP BleLayer. err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); @@ -269,13 +272,8 @@ CHIP_ERROR BLEManagerImpl::_Init() memset(mIndConfId, kUnusedIndex, sizeof(mIndConfId)); mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; - // Create FreeRTOS sw timer for BLE timeouts and interval change. - sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel - pdMS_TO_TICKS(BLE_DEFAULT_TIMER_PERIOD_MS), // == default timer period - false, // no timer reload (==one-shot) - (void *) this, // init timer id = ble obj context - BleAdvTimeoutHandler // timer callback handler - ); + // SW timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = osTimerNew(BleAdvTimeoutHandler, osTimerOnce, NULL, NULL); mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); mFlags.Set(Flags::kFastAdvertisingEnabled, true); @@ -1070,7 +1068,7 @@ uint8_t BLEManagerImpl::GetTimerHandle(uint8_t connectionHandle, bool allocate) return freeIndex; } -void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +void BLEManagerImpl::BleAdvTimeoutHandler(void * arg) { if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) { @@ -1081,7 +1079,7 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) { - if (xTimerStop(sbleAdvTimeoutTimer, pdMS_TO_TICKS(0)) == pdFAIL) + if (osTimerStop(sbleAdvTimeoutTimer) != osOK) { ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); } @@ -1089,15 +1087,7 @@ void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) { - if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) - { - CancelBleAdvTimeoutTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs), pdMS_TO_TICKS(100)) != pdPASS) + if (osTimerStart(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs)) != osOK) { ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); } From 50cfda6a85ef5bbf707d09a0b81f01db549ea1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 3 Sep 2024 13:37:03 +0200 Subject: [PATCH 10/70] Update Matter ESP32 Energy Management Example README.md (#35282) * Update Matter ESP32 Energy Management Example README.md * Update README.md * Update README.md --- examples/energy-management-app/esp32/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/energy-management-app/esp32/README.md b/examples/energy-management-app/esp32/README.md index 8e0d127f21b56d..733ac5a632d48a 100644 --- a/examples/energy-management-app/esp32/README.md +++ b/examples/energy-management-app/esp32/README.md @@ -12,14 +12,14 @@ guides to get started. ### Enabling ESP-Insights: -- Before building the app, enable the option: ESP_INSIGHTS_ENABLED through +- Before building the app, enable the option: `ESP_INSIGHTS_ENABLED` through menuconfig. -- Create a file named insights_auth_key.txt in the main directory of the +- Create a file named `insights_auth_key.txt` in the main directory of the example. -- Follow the steps - present[here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) +- Follow the steps present + [here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) to set up an insights_account and the auth key created while setting it up will be used in the example. @@ -39,7 +39,7 @@ cp /path/to/auth/key.txt path/to/connectedhomeip/examples/energy-management-app/ ### Build time configuration - Application mode: By default the example app will run the EVSE example, - however this can be changed using the `idy.py menuconfig` command and + however this can be changed using the `idf.py menuconfig` command and searching for: ENABLE_EXAMPLE_WATER_HEATER_DEVICE From ce3b4d9fdfa87e926a7e28f3c6335c6074989f13 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 3 Sep 2024 14:10:08 +0200 Subject: [PATCH 11/70] Split TC_MCORE_FS_1_3 to align with the Test Spec (#35274) * [TC_MCORE_FS_1_3] Fix test script according to test plan update * Separate storage for all used components * Open commissioning window on TH_FSA_BRIDGE * Python wrapper for running fabric-admin and fabric-bridge together * Customize fabric-admin and fabric-bridge RPC ports * Create storage directory * Use fabric-sync-app in the TC-MCORE-FS-1.3 script * Use CommissionerControlCluster to commission TH_SERVER onto DUT * Auto-link bridge with admin * Test automation setup * Terminate apps on SIGTERM and SIGINT * Open commissioning window on fabric-bridge after adding to FSA * Commissioning TH_FSA_BRIDGE to DUT_FSA fabric * Synchronize server from TH to DUT * Start another instance of app server * Test if unique ID was synced * Allow customization for fabric-sync app components * Final cleanup * Split test case into two test cases * Simplify TC_MCORE_FS_1_3 script * Simplify TC_MCORE_FS_1_4 steps * Use volatile storage for fabric-sync-app by default * Add TC_MCORE_FS_1_4 to exceptions * Get rid of defaults * Document used options in open commissioning window * Speed up the pipe read busy loop * Refactor local output processing * Improve wait for output * Add FS-sync tests to CI * Improve Python code style * Fix wait for fabric-sync-app start * Fix asyncio forwarder * Fixes for review comments --- .github/workflows/tests.yaml | 6 + .../fabric-admin/scripts/fabric-sync-app.py | 318 +++++++++++++ src/python_testing/TC_MCORE_FS_1_3.py | 297 ++++++++---- src/python_testing/TC_MCORE_FS_1_4.py | 442 ++++++++++++++++++ src/python_testing/execute_python_tests.py | 1 + 5 files changed, 981 insertions(+), 83 deletions(-) create mode 100755 examples/fabric-admin/scripts/fabric-sync-app.py create mode 100644 src/python_testing/TC_MCORE_FS_1_4.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b37ed3c6ca4370..5265f82b09454c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -486,6 +486,9 @@ jobs: --target linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-network-manager-ipv6only-no-ble-no-wifi-tsan-clang-test \ + --target linux-x64-fabric-admin-rpc-ipv6only-clang \ + --target linux-x64-fabric-bridge-rpc-ipv6only-no-ble-no-wifi-clang \ + --target linux-x64-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang \ --target linux-x64-python-bindings \ build \ --copy-artifacts-to objdir-clone \ @@ -500,6 +503,9 @@ jobs: echo "CHIP_MICROWAVE_OVEN_APP: out/linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app" >> /tmp/test_env.yaml echo "CHIP_RVC_APP: out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app" >> /tmp/test_env.yaml echo "NETWORK_MANAGEMENT_APP: out/linux-x64-network-manager-ipv6only-no-ble-no-wifi-tsan-clang-test/matter-network-manager-app" >> /tmp/test_env.yaml + echo "FABRIC_ADMIN_APP: out/linux-x64-fabric-admin-rpc-ipv6only-clang/fabric-admin" >> /tmp/test_env.yaml + echo "FABRIC_BRIDGE_APP: out/linux-x64-fabric-bridge-rpc-ipv6only-no-ble-no-wifi-clang/fabric-bridge-app" >> /tmp/test_env.yaml + echo "LIGHTING_APP_NO_UNIQUE_ID: out/linux-x64-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang/chip-lighting-app" >> /tmp/test_env.yaml echo "TRACE_APP: out/trace_data/app-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml echo "TRACE_TEST_JSON: out/trace_data/test-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml echo "TRACE_TEST_PERFETTO: out/trace_data/test-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml diff --git a/examples/fabric-admin/scripts/fabric-sync-app.py b/examples/fabric-admin/scripts/fabric-sync-app.py new file mode 100755 index 00000000000000..c6faed8b67ac00 --- /dev/null +++ b/examples/fabric-admin/scripts/fabric-sync-app.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import asyncio +import contextlib +import os +import signal +import sys +from argparse import ArgumentParser +from tempfile import TemporaryDirectory + + +async def asyncio_stdin() -> asyncio.StreamReader: + """Wrap sys.stdin in an asyncio StreamReader.""" + loop = asyncio.get_event_loop() + reader = asyncio.StreamReader() + protocol = asyncio.StreamReaderProtocol(reader) + await loop.connect_read_pipe(lambda: protocol, sys.stdin) + return reader + + +async def asyncio_stdout(file=sys.stdout) -> asyncio.StreamWriter: + """Wrap an IO stream in an asyncio StreamWriter.""" + loop = asyncio.get_event_loop() + transport, protocol = await loop.connect_write_pipe( + lambda: asyncio.streams.FlowControlMixin(loop=loop), + os.fdopen(file.fileno(), 'wb')) + return asyncio.streams.StreamWriter(transport, protocol, None, loop) + + +async def forward_f(prefix: bytes, f_in: asyncio.StreamReader, + f_out: asyncio.StreamWriter, cb=None): + """Forward f_in to f_out with a prefix attached. + + This function can optionally feed received lines to a callback function. + """ + while True: + line = await f_in.readline() + if not line: + break + if cb is not None: + cb(line) + f_out.write(prefix) + f_out.write(line) + await f_out.drain() + + +async def forward_pipe(pipe_path: str, f_out: asyncio.StreamWriter): + """Forward named pipe to f_out. + + Unfortunately, Python does not support async file I/O on named pipes. This + function performs busy waiting with a short asyncio-friendly sleep to read + from the pipe. + """ + fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) + while True: + try: + data = os.read(fd, 1024) + if data: + f_out.write(data) + if not data: + await asyncio.sleep(0.1) + except BlockingIOError: + await asyncio.sleep(0.1) + + +async def forward_stdin(f_out: asyncio.StreamWriter): + """Forward stdin to f_out.""" + reader = await asyncio_stdin() + while True: + line = await reader.readline() + if not line: + # Exit on Ctrl-D (EOF). + sys.exit(0) + f_out.write(line) + + +class Subprocess: + + def __init__(self, tag: str, program: str, *args, stdout_cb=None): + self.event = asyncio.Event() + self.tag = tag.encode() + self.program = program + self.args = args + self.stdout_cb = stdout_cb + self.expected_output = None + + def _check_output(self, line: bytes): + if self.expected_output is not None and self.expected_output in line: + self.event.set() + + async def run(self): + self.p = await asyncio.create_subprocess_exec(self.program, *self.args, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE) + # Add the stdout and stderr processing to the event loop. + asyncio.create_task(forward_f( + self.tag, + self.p.stderr, + await asyncio_stdout(sys.stderr))) + asyncio.create_task(forward_f( + self.tag, + self.p.stdout, + await asyncio_stdout(sys.stdout), + cb=self._check_output)) + + async def send(self, message: str, expected_output: str = None, timeout: float = None): + """Send a message to a process and optionally wait for a response.""" + + if expected_output is not None: + self.expected_output = expected_output.encode() + self.event.clear() + + self.p.stdin.write((message + "\n").encode()) + await self.p.stdin.drain() + + if expected_output is not None: + await asyncio.wait_for(self.event.wait(), timeout=timeout) + self.expected_output = None + + async def wait(self): + await self.p.wait() + + def terminate(self): + self.p.terminate() + + +async def run_admin(program, stdout_cb=None, storage_dir=None, + rpc_admin_port=None, rpc_bridge_port=None, + paa_trust_store_path=None, commissioner_name=None, + commissioner_node_id=None, commissioner_vendor_id=None): + args = [] + if storage_dir is not None: + args.extend(["--storage-directory", storage_dir]) + if rpc_admin_port is not None: + args.extend(["--local-server-port", str(rpc_admin_port)]) + if rpc_bridge_port is not None: + args.extend(["--fabric-bridge-server-port", str(rpc_bridge_port)]) + if paa_trust_store_path is not None: + args.extend(["--paa-trust-store-path", paa_trust_store_path]) + if commissioner_name is not None: + args.extend(["--commissioner-name", commissioner_name]) + if commissioner_node_id is not None: + args.extend(["--commissioner-nodeid", str(commissioner_node_id)]) + if commissioner_vendor_id is not None: + args.extend(["--commissioner-vendor-id", str(commissioner_vendor_id)]) + p = Subprocess("[FS-ADMIN]", program, "interactive", "start", *args, + stdout_cb=stdout_cb) + await p.run() + return p + + +async def run_bridge(program, storage_dir=None, rpc_admin_port=None, + rpc_bridge_port=None, discriminator=None, passcode=None, + secured_device_port=None): + args = [] + if storage_dir is not None: + args.extend(["--KVS", + os.path.join(storage_dir, "chip_fabric_bridge_kvs")]) + if rpc_admin_port is not None: + args.extend(["--fabric-admin-server-port", str(rpc_admin_port)]) + if rpc_bridge_port is not None: + args.extend(["--local-server-port", str(rpc_bridge_port)]) + if discriminator is not None: + args.extend(["--discriminator", str(discriminator)]) + if passcode is not None: + args.extend(["--passcode", str(passcode)]) + if secured_device_port is not None: + args.extend(["--secured-device-port", str(secured_device_port)]) + p = Subprocess("[FS-BRIDGE]", program, *args) + await p.run() + return p + + +async def main(args): + + # Node ID of the bridge on the fabric. + bridge_node_id = 1 + + if args.commissioner_node_id == bridge_node_id: + raise ValueError(f"NodeID={bridge_node_id} is reserved for the local fabric-bridge") + + storage_dir = args.storage_dir + if storage_dir is not None: + os.makedirs(storage_dir, exist_ok=True) + else: + storage = TemporaryDirectory(prefix="fabric-sync-app") + storage_dir = storage.name + + pipe = args.stdin_pipe + if pipe and not os.path.exists(pipe): + os.mkfifo(pipe) + + def terminate(signum, frame): + admin.terminate() + bridge.terminate() + sys.exit(0) + + signal.signal(signal.SIGINT, terminate) + signal.signal(signal.SIGTERM, terminate) + + admin, bridge = await asyncio.gather( + run_admin( + args.app_admin, + storage_dir=storage_dir, + rpc_admin_port=args.app_admin_rpc_port, + rpc_bridge_port=args.app_bridge_rpc_port, + paa_trust_store_path=args.paa_trust_store_path, + commissioner_name=args.commissioner_name, + commissioner_node_id=args.commissioner_node_id, + commissioner_vendor_id=args.commissioner_vendor_id, + ), + run_bridge( + args.app_bridge, + storage_dir=storage_dir, + rpc_admin_port=args.app_admin_rpc_port, + rpc_bridge_port=args.app_bridge_rpc_port, + secured_device_port=args.secured_device_port, + discriminator=args.discriminator, + passcode=args.passcode, + )) + + # Wait a bit for apps to start. + await asyncio.sleep(1) + + try: + # Check whether the bridge is already commissioned. If it is, + # we will get the response, otherwise we will hit timeout. + await admin.send( + f"descriptor read device-type-list {bridge_node_id} 1 --timeout 1", + # Log message which should appear in the fabric-admin output if + # the bridge is already commissioned. + expected_output="Reading attribute: Cluster=0x0000_001D Endpoint=0x1 AttributeId=0x0000_0000", + timeout=1.5) + except asyncio.TimeoutError: + # Commission the bridge to the admin. + cmd = f"fabricsync add-local-bridge {bridge_node_id}" + if args.passcode is not None: + cmd += f" --setup-pin-code {args.passcode}" + if args.secured_device_port is not None: + cmd += f" --local-port {args.secured_device_port}" + await admin.send( + cmd, + # Wait for the log message indicating that the bridge has been + # added to the fabric. + f"Commissioning complete for node ID {bridge_node_id:#018x}: success") + + # Open commissioning window with original setup code for the bridge. + cw_endpoint_id = 0 + cw_option = 0 # 0: Original setup code, 1: New setup code + cw_timeout = 600 + cw_iteration = 1000 + cw_discriminator = 0 + await admin.send(f"pairing open-commissioning-window {bridge_node_id} {cw_endpoint_id}" + f" {cw_option} {cw_timeout} {cw_iteration} {cw_discriminator}") + + try: + await asyncio.gather( + forward_pipe(pipe, admin.p.stdin) if pipe else forward_stdin(admin.p.stdin), + admin.wait(), + bridge.wait(), + ) + except SystemExit: + admin.terminate() + bridge.terminate() + except Exception: + admin.terminate() + bridge.terminate() + raise + + +if __name__ == "__main__": + parser = ArgumentParser(description="Fabric-Sync Example Application") + parser.add_argument("--app-admin", metavar="PATH", + default="out/linux-x64-fabric-admin-rpc/fabric-admin", + help="path to the fabric-admin executable; default=%(default)s") + parser.add_argument("--app-bridge", metavar="PATH", + default="out/linux-x64-fabric-bridge-rpc/fabric-bridge-app", + help="path to the fabric-bridge executable; default=%(default)s") + parser.add_argument("--app-admin-rpc-port", metavar="PORT", type=int, + help="fabric-admin RPC server port") + parser.add_argument("--app-bridge-rpc-port", metavar="PORT", type=int, + help="fabric-bridge RPC server port") + parser.add_argument("--stdin-pipe", metavar="PATH", + help="read input from a named pipe instead of stdin") + parser.add_argument("--storage-dir", metavar="PATH", + help=("directory to place storage files in; by default " + "volatile storage is used")) + parser.add_argument("--paa-trust-store-path", metavar="PATH", + help="path to directory holding PAA certificates") + parser.add_argument("--commissioner-name", metavar="NAME", + help="commissioner name to use for the admin") + parser.add_argument("--commissioner-node-id", metavar="NUM", type=int, + help="commissioner node ID to use for the admin") + parser.add_argument("--commissioner-vendor-id", metavar="NUM", type=int, + help="commissioner vendor ID to use for the admin") + parser.add_argument("--secured-device-port", metavar="NUM", type=int, + help="secure messages listen port to use for the bridge") + parser.add_argument("--discriminator", metavar="NUM", type=int, + help="discriminator to use for the bridge") + parser.add_argument("--passcode", metavar="NUM", type=int, + help="passcode to use for the bridge") + with contextlib.suppress(KeyboardInterrupt): + asyncio.run(main(parser.parse_args())) diff --git a/src/python_testing/TC_MCORE_FS_1_3.py b/src/python_testing/TC_MCORE_FS_1_3.py index 4245bc139ceb38..1a18896c055952 100644 --- a/src/python_testing/TC_MCORE_FS_1_3.py +++ b/src/python_testing/TC_MCORE_FS_1_3.py @@ -15,15 +15,31 @@ # limitations under the License. # -# This test requires a TH_SERVER application that returns UnsupportedAttribute when reading UniqueID from BasicInformation Cluster. Please specify with --string-arg th_server_no_uid_app_path: +# This test requires a TH_SERVER_NO_UID application that returns UnsupportedAttribute +# when reading UniqueID from BasicInformation Cluster. Please specify the app +# location with --string-arg th_server_no_uid_app_path: +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: examples/fabric-admin/scripts/fabric-sync-app.py +# test-runner-run/run1/app-args: --app-admin=${FABRIC_ADMIN_APP} --app-bridge=${FABRIC_BRIDGE_APP} --stdin-pipe=dut-fsa-stdin --discriminator=1234 +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/script-args: --PICS src/app/tests/suites/certification/ci-pics-values --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --string-arg th_server_no_uid_app_path:${LIGHTING_APP_NO_UNIQUE_ID} +# test-runner-run/run1/script-start-delay: 5 +# test-runner-run/run1/quiet: false +# === END CI TEST ARGUMENTS === + +import asyncio import logging import os import random -import signal import subprocess -import time -import uuid +import sys +import tempfile +import threading import chip.clusters as Clusters from chip import ChipDeviceCtrl @@ -32,109 +48,224 @@ from mobly import asserts +# TODO: Make this class more generic. Issue #35348 +class Subprocess(threading.Thread): + + def __init__(self, args: list = [], tag="", **kw): + super().__init__(**kw) + self.tag = f"[{tag}] " if tag else "" + self.args = args + + def forward_f(self, f_in, f_out): + while True: + line = f_in.readline() + if not line: + break + f_out.write(f"{self.tag}{line}") + f_out.flush() + + def run(self): + logging.info("RUN: %s", " ".join(self.args)) + self.p = subprocess.Popen(self.args, errors="ignore", stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Forward stdout and stderr with a tag attached. + t1 = threading.Thread(target=self.forward_f, args=[self.p.stdout, sys.stdout]) + t1.start() + t2 = threading.Thread(target=self.forward_f, args=[self.p.stderr, sys.stderr]) + t2.start() + # Wait for the process to finish. + self.p.wait() + t1.join() + t2.join() + + def stop(self): + self.p.terminate() + self.join() + + +class AppServer: + + def __init__(self, app, storage_dir, port=None, discriminator=None, passcode=None): + + args = [app] + args.extend(["--KVS", tempfile.mkstemp(dir=storage_dir, prefix="kvs-app-")[1]]) + args.extend(['--secured-device-port', str(port)]) + args.extend(["--discriminator", str(discriminator)]) + args.extend(["--passcode", str(passcode)]) + self.app = Subprocess(args, tag="SERVER") + self.app.start() + + def stop(self): + self.app.stop() + + class TC_MCORE_FS_1_3(MatterBaseTest): - @async_test_body - async def setup_class(self): + + @property + def default_timeout(self) -> int: + # This test has some manual steps, so we need a longer timeout. + return 200 + + def setup_class(self): super().setup_class() - self.th_server_nodeid = 1111 - self.th_server_kvs = None - self.th_server_port = 5543 - self.app_process_for_dut_eco = None + self.th_server = None + self.storage = None - # Create a second controller on a new fabric to communicate to the server - new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() - new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) - paa_path = str(self.matter_test_config.paa_trust_store_path) - self.TH_server_controller = new_fabric_admin.NewController(nodeId=112233, paaTrustStorePath=paa_path) + # Get the path to the TH_SERVER_NO_UID app from the user params. + th_server_app = self.user_params.get("th_server_no_uid_app_path", None) + if not th_server_app: + asserts.fail("This test requires a TH_SERVER_NO_UID app. Specify app path with --string-arg th_server_no_uid_app_path:") + if not os.path.exists(th_server_app): + asserts.fail(f"The path {th_server_app} does not exist") - def teardown_class(self): - if self.app_process_for_dut_eco is not None: - logging.warning("Stopping app with SIGTERM") - self.app_process_for_dut_eco.send_signal(signal.SIGTERM.value) - self.app_process_for_dut_eco.wait() + # Create a temporary storage directory for keeping KVS files. + self.storage = tempfile.TemporaryDirectory(prefix=self.__class__.__name__) + logging.info("Temporary storage directory: %s", self.storage.name) + + self.th_server_port = 5544 + self.th_server_discriminator = random.randint(0, 4095) + self.th_server_passcode = 20202021 - os.remove(self.th_server_kvs) + # Start the TH_SERVER_NO_UID app. + self.th_server = AppServer( + th_server_app, + storage_dir=self.storage.name, + port=self.th_server_port, + discriminator=self.th_server_discriminator, + passcode=self.th_server_passcode) + + def teardown_class(self): + if self.th_server is not None: + self.th_server.stop() + if self.storage is not None: + self.storage.cleanup() super().teardown_class() - async def create_device_and_commission_to_th_fabric(self, kvs, port, node_id_for_th, device_info): - app = self.user_params.get("th_server_no_uid_app_path", None) - if not app: - asserts.fail('This test requires a TH_SERVER app. Specify app path with --string-arg th_server_no_uid_app_path:') + def steps_TC_MCORE_FS_1_3(self) -> list[TestStep]: + return [ + TestStep(0, "Commission DUT if not done", is_commissioning=True), + TestStep(1, "TH commissions TH_SERVER_NO_UID to TH's fabric"), + TestStep(2, "DUT_FSA commissions TH_SERVER_NO_UID to DUT_FSA's fabric and generates a UniqueID.", + "TH verifies a value is visible for the UniqueID from the DUT_FSA's Bridged Device Basic Information Cluster."), + ] - if not os.path.exists(app): - asserts.fail(f'The path {app} does not exist') + async def commission_via_commissioner_control(self, controller_node_id: int, device_node_id: int): + """Commission device_node_id to controller_node_id using CommissionerControl cluster.""" - discriminator = random.randint(0, 4095) - passcode = 20202021 + request_id = random.randint(0, 0xFFFFFFFFFFFFFFFF) - cmd = [app] - cmd.extend(['--secured-device-port', str(port)]) - cmd.extend(['--discriminator', str(discriminator)]) - cmd.extend(['--passcode', str(passcode)]) - cmd.extend(['--KVS', kvs]) + vendor_id = await self.read_single_attribute_check_success( + node_id=device_node_id, + cluster=Clusters.BasicInformation, + attribute=Clusters.BasicInformation.Attributes.VendorID, + ) - # TODO: Determine if we want these logs cooked or pushed to somewhere else - logging.info(f"Starting TH device for {device_info}") - self.app_process_for_dut_eco = subprocess.Popen(cmd) - logging.info(f"Started TH device for {device_info}") - time.sleep(3) + product_id = await self.read_single_attribute_check_success( + node_id=device_node_id, + cluster=Clusters.BasicInformation, + attribute=Clusters.BasicInformation.Attributes.ProductID, + ) - logging.info("Commissioning from separate fabric") - await self.TH_server_controller.CommissionOnNetwork(nodeId=node_id_for_th, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) - logging.info("Commissioning device for DUT ecosystem onto TH for managing") + await self.send_single_cmd( + node_id=controller_node_id, + cmd=Clusters.CommissionerControl.Commands.RequestCommissioningApproval( + requestId=request_id, + vendorId=vendor_id, + productId=product_id, + ), + ) - def steps_TC_MCORE_FS_1_3(self) -> list[TestStep]: - steps = [TestStep(1, "TH commissions TH_SERVER to TH’s fabric.", is_commissioning=True), - TestStep(2, "DUT_FSA commissions TH_SERVER to DUT_FSA’s fabric and generates a UniqueID.")] - return steps + if not self.is_ci: + self.wait_for_user_input("Approve Commissioning Approval Request on DUT using manufacturer specified mechanism") + + resp = await self.send_single_cmd( + node_id=controller_node_id, + cmd=Clusters.CommissionerControl.Commands.CommissionNode( + requestId=request_id, + responseTimeoutSeconds=30, + ), + ) + + asserts.assert_equal(type(resp), Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow, + "Incorrect response type") + + await self.send_single_cmd( + node_id=device_node_id, + cmd=Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow( + commissioningTimeout=3*60, + PAKEPasscodeVerifier=resp.PAKEPasscodeVerifier, + discriminator=resp.discriminator, + iterations=resp.iterations, + salt=resp.salt, + ), + timedRequestTimeoutMs=5000, + ) @async_test_body async def test_TC_MCORE_FS_1_3(self): self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') - self.print_step(0, "Commissioning DUT to TH, already done") + + # Commissioning - done + self.step(0) self.step(1) - root_node_endpoint = 0 - root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) - set_of_endpoints_before_adding_device = set(root_part_list) - logging.info(f"Set of endpoints before adding the device: {set_of_endpoints_before_adding_device}") - kvs = f'kvs_{str(uuid.uuid4())}' - device_info = "for TH ecosystem" - await self.create_device_and_commission_to_th_fabric(kvs, self.th_server_port, self.th_server_nodeid, device_info) + th_server_th_node_id = 1 + await self.default_controller.CommissionOnNetwork( + nodeId=th_server_th_node_id, + setupPinCode=self.th_server_passcode, + filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, + filter=self.th_server_discriminator, + ) - self.th_server_kvs = kvs - read_result = await self.TH_server_controller.ReadAttribute(self.th_server_nodeid, [(root_node_endpoint, Clusters.BasicInformation.Attributes.UniqueID)]) - result = read_result[root_node_endpoint][Clusters.BasicInformation][Clusters.BasicInformation.Attributes.UniqueID] - asserts.assert_true(type_matches(result, Clusters.Attribute.ValueDecodeFailure), "We were expecting a value decode failure") - asserts.assert_equal(result.Reason.status, Status.UnsupportedAttribute, "Incorrect error returned from reading UniqueID") + await self.read_single_attribute_expect_error( + cluster=Clusters.BasicInformation, + attribute=Clusters.BasicInformation.Attributes.UniqueID, + node_id=th_server_th_node_id, + error=Status.UnsupportedAttribute, + ) self.step(2) - params = await self.openCommissioningWindow(dev_ctrl=self.TH_server_controller, node_id=self.th_server_nodeid) - - self.wait_for_user_input( - prompt_msg=f"Using the DUT vendor's provided interface, commission the device using the following parameters:\n" - f"- discriminator: {params.randomDiscriminator}\n" - f"- setupPinCode: {params.commissioningParameters.setupPinCode}\n" - f"- setupQRCode: {params.commissioningParameters.setupQRCode}\n" - f"- setupManualcode: {params.commissioningParameters.setupManualCode}\n" - f"If using FabricSync Admin, you may type:\n" - f">>> pairing onnetwork {params.commissioningParameters.setupPinCode}") - - root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) - set_of_endpoints_after_adding_device = set(root_part_list) - logging.info(f"Set of endpoints after adding the device: {set_of_endpoints_after_adding_device}") - - asserts.assert_true(set_of_endpoints_after_adding_device.issuperset( - set_of_endpoints_before_adding_device), "Expected only new endpoints to be added") - unique_endpoints_set = set_of_endpoints_after_adding_device - set_of_endpoints_before_adding_device - asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") - newly_added_endpoint = list(unique_endpoints_set)[0] - - th_sed_dut_unique_id = await self.read_single_attribute_check_success(cluster=Clusters.BridgedDeviceBasicInformation, attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, endpoint=newly_added_endpoint) - asserts.assert_true(type_matches(th_sed_dut_unique_id, str), "UniqueID should be a string") - asserts.assert_true(th_sed_dut_unique_id, "UniqueID should not be an empty string") + + # Get the list of endpoints on the DUT_FSA_BRIDGE before adding the TH_SERVER_NO_UID. + dut_fsa_bridge_endpoints = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=self.dut_node_id, + endpoint=0, + )) + + await self.commission_via_commissioner_control( + controller_node_id=self.dut_node_id, + device_node_id=th_server_th_node_id) + + # Wait for the device to appear on the DUT_FSA_BRIDGE. + await asyncio.sleep(2) + + # Get the list of endpoints on the DUT_FSA_BRIDGE after adding the TH_SERVER_NO_UID. + dut_fsa_bridge_endpoints_new = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=self.dut_node_id, + endpoint=0, + )) + + # Get the endpoint number for just added TH_SERVER_NO_UID. + logging.info("Endpoints on DUT_FSA_BRIDGE: old=%s, new=%s", dut_fsa_bridge_endpoints, dut_fsa_bridge_endpoints_new) + asserts.assert_true(dut_fsa_bridge_endpoints_new.issuperset(dut_fsa_bridge_endpoints), + "Expected only new endpoints to be added") + unique_endpoints_set = dut_fsa_bridge_endpoints_new - dut_fsa_bridge_endpoints + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint on DUT_FSA") + dut_fsa_bridge_th_server_endpoint = list(unique_endpoints_set)[0] + + dut_fsa_bridge_th_server_unique_id = await self.read_single_attribute_check_success( + cluster=Clusters.BridgedDeviceBasicInformation, + attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, + endpoint=dut_fsa_bridge_th_server_endpoint) + asserts.assert_true(type_matches(dut_fsa_bridge_th_server_unique_id, str), "UniqueID should be a string") + asserts.assert_true(dut_fsa_bridge_th_server_unique_id, "UniqueID should not be an empty string") + logging.info("UniqueID generated for TH_SERVER_NO_UID: %s", dut_fsa_bridge_th_server_unique_id) if __name__ == "__main__": diff --git a/src/python_testing/TC_MCORE_FS_1_4.py b/src/python_testing/TC_MCORE_FS_1_4.py new file mode 100644 index 00000000000000..8e05c2dd7e9c3d --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_4.py @@ -0,0 +1,442 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This test requires a TH_SERVER_NO_UID application that returns UnsupportedAttribute +# when reading UniqueID from BasicInformation Cluster. Please specify the app +# location with --string-arg th_server_no_uid_app_path: + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: examples/fabric-admin/scripts/fabric-sync-app.py +# test-runner-run/run1/app-args: --app-admin=${FABRIC_ADMIN_APP} --app-bridge=${FABRIC_BRIDGE_APP} --stdin-pipe=dut-fsa-stdin --discriminator=1234 +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/script-args: --PICS src/app/tests/suites/certification/ci-pics-values --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --string-arg th_fsa_app_path:examples/fabric-admin/scripts/fabric-sync-app.py th_fsa_admin_path:${FABRIC_ADMIN_APP} th_fsa_bridge_path:${FABRIC_BRIDGE_APP} th_server_no_uid_app_path:${LIGHTING_APP_NO_UNIQUE_ID} dut_fsa_stdin_pipe:dut-fsa-stdin +# test-runner-run/run1/script-start-delay: 5 +# test-runner-run/run1/quiet: false +# === END CI TEST ARGUMENTS === + +import asyncio +import logging +import os +import random +import subprocess +import sys +import tempfile +import threading + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.interaction_model import Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +# TODO: Make this class more generic. Issue #35348 +class Subprocess(threading.Thread): + + def __init__(self, args: list = [], stdout_cb=None, tag="", **kw): + super().__init__(**kw) + self.tag = f"[{tag}] " if tag else "" + self.stdout_cb = stdout_cb + self.args = args + + def forward_f(self, f_in, f_out): + while True: + line = f_in.readline() + if not line: + break + f_out.write(f"{self.tag}{line}") + f_out.flush() + if self.stdout_cb is not None: + self.stdout_cb(line) + + def run(self): + logging.info("RUN: %s", " ".join(self.args)) + self.p = subprocess.Popen(self.args, errors="ignore", stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Forward stdout and stderr with a tag attached. + forwarding_stdout_thread = threading.Thread(target=self.forward_f, args=[self.p.stdout, sys.stdout]) + forwarding_stdout_thread.start() + forwarding_stderr_thread = threading.Thread(target=self.forward_f, args=[self.p.stderr, sys.stderr]) + forwarding_stderr_thread.start() + # Wait for the process to finish. + self.p.wait() + forwarding_stdout_thread.join() + forwarding_stderr_thread.join() + + def stop(self): + self.p.terminate() + self.join() + + +class FabricSyncApp: + + def _process_admin_output(self, line): + if self.wait_for_text_text is not None and self.wait_for_text_text in line: + self.wait_for_text_event.set() + + def wait_for_text(self, timeout=30): + if not self.wait_for_text_event.wait(timeout=timeout): + raise Exception(f"Timeout waiting for text: {self.wait_for_text_text}") + self.wait_for_text_event.clear() + self.wait_for_text_text = None + + def __init__(self, fabric_sync_app_path, fabric_admin_app_path, fabric_bridge_app_path, + storage_dir, fabric_name=None, node_id=None, vendor_id=None, + paa_trust_store_path=None, bridge_port=None, bridge_discriminator=None, + bridge_passcode=None): + + self.wait_for_text_event = threading.Event() + self.wait_for_text_text = None + + args = [fabric_sync_app_path] + args.append(f"--app-admin={fabric_admin_app_path}") + args.append(f"--app-bridge={fabric_bridge_app_path}") + # Override default ports, so it will be possible to run + # our TH_FSA alongside the DUT_FSA during CI testing. + args.append("--app-admin-rpc-port=44000") + args.append("--app-bridge-rpc-port=44001") + # Keep the storage directory in a temporary location. + args.append(f"--storage-dir={storage_dir}") + if paa_trust_store_path is not None: + args.append(f"--paa-trust-store-path={paa_trust_store_path}") + if fabric_name is not None: + args.append(f"--commissioner-name={fabric_name}") + if node_id is not None: + args.append(f"--commissioner-node-id={node_id}") + args.append(f"--commissioner-vendor-id={vendor_id}") + args.append(f"--secured-device-port={bridge_port}") + args.append(f"--discriminator={bridge_discriminator}") + args.append(f"--passcode={bridge_passcode}") + + self.fabric_sync_app = Subprocess(args, stdout_cb=self._process_admin_output) + self.wait_for_text_text = "Successfully opened pairing window on the device" + self.fabric_sync_app.start() + + # Wait for the fabric-sync-app to be ready. + self.wait_for_text() + + def commission_on_network(self, node_id, setup_pin_code=None, filter_type=None, filter=None): + self.wait_for_text_text = f"Commissioning complete for node ID {node_id:#018x}: success" + # Send the commissioning command to the admin. + self.fabric_sync_app.p.stdin.write(f"pairing onnetwork {node_id} {setup_pin_code}\n") + self.fabric_sync_app.p.stdin.flush() + # Wait for success message. + self.wait_for_text() + + def stop(self): + self.fabric_sync_app.stop() + + +class AppServer: + + def __init__(self, app, storage_dir, port=None, discriminator=None, passcode=None): + + args = [app] + args.extend(["--KVS", tempfile.mkstemp(dir=storage_dir, prefix="kvs-app-")[1]]) + args.extend(['--secured-device-port', str(port)]) + args.extend(["--discriminator", str(discriminator)]) + args.extend(["--passcode", str(passcode)]) + self.app = Subprocess(args, tag="SERVER") + self.app.start() + + def stop(self): + self.app.stop() + + +class TC_MCORE_FS_1_4(MatterBaseTest): + + @property + def default_timeout(self) -> int: + # This test has some manual steps, so we need a longer timeout. + return 200 + + def setup_class(self): + super().setup_class() + + self.th_fsa_controller = None + self.th_server = None + self.storage = None + + # Get the path to the TH_FSA (fabric-admin and fabric-bridge) app from the user params. + th_fsa_app_path = self.user_params.get("th_fsa_app_path") + if not th_fsa_app_path: + asserts.fail("This test requires a TH_FSA app. Specify app path with --string-arg th_fsa_app_path:") + if not os.path.exists(th_fsa_app_path): + asserts.fail(f"The path {th_fsa_app_path} does not exist") + th_fsa_admin_path = self.user_params.get("th_fsa_admin_path") + if not th_fsa_admin_path: + asserts.fail("This test requires a TH_FSA_ADMIN app. Specify app path with --string-arg th_fsa_admin_path:") + if not os.path.exists(th_fsa_admin_path): + asserts.fail(f"The path {th_fsa_admin_path} does not exist") + th_fsa_bridge_path = self.user_params.get("th_fsa_bridge_path") + if not th_fsa_bridge_path: + asserts.fail("This test requires a TH_FSA_BRIDGE app. Specify app path with --string-arg th_fsa_bridge_path:") + if not os.path.exists(th_fsa_bridge_path): + asserts.fail(f"The path {th_fsa_bridge_path} does not exist") + + # Get the path to the TH_SERVER_NO_UID app from the user params. + th_server_app = self.user_params.get("th_server_no_uid_app_path", None) + if not th_server_app: + asserts.fail("This test requires a TH_SERVER_NO_UID app. Specify app path with --string-arg th_server_no_uid_app_path:") + if not os.path.exists(th_server_app): + asserts.fail(f"The path {th_server_app} does not exist") + + # Create a temporary storage directory for keeping KVS files. + self.storage = tempfile.TemporaryDirectory(prefix=self.__class__.__name__) + logging.info("Temporary storage directory: %s", self.storage.name) + + self.th_fsa_bridge_address = "::1" + self.th_fsa_bridge_port = 5543 + # Random discriminator between 0 and MAX - 1. The one-less is to save + # a room for the TH_SERVER_NO_UID discriminator. + self.th_fsa_bridge_discriminator = random.randint(0, 4094) + self.th_fsa_bridge_passcode = 20202021 + + self.th_fsa_controller = FabricSyncApp( + th_fsa_app_path, + th_fsa_admin_path, + th_fsa_bridge_path, + storage_dir=self.storage.name, + paa_trust_store_path=self.matter_test_config.paa_trust_store_path, + bridge_port=self.th_fsa_bridge_port, + bridge_discriminator=self.th_fsa_bridge_discriminator, + bridge_passcode=self.th_fsa_bridge_passcode, + vendor_id=0xFFF1) + + # Get the named pipe path for the DUT_FSA app input from the user params. + dut_fsa_stdin_pipe = self.user_params.get("dut_fsa_stdin_pipe", None) + if dut_fsa_stdin_pipe is not None: + self.dut_fsa_stdin = open(dut_fsa_stdin_pipe, "w") + + self.th_server_port = 5544 + self.th_server_discriminator = self.th_fsa_bridge_discriminator + 1 + self.th_server_passcode = 20202021 + + # Start the TH_SERVER_NO_UID app. + self.th_server = AppServer( + th_server_app, + storage_dir=self.storage.name, + port=self.th_server_port, + discriminator=self.th_server_discriminator, + passcode=self.th_server_passcode) + + def teardown_class(self): + if self.th_fsa_controller is not None: + self.th_fsa_controller.stop() + if self.th_server is not None: + self.th_server.stop() + if self.storage is not None: + self.storage.cleanup() + super().teardown_class() + + def steps_TC_MCORE_FS_1_4(self) -> list[TestStep]: + return [ + TestStep(0, "Commission DUT if not done", is_commissioning=True), + TestStep(1, "TH commissions TH_SERVER_NO_UID to TH's fabric.", + "TH verifies that the TH_SERVER_NO_UID does not provide a UniqueID."), + TestStep(2, "TH instructs TH_FSA to commission TH_SERVER_NO_UID to TH_FSA's fabric."), + TestStep(3, "TH instructs TH_FSA to open up commissioning window on it's aggregator."), + TestStep(4, "Follow manufacturer provided instructions to have DUT_FSA commission TH_FSA's aggregator."), + TestStep(5, "Follow manufacturer provided instructions to enable DUT_FSA to synchronize TH_SERVER_NO_UID" + " from TH_FSA onto DUT_FSA's fabric. TH to provide endpoint saved from step 2 in user prompt."), + TestStep(6, "DUT_FSA synchronizes TH_SERVER_NO_UID onto DUT_FSA's fabric and copies the UniqueID presented" + " by TH_FSA's Bridged Device Basic Information Cluster."), + ] + + @async_test_body + async def test_TC_MCORE_FS_1_4(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + + # Commissioning - done + self.step(0) + + self.step(1) + + th_server_th_node_id = 1 + await self.default_controller.CommissionOnNetwork( + nodeId=th_server_th_node_id, + setupPinCode=self.th_server_passcode, + filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, + filter=self.th_server_discriminator, + ) + + await self.read_single_attribute_expect_error( + cluster=Clusters.BasicInformation, + attribute=Clusters.BasicInformation.Attributes.UniqueID, + node_id=th_server_th_node_id, + error=Status.UnsupportedAttribute, + ) + + self.step(2) + + th_fsa_bridge_th_node_id = 2 + # Commissioning TH_FSA_BRIDGE to TH fabric. + await self.default_controller.CommissionOnNetwork( + nodeId=th_fsa_bridge_th_node_id, + setupPinCode=self.th_fsa_bridge_passcode, + filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, + filter=self.th_fsa_bridge_discriminator, + ) + + # Get the list of endpoints on the TH_FSA_BRIDGE before adding the TH_SERVER_NO_UID. + th_fsa_bridge_endpoints = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=th_fsa_bridge_th_node_id, + endpoint=0, + )) + + discriminator = random.randint(0, 4095) + # Open commissioning window on TH_SERVER_NO_UID. + params = await self.default_controller.OpenCommissioningWindow( + nodeid=th_server_th_node_id, + option=self.default_controller.CommissioningWindowPasscode.kTokenWithRandomPin, + discriminator=discriminator, + iteration=10000, + timeout=600) + + th_server_th_fsa_node_id = 3 + # Commissioning TH_SERVER_NO_UID to TH_FSA. + self.th_fsa_controller.commission_on_network( + node_id=th_server_th_fsa_node_id, + setup_pin_code=params.setupPinCode, + filter_type=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, + filter=discriminator, + ) + + # Wait some time, so the dynamic endpoint will appear on the TH_FSA_BRIDGE. + await asyncio.sleep(5) + + # Get the list of endpoints on the TH_FSA_BRIDGE after adding the TH_SERVER_NO_UID. + th_fsa_bridge_endpoints_new = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=th_fsa_bridge_th_node_id, + endpoint=0, + )) + + # Get the endpoint number for just added TH_SERVER_NO_UID. + logging.info("Endpoints on TH_FSA_BRIDGE: old=%s, new=%s", th_fsa_bridge_endpoints, th_fsa_bridge_endpoints_new) + asserts.assert_true(th_fsa_bridge_endpoints_new.issuperset(th_fsa_bridge_endpoints), + "Expected only new endpoints to be added") + unique_endpoints_set = th_fsa_bridge_endpoints_new - th_fsa_bridge_endpoints + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + th_fsa_bridge_th_server_endpoint = list(unique_endpoints_set)[0] + + # Verify that TH_FSA created a UniqueID for TH_SERVER_NO_UID. + th_fsa_bridge_th_server_unique_id = await self.read_single_attribute_check_success( + cluster=Clusters.BridgedDeviceBasicInformation, + attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, + node_id=th_fsa_bridge_th_node_id, + endpoint=th_fsa_bridge_th_server_endpoint) + asserts.assert_true(type_matches(th_fsa_bridge_th_server_unique_id, str), "UniqueID should be a string") + asserts.assert_true(th_fsa_bridge_th_server_unique_id, "UniqueID should not be an empty string") + logging.info("UniqueID generated for TH_SERVER_NO_UID: %s", th_fsa_bridge_th_server_unique_id) + + self.step(3) + + discriminator = random.randint(0, 4095) + # Open commissioning window on TH_FSA_BRIDGE. + params = await self.default_controller.OpenCommissioningWindow( + nodeid=th_fsa_bridge_th_node_id, + option=self.default_controller.CommissioningWindowPasscode.kTokenWithRandomPin, + discriminator=discriminator, + iteration=10000, + timeout=600) + + self.step(4) + + # Commissioning TH_FSA_BRIDGE to DUT_FSA fabric. + if not self.is_ci: + self.wait_for_user_input( + f"Commission TH_FSA's aggregator on DUT using manufacturer specified mechanism.\n" + f"Use the following parameters:\n" + f"- discriminator: {discriminator}\n" + f"- setupPinCode: {params.setupPinCode}\n" + f"- setupQRCode: {params.setupQRCode}\n" + f"- setupManualCode: {params.setupManualCode}\n" + f"If using FabricSync Admin, you may type:\n" + f">>> fabricsync add-bridge {params.setupPinCode} {self.th_fsa_bridge_port}") + else: + self.dut_fsa_stdin.write( + f"fabricsync add-bridge 10 {params.setupPinCode} {self.th_fsa_bridge_address} {self.th_fsa_bridge_port}\n") + self.dut_fsa_stdin.flush() + # Wait for the commissioning to complete. + await asyncio.sleep(5) + + self.step(5) + + # Get the list of endpoints on the DUT_FSA_BRIDGE before synchronization. + dut_fsa_bridge_endpoints = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=self.dut_node_id, + endpoint=0, + )) + + # Synchronize TH_SERVER_NO_UID from TH_FSA to DUT_FSA fabric. + if not self.is_ci: + self.wait_for_user_input( + f"Synchronize endpoint from TH_FSA's aggregator to DUT using manufacturer specified mechanism.\n" + f"Use the following parameters:\n" + f"- endpointID: {th_fsa_bridge_th_server_endpoint}\n" + f"If using FabricSync Admin, you may type:\n" + f">>> fabricsync sync-device {th_fsa_bridge_th_server_endpoint}") + else: + self.dut_fsa_stdin.write(f"fabricsync sync-device {th_fsa_bridge_th_server_endpoint}\n") + self.dut_fsa_stdin.flush() + # Wait for the synchronization to complete. + await asyncio.sleep(5) + + self.step(6) + + # Get the list of endpoints on the DUT_FSA_BRIDGE after synchronization + dut_fsa_bridge_endpoints_new = set(await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + node_id=self.dut_node_id, + endpoint=0, + )) + + # Get the endpoint number for just synced TH_SERVER_NO_UID. + logging.info("Endpoints on DUT_FSA_BRIDGE: old=%s, new=%s", dut_fsa_bridge_endpoints, dut_fsa_bridge_endpoints_new) + asserts.assert_true(dut_fsa_bridge_endpoints_new.issuperset(dut_fsa_bridge_endpoints), + "Expected only new endpoints to be added") + unique_endpoints_set = dut_fsa_bridge_endpoints_new - dut_fsa_bridge_endpoints + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint on DUT_FSA") + dut_fsa_bridge_th_server_endpoint = list(unique_endpoints_set)[0] + + # Verify that DUT_FSA copied the TH_SERVER_NO_UID UniqueID from TH_FSA. + dut_fsa_bridge_th_server_unique_id = await self.read_single_attribute_check_success( + cluster=Clusters.BridgedDeviceBasicInformation, + attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, + endpoint=dut_fsa_bridge_th_server_endpoint) + asserts.assert_true(type_matches(dut_fsa_bridge_th_server_unique_id, str), "UniqueID should be a string") + asserts.assert_true(dut_fsa_bridge_th_server_unique_id, "UniqueID should not be an empty string") + logging.info("UniqueID for TH_SERVER_NO_UID on DUT_FSA: %s", th_fsa_bridge_th_server_unique_id) + + # Make sure that the UniqueID on the DUT_FSA_BRIDGE is the same as the one on the DUT_FSA_BRIDGE. + asserts.assert_equal(dut_fsa_bridge_th_server_unique_id, th_fsa_bridge_th_server_unique_id, + "UniqueID on DUT_FSA and TH_FSA should be the same") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/execute_python_tests.py b/src/python_testing/execute_python_tests.py index 8249be9b7c8ef3..1f6afa9d7035fd 100644 --- a/src/python_testing/execute_python_tests.py +++ b/src/python_testing/execute_python_tests.py @@ -75,6 +75,7 @@ def main(search_directory, env_file): "TC_MCORE_FS_1_1.py", "TC_MCORE_FS_1_2.py", "TC_MCORE_FS_1_3.py", + "TC_MCORE_FS_1_4.py", "TC_MCORE_FS_1_5.py", "TC_OCC_3_1.py", "TC_OCC_3_2.py", From 2f85b9879b37c1ec9199db3c42e1d7cc6b6ae86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20G=C3=B3rski?= <105657200+HubertHugo@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:43:41 +0200 Subject: [PATCH 12/70] [nrfconnect] Added BT reassembly config as default for SMP DFU samples (#35357) --- config/nrfconnect/chip-module/Kconfig.features | 1 + 1 file changed, 1 insertion(+) diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index fbae62d28e1f24..a610c37eed70d8 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -162,6 +162,7 @@ config CHIP_DFU_OVER_BT_SMP # Enable custom SMP request to erase settings partition. select MCUMGR_GRP_ZBASIC select MCUMGR_GRP_ZBASIC_STORAGE_ERASE + select MCUMGR_TRANSPORT_BT_REASSEMBLY help Enables Device Firmware Upgrade over Bluetooth LE with SMP and configures the set of options related to that feature. From 5f5aef0b0c36cb3d5a46f9e7313b664185d194bd Mon Sep 17 00:00:00 2001 From: Martin Girardot <165289184+Martin-NXP@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:49:08 +0200 Subject: [PATCH 13/70] [NXP][rw61x][k32w1] Rework reference apps (#35172) * [NXP][third_party] Add new NXP SDK support Signed-off-by: Martin Girardot * [NXP][examples] Update examples to support new NXP SDK Signed-off-by: Martin Girardot * [NXP][src] Update src to support new NXP SDK Signed-off-by: Martin Girardot * [NXP][docs] Update docs to support new NXP SDK Signed-off-by: Martin Girardot * [NXP][scripts] Update scripts to support new NXP SDK Signed-off-by: Martin Girardot * [NXP][workflows] Update rw61x workflow to support new NXP SDK Signed-off-by: Martin Girardot * [NXP][submodules] Update submodules to support new NXP SDK Signed-off-by: Martin Girardot * Restyled by gn * Restyled by prettier-markdown * [NXP] Spelling fixes Signed-off-by: Martin Girardot * [NXP][examples][common] Add common README file for contact sensor and lighting app Add mcxw71/k32w1 specific OTA guide in nxp docs area. Signed-off-by: marius-alex-tache * Restyled by prettier-markdown * [NXP][rw61x][examples][laundry-washer][thermostat][all-custer-app] Updating path to new nxp_matter_support repo Signed-off-by: Gatien Chapon * [NXP][docs] Update RW61x OTA readme to specify the upgrade type used Signed-off-by: Dina Benamar * [NXP] Doc and spelling fixes Signed-off-by: Martin Girardot * Restyled by gn * Restyled by prettier-markdown * Restyled by prettier-markdown * [NXP][workflows] Update docker image version Signed-off-by: Martin Girardot --------- Signed-off-by: Martin Girardot Signed-off-by: marius-alex-tache Signed-off-by: Gatien Chapon Signed-off-by: Dina Benamar Co-authored-by: Restyled.io Co-authored-by: marius-alex-tache Co-authored-by: Gatien Chapon Co-authored-by: Dina Benamar --- .github/workflows/examples-nxp.yaml | 2 +- docs/guides/nxp/nxp_manufacturing_flow.md | 76 +- docs/guides/nxp/nxp_mcxw71_ota_guide.md | 179 ++++ .../nxp/nxp_rw61x_ota_software_update.md | 71 +- .../all-clusters-app/nxp/rt/rw61x/BUILD.gn | 27 +- .../all-clusters-app/nxp/rt/rw61x/README.md | 98 ++- examples/contact-sensor-app/nxp/README.md | 195 +++++ examples/contact-sensor-app/nxp/k32w1/.gn | 2 +- .../contact-sensor-app/nxp/k32w1/BUILD.gn | 28 +- .../contact-sensor-app/nxp/k32w1/README.md | 452 ++-------- .../contact-sensor-app/nxp/k32w1/args.gni | 1 + .../laundry-washer-app/nxp/rt/rw61x/BUILD.gn | 18 +- examples/lighting-app/nxp/README.md | 137 +++ examples/lighting-app/nxp/k32w1/.gn | 2 +- examples/lighting-app/nxp/k32w1/BUILD.gn | 30 +- examples/lighting-app/nxp/k32w1/README.md | 450 ++-------- examples/lighting-app/nxp/k32w1/args.gni | 5 +- .../source/CommonDeviceCallbacks.cpp | 3 +- .../app/ldscripts/k32w1_app.ld | 0 .../project_include/freeRTOS/FreeRTOSConfig.h | 0 .../openthread/OpenThreadConfig.h | 0 .../app/support/BUILD.gn | 0 .../app/support/FreeRtosHooks.c | 0 .../app/support/FreeRtosHooks.h | 0 .../app/support/Memconfig.cpp | 0 .../board/peripherals.c | 0 .../board/peripherals.h | 0 .../button/ButtonManager.cpp | 0 .../button/ButtonManager.h | 0 .../clusters/Identify.cpp | 0 .../doc/images/debug_k32w1.jpg | Bin .../doc/images/import_demo.jpg | Bin .../doc/images/installed_sdks.jpg | Bin .../doc/images/k32w1-evk.jpg | Bin .../doc/images/mcux-sdk-download.jpg | Bin .../doc/images/new_project.jpg | Bin .../doc/images/ota_topology.JPG | Bin .../source/AppFactoryDataExample.cpp | 0 .../OperationalKeystore.cpp | 0 .../{k32w1 => mcxw71_k32w1}/ota/OtaUtils.cpp | 0 .../{k32w1 => mcxw71_k32w1}/rpc/AppRpc.cpp | 0 .../util/LedDimmer.cpp | 0 .../{k32w1 => mcxw71_k32w1}/util/LedOnOff.cpp | 0 .../util/LightingManagerDimmable.cpp | 0 .../util/LightingManagerDimmable.h | 0 .../source/AppFactoryDataExample.cpp | 11 + examples/thermostat/nxp/rt/rw61x/BUILD.gn | 18 +- scripts/build/builders/nxp.py | 9 +- scripts/setup/nxp/update_nxp_sdk.py | 120 --- .../nxp/factory_data_generator/generate.py | 17 +- .../nxp/common/ConfigurationManagerImpl.cpp | 1 - .../nxp/common/ConnectivityManagerImpl.cpp | 153 +++- .../nxp/common/ConnectivityManagerImpl.h | 15 +- src/platform/nxp/common/DnssdImpl.cpp | 793 +++++++++++------- src/platform/nxp/common/NXPConfig.h | 2 +- src/platform/nxp/common/ram_storage.c | 8 +- .../BLEManagerImpl.cpp | 2 +- .../{k32w1 => mcxw71_k32w1}/BLEManagerImpl.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/BUILD.gn | 8 +- .../BlePlatformConfig.h | 0 .../CHIPCryptoPalK32W1.cpp | 0 .../CHIPDevicePlatformConfig.h | 0 .../CHIPDevicePlatformEvent.h | 0 .../CHIPPlatformConfig.h | 0 .../ConfigurationManagerImpl.cpp | 2 +- .../ConfigurationManagerImpl.h | 2 +- .../ConnectivityManagerImpl.cpp | 0 .../ConnectivityManagerImpl.h | 0 .../DiagnosticDataProviderImpl.cpp | 2 +- .../DiagnosticDataProviderImpl.h | 0 .../FactoryDataDriverImpl.cpp | 2 +- .../FactoryDataDriverImpl.h | 0 .../FactoryDataProviderImpl.cpp | 2 +- .../FactoryDataProviderImpl.h | 0 .../InetPlatformConfig.h | 0 .../{k32w1 => mcxw71_k32w1}/K32W1Config.cpp | 2 +- .../nxp/{k32w1 => mcxw71_k32w1}/K32W1Config.h | 0 .../K32W1PersistentStorageOpKeystore.cpp | 0 .../K32W1PersistentStorageOpKeystore.h | 0 .../KeyValueStoreManagerImpl.cpp | 2 +- .../KeyValueStoreManagerImpl.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/Logging.cpp | 0 .../{k32w1 => mcxw71_k32w1}/LowPowerHooks.cpp | 0 .../OTAFirmwareProcessor.cpp | 2 +- .../OTAFirmwareProcessor.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/OTAHooks.cpp | 4 +- .../PlatformManagerImpl.cpp | 6 +- .../PlatformManagerImpl.h | 0 .../{k32w1 => mcxw71_k32w1}/SMU2Manager.cpp | 0 .../nxp/{k32w1 => mcxw71_k32w1}/SMU2Manager.h | 0 .../SystemPlatformConfig.h | 0 .../SystemTimeSupport.cpp | 0 .../ThreadStackManagerImpl.cpp | 2 +- .../ThreadStackManagerImpl.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/args.gni | 12 +- .../ble_function_mux.c | 0 .../ble_function_mux.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/gatt_db.h | 0 .../{k32w1 => mcxw71_k32w1}/gatt_uuid128.h | 0 .../k32w1-chip-mbedtls-config.h | 0 .../nxp/{k32w1 => mcxw71_k32w1}/ram_storage.c | 0 .../nxp/{k32w1 => mcxw71_k32w1}/ram_storage.h | 0 src/platform/nxp/rt/rw61x/BUILD.gn | 56 +- .../nxp/rt/rw61x/CHIPPlatformConfig.h | 2 +- src/platform/nxp/rt/rw61x/ELSFactoryData.c | 453 ---------- src/platform/nxp/rt/rw61x/ELSFactoryData.h | 247 ------ .../rt/rw61x/FactoryDataProviderEncImpl.cpp | 481 +++++++++++ .../nxp/rt/rw61x/FactoryDataProviderEncImpl.h | 87 ++ .../nxp/rt/rw61x/FactoryDataProviderImpl.cpp | 674 ++------------- .../nxp/rt/rw61x/FactoryDataProviderImpl.h | 4 +- .../nxp/rt/rw61x/PlatformManagerImpl.cpp | 6 +- src/platform/nxp/rt/rw61x/args.gni | 10 +- third_party/nxp/nxp_matter_support | 2 +- third_party/openthread/ot-nxp | 2 +- .../nxp/{k32w1 => mcxw71_k32w1}/BUILD.gn | 6 +- .../platforms/nxp/rt/rw61x/BUILD.gn | 28 +- 116 files changed, 2219 insertions(+), 2812 deletions(-) create mode 100644 docs/guides/nxp/nxp_mcxw71_ota_guide.md create mode 100644 examples/contact-sensor-app/nxp/README.md create mode 100644 examples/lighting-app/nxp/README.md rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/ldscripts/k32w1_app.ld (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/project_include/freeRTOS/FreeRTOSConfig.h (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/project_include/openthread/OpenThreadConfig.h (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/support/BUILD.gn (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/support/FreeRtosHooks.c (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/support/FreeRtosHooks.h (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/app/support/Memconfig.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/board/peripherals.c (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/board/peripherals.h (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/button/ButtonManager.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/button/ButtonManager.h (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/clusters/Identify.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/debug_k32w1.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/import_demo.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/installed_sdks.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/k32w1-evk.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/mcux-sdk-download.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/new_project.jpg (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/doc/images/ota_topology.JPG (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/factory_data/source/AppFactoryDataExample.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/operational_keystore/OperationalKeystore.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/ota/OtaUtils.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/rpc/AppRpc.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/util/LedDimmer.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/util/LedOnOff.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/util/LightingManagerDimmable.cpp (100%) rename examples/platform/nxp/{k32w1 => mcxw71_k32w1}/util/LightingManagerDimmable.h (100%) delete mode 100755 scripts/setup/nxp/update_nxp_sdk.py rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/BLEManagerImpl.cpp (98%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/BLEManagerImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/BUILD.gn (96%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/BlePlatformConfig.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/CHIPCryptoPalK32W1.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/CHIPDevicePlatformConfig.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/CHIPDevicePlatformEvent.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/CHIPPlatformConfig.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ConfigurationManagerImpl.cpp (99%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ConfigurationManagerImpl.h (98%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ConnectivityManagerImpl.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ConnectivityManagerImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/DiagnosticDataProviderImpl.cpp (99%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/DiagnosticDataProviderImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/FactoryDataDriverImpl.cpp (98%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/FactoryDataDriverImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/FactoryDataProviderImpl.cpp (99%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/FactoryDataProviderImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/InetPlatformConfig.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/K32W1Config.cpp (99%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/K32W1Config.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/K32W1PersistentStorageOpKeystore.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/K32W1PersistentStorageOpKeystore.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/KeyValueStoreManagerImpl.cpp (99%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/KeyValueStoreManagerImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/Logging.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/LowPowerHooks.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/OTAFirmwareProcessor.cpp (98%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/OTAFirmwareProcessor.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/OTAHooks.cpp (97%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/PlatformManagerImpl.cpp (96%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/PlatformManagerImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/SMU2Manager.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/SMU2Manager.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/SystemPlatformConfig.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/SystemTimeSupport.cpp (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ThreadStackManagerImpl.cpp (98%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ThreadStackManagerImpl.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/args.gni (89%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ble_function_mux.c (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ble_function_mux.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/gatt_db.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/gatt_uuid128.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/k32w1-chip-mbedtls-config.h (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ram_storage.c (100%) rename src/platform/nxp/{k32w1 => mcxw71_k32w1}/ram_storage.h (100%) delete mode 100644 src/platform/nxp/rt/rw61x/ELSFactoryData.c delete mode 100644 src/platform/nxp/rt/rw61x/ELSFactoryData.h create mode 100644 src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp create mode 100644 src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h rename third_party/openthread/platforms/nxp/{k32w1 => mcxw71_k32w1}/BUILD.gn (93%) diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 04094f0b20480d..050751457645d4 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -150,7 +150,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-rw61x:74 + image: ghcr.io/project-chip/chip-build-nxp:74 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/docs/guides/nxp/nxp_manufacturing_flow.md b/docs/guides/nxp/nxp_manufacturing_flow.md index bad70db294a9ae..cb8431cc3b3083 100644 --- a/docs/guides/nxp/nxp_manufacturing_flow.md +++ b/docs/guides/nxp/nxp_manufacturing_flow.md @@ -247,24 +247,58 @@ adding the following gn argument `chip_use_plain_dac_key=true`. Supported platforms: -- RW61X - `src/plaftorm/nxp/rt/rw61x/FactoryDataProviderImpl.h` - -For platforms that have a secure subsystem (`SE50`), the DAC private key can be -converted to an encrypted blob. This blob will overwrite the DAC private key in -factory data and will be imported in the `SE50` before to sign, by the factory -data provider instance. - -The conversion process shall happen at manufacturing time and should be run one -time only: - -- Write factory data binary. -- Build the application with - `chip_with_factory_data=1 chip_convert_dac_private_key=1` set. -- Write the application to the board and let it run. - -After the conversion process: - -- Make sure the application is built with `chip_with_factory_data=1`, but - without `chip_convert_dac_private_key` arg, since conversion already - happened. -- Write the application to the board. +- RW61X + +there are three implementations for factory data protection + +- whole factory data protection with AES encryption ( chip_with_factory_data=1 + chip_enable_secure_whole_factory_data=true ) + `examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp`\ + `src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp` + +- only dac private key protection ( chip_with_factory_data=1 + chip_enable_secure_dac_private_key_storage=true ) + `examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp` + \ + `src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp` + +- whole factory data protection with hard-coded AES key ( + chip_with_factory_data=1 ) + `examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp` + \ + `src/platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.cpp` + +for the first one, the whole factory data is encrypted by an AES-256 key, the +AES key can be passed through serial link when in factory production mode, and +will be provisioned into Edge Lock, and the returned AES Key blob (wrapped key) +can be stored in the end of factory data region in TLV format. for the +decryption process, the blob is retrieved and provisioned into Edge Lock and the +whole factory data can be decrypted using the returned key index in Edge Lock. +Compared with only dac private key protection solution, this solution can avoid +tampering with the original factory data. + +the factory data should be encrypted by an AES-256 key using "--aes256_key" +option in "generate.py" script file. + +it will check whether there is AES key blob in factory data region when in each +initialization, if not, the default AES key is converted and the result is +stored into flash, it run only once. + +for the second one, it only protect the dac private key inside the factory data, +the dac private key is retrieved and provisioned into Edge Lock, the returned +key blob replace the previous dac private key, and also update the overall size +and hash, and re-write the factory data. when device is doing matter +commissioning, the blob is retrieved and provisioned into Edge Lock and the +signing can be done using the returned key index in Edge Lock. + +the factory data should be plain text for the first programming. it will check +whether there is dac private key blob (base on the size of blob, should be 48) +in factory data when in each initialization, if not, the dac private key is +converted and the result is stored into flash, it run only once. + +for the third one, it is a little similar to the first one, the whole factory +data is encrypted by an AES key, but there are two differences: + +- the AES key is hard-coded and not provisioned into Edge Lock +- the factory data should be encrypted by AES-128 key using "--aes128_key" + option in "generate.py" script file. diff --git a/docs/guides/nxp/nxp_mcxw71_ota_guide.md b/docs/guides/nxp/nxp_mcxw71_ota_guide.md new file mode 100644 index 00000000000000..b21bf933d7e98e --- /dev/null +++ b/docs/guides/nxp/nxp_mcxw71_ota_guide.md @@ -0,0 +1,179 @@ +# NXP `MCXW71/K32W1` OTA guide + +### Convert `srec` into `sb3` file + +The OTA image files must be encrypted using Over The Air Programming Tool +([OTAP](https://www.nxp.com/design/microcontrollers-developer-resources/connectivity-tool-suite:CONNECTIVITY-TOOL-SUITE?#downloads)). +Bootloader will load the new OTA image only if it detects that the file was +encrypted with the `OTAP` correct keys. + +`.srec` file is input for Over The air Programming (`OTAP`) application +(unencrypted) and it's converted to `.sb3` format (encrypted). + +In `OTAP` application + +- select OTA protocol => `OTAP` Matter +- Browse File +- follow default options (KW45/K32W148, Preserve NVM) +- image information: will update "Application Core (MCU)" - this will generate + the image only for the CM33 core +- keep other settings at default values + +### Generate `ota` file + +In order to build an OTA image, use the NXP wrapper over the standard tool +`src/app/ota_image_tool.py`: + +- `scripts/tools/nxp/ota/ota_image_tool.py` + +The tool can be used to generate an OTA image with the following format: + +``` + | OTA image header | TLV1 | TLV2 | ... | TLVn | +``` + +where each TLV is in the form `|tag|length|value|`. + +Note that "standard" TLV format is used. Matter TLV format is only used for +factory data TLV value. + +Please see more in the +[OTA image tool guide](../../../scripts/tools/nxp/ota/README.md). + +Here is an example that generates an OTA image with application update TLV from +an `.sb3` file: + +``` +./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 --app-input-file ~/binaries/chip-mcxw71-app.sb3 ~/binaries/chip-mcxw71-app.ota + +``` + +A note regarding OTA image header version (`-vn` option). An application binary +has its own software version (given by +`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION`, which can be overwritten). In +order to have a correct OTA process, the OTA header version should be the same +as the binary embedded software version. A user can set a custom software +version in the gn build args by setting `nxp_software_version` to the wanted +version. + +### OTA factory data + +A user can update the factory data through OTA, at the same time the application +firmware is updated by enabling the following processor in the `gn args`: + +- `chip_enable_ota_factory_data_processor=1` to enable default factory data + update processor (disabled by default). + +The OTA image used must be updated to include the new factory data. + +[OTA image tool guide](../../../scripts/tools/nxp/ota/README.md). + +### Running OTA + +The OTA topology used for OTA testing is illustrated in the figure below. +Topology is similar with the one used for Matter Test Events. + +![OTA_TOPOLOGY](../../../examples/platform/nxp/mcxw71_k32w1/doc/images/ota_topology.JPG) + +The concept for OTA is the next one: + +- there is an OTA Provider Application that holds the OTA image. In our case, + this is a Linux application running on an Ubuntu based-system; +- the OTA Requestor functionality is embedded inside the reference + application. It will be used for requesting OTA blocks from the OTA + Provider; +- the controller (a linux application called chip-tool) will be used for + commissioning both the device and the OTA Provider App. The device will be + commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the + OTA Provider Application will be commissioned using the `onnetwork` option + of `chip-tool`; +- during commissioning, each device is assigned a node id by the chip-tool + (can be specified manually by the user). Using the node id of the device and + of the reference application, chip-tool triggers the OTA transfer by + invoking the `announce-ota-provider` command - basically, the OTA Requestor + is informed of the node id of the OTA Provider Application. + +_Computer #1_ can be any system running an Ubuntu distribution. We recommand +using CSA official instructions from +[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are +proposed. Also, CSA official instructions document point to the OS/Docker images +that should be used on the RPis. For compatibility reasons, we recommand +compiling chip-tool and OTA Provider applications with the same commit id that +was used for compiling the reference application. Also, please note that there +is a single controller (chip-tool) running on Computer #1 which is used for +commissioning both the device and the OTA Provider Application. If needed, +[these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be +used for connecting the RPis to WiFi. + +Build the Linux OTA provider application: + +``` +user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false +``` + +Build Linux `chip-tool`: + +``` +user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool-app +``` + +Start the OTA Provider Application: + +``` +user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* +user@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-mcxw71-app.ota +``` + +Provision the OTA provider application and assign node id _1_. Also, grant ACL +entries to allow OTA requestors: + +``` +user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing onnetwork 1 20202021 +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 1 0 +``` + +Provision the device and assign node id _2_: + +``` +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing ble-thread 2 hex: 20202021 3840 +``` + +Start the OTA process: + +``` +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0 +``` + +### Known issues + +- SRP cache on the openthread border router needs to flushed each time a new + commissioning process is attempted. For this, factory reset the device, then + execute `ot-ctl server disable` followed by `ot-ctl server enable`. After + this step, the commissioning process of the device can start; +- Due to some MDNS issues, the commissioning of the OTA Provider Application + may fail. Please make sure that the SRP cache is disabled + (`ot-ctl srp server disable`) on the openthread border router while + commissioning the OTA Provider Application; +- No other Docker image should be running (e.g.: Docker image needed by Test + Harness) except the OTBR one. A docker image can be killed using the + command: + + ``` + user@computer1:~/connectedhomeip$ : sudo docker kill $container_id + ``` + +- In order to avoid MDNS issues, only one interface should be active at one + time. E.g.: if WiFi is used then disable the Ethernet interface and also + disable multicast on that interface: + + ``` + user@computer1:~/connectedhomeip$ sudo ip link set dev eth0 down + user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast + ``` + +- If OTBR Docker image is used, then the "-B" parameter should point to the + interface used for the backbone. + +- If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected. + Otherwise, issues related to BLE-WiFi combo may appear. diff --git a/docs/guides/nxp/nxp_rw61x_ota_software_update.md b/docs/guides/nxp/nxp_rw61x_ota_software_update.md index 1543b2f94402cf..af67b1419d0526 100644 --- a/docs/guides/nxp/nxp_rw61x_ota_software_update.md +++ b/docs/guides/nxp/nxp_rw61x_ota_software_update.md @@ -48,10 +48,9 @@ MCUBoot is an open-source secure bootloader used by RW61x to apply the self-upgrade. For more details, please refer to the [MCUBoot documentation](https://github.com/mcu-tools/mcuboot/blob/main/docs/design.md). -In our use case, the bootloader runs the application residing in the primary -partition. In order to run the OTA update image, the bootloader will swap the -content of the primary and the secondary partitions. This type of upgrade is -called swap-move and is the default upgrade configured by MCUBoot. +For RW61x platform, the bootloader is configured to use the flash remapping +mechanism by default, in order to perform the image upgrade. This is achieved by +using the `MCUBoot DIRECT-XIP` upgrade mode. ## OTA Software Update process for RW61x example application @@ -86,47 +85,42 @@ J-Link > exec EnableEraseAllFlashBanks J-Link > erase 0x8000000, 0x88a0000 ``` -- Using MCUXPresso, import the `mcuboot_opensource` demo example from the SDK - previously downloaded. The example can be found under the `ota_examples` - folder. - ![mcuboot_demo](../../../examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG) -- Before building the demo example, it should be specified that the - application to be run by the bootloader is monolithic. As a result, only one - image will be upgraded by the bootloader. This can be done by defining - `MONOLITHIC_APP` as 1 in the settings of the `mcuboot_opensource` project : +- MCUBoot application can be built with SDK installed, using instructions + + below. + +- Retrieve the mcuboot directory with : ``` -Right click on the Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> MCU C Compiler -> Preprocessor -> Add "MONOLITHIC_APP=1" in the Defined Symbols +user@ubuntu: cd ~/Desktop/connectedhomeip/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/armgcc ``` -![rw610_mcuboot_monolithic](../../../examples/platform/nxp/rt/rw61x/doc/images/mcuboot_monolithic_app.PNG) +``: Supported rw612 boards are: `rdrw612bga` or `frdmrw612` -- Build the demo example project. +- Build the mcuboot application : ``` -Right click on the Project -> Build Project +user@ubuntu: chmod +x build_flash_release.sh +user@ubuntu: export ARMGCC_DIR=/opt/gcc-arm-none-eabi-10.3-2021.10 # with ARMGCC_DIR referencing the compiler path +user@ubuntu: ./build_flash_release.sh ``` -- Program the demo example to the target board. +- Program the generated binary to the target board. ``` -Right click on the Project -> Debug -> As->SEGGER JLink probes -> OK -> Select elf file +J-Link > loadbin ~/Desktop/connectedhomeip/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/armgcc/flash_release/mcuboot_opensource.elf ``` -Note : The mcuboot binary is loaded in flash at address 0x8000000. - -- To run the flashed demo, either press the reset button of the device or use - the debugger IDE of MCUXpresso. If it runs successfully, the following logs - will be displayed on the terminal : +- If it runs successfully, the following logs will be displayed on the + terminal : ``` hello sbl. -Bootloader Version 1.9.0 -Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 -Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 -Boot source: none -Swap type: none -erasing trailer; fa_id=2 +Disabling flash remapping function +Bootloader Version 2.0.0 +Image 0 Primary slot: Image not found +Image 0 Secondary slot: Image not found +No slot to load for image 0 Unable to find bootable image ``` @@ -135,7 +129,7 @@ partitions to be the size of 4.4 MB. If the size is to be changed, the partition addresses should be modified in the flash_partitioning.h accordingly. For more information about the flash partitioning with mcuboot, please refer to the dedicated readme.txt located in -"`SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/`". +"`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/`". ### Generating and flashing the signed application image @@ -162,15 +156,15 @@ arm-none-eabi-objcopy -R .flash_config -R .NVM -O binary chip-rw61x-all-cluster- To sign the image and wrap the raw binary of the application with the header and trailer, "`imgtool`" is provided in the SDK and can be found in -"`/middleware/mcuboot_opensource/scripts/`". +"`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/middleware/mcuboot_opensource/scripts/`". The following commands can be run (make sure to replace the /path/to/file/binary with the adequate files): ``` -user@ubuntu: cd ~/Desktop/SDK_RW612/middleware/mcuboot_opensource/scripts +user@ubuntu: cd ~/Desktop//third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/middleware/mcuboot_opensource/scripts/ -user@ubuntu: python3 imgtool.py sign --key ~/Desktop/SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem --align 4 --header-size 0x1000 --pad-header --slot-size 0x440000 --max-sectors 1088 --version "1.0" ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example.bin ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example_SIGNED.bin +user@ubuntu: python3 imgtool.py sign --key ~/Desktop//third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem --align 4 --header-size 0x1000 --pad-header --pad --confirm --slot-size 0x440000 --max-sectors 1088 --version "1.0" ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example.bin ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example_SIGNED.bin ``` Notes : @@ -182,7 +176,7 @@ Notes : adjusted accordingly. - In this example, the image is signed with the private key provided by the SDK as an example - (`SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem`), + (`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem`), MCUBoot is built with its corresponding public key which would be used to verify the integrity of the image. It is possible to generate a new pair of keys using the following commands. This procedure should be done prior to @@ -201,7 +195,7 @@ user@ubuntu: python3 imgtool.py getpub -k priv_key.pem ``` - The extracted public key can then be copied to the - `SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/keys/sign-rsa2048-pub.c`, + `/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-pub.c`, given as a value to the rsa_pub_key[] array. The resulting output is the signed binary of the application version "1.0". @@ -221,11 +215,12 @@ application and run it. To generate the OTA update image the same procedure can be followed from the [Generating and flashing the signed application image](#generating-and-flashing-the-signed-application-image) sub-section, replacing the "--version "1.0"" argument with "--version "2.0"" -(recent version of the update). +(recent version of the update), without arguments "--pad" "--confirm" when +running `imgtool` script during OTA Update Image generation. Note : When building the update image, the build arguments -`nxp_software_version=2 nxp_sofware_version_string=\"2.0\"` can be added to the -`gn gen` command in order to specify the upgraded version. +nxp_software_version=2 nxp_software_version_string=\"2.0\" can be added to the +gn gen command in order to specify the upgraded version. When the signed binary of the update is generated, the file should be converted into OTA format. To do so, the ota_image_tool is provided in the repo and can be diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index e6bf8d64d94524..b0e1c1c47a98ea 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -65,7 +65,8 @@ rt_sdk("sdk") { defines = [] # To be moved, temporary mbedtls config fix to build app with factory data - if (chip_enable_secure_dac_private_key_storage == 1) { + if (chip_enable_secure_dac_private_key_storage || + chip_enable_secure_whole_factory_data) { defines += [ "MBEDTLS_NIST_KW_C", "MBEDTLS_PSA_CRYPTO_CLIENT", @@ -82,10 +83,18 @@ rt_sdk("sdk") { include_dirs += [ "${example_platform_dir}/board/" ] sources += [ "${example_platform_dir}/board/pin_mux.c" ] sources += [ "${example_platform_dir}/board/hardware_init.c" ] - sources += [ "${example_platform_dir}/board/clock_config.c" ] - sources += [ "${example_platform_dir}/board/board.c" ] sources += [ "${example_platform_dir}/board/peripherals.c" ] + if (board_version == "frdm") { + include_dirs += [ "${example_platform_dir}/board/frdmrw612/" ] + sources += [ "${example_platform_dir}/board/frdmrw612/clock_config.c" ] + sources += [ "${example_platform_dir}/board/frdmrw612/board.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/rdrw612bga/" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/clock_config.c" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/board.c" ] + } + # Indicate the path to CHIPProjectConfig.h include_dirs += [ "include/config" ] @@ -97,7 +106,7 @@ rt_sdk("sdk") { # For matter with BR feature, increase FreeRTOS heap size if (chip_enable_wifi && chip_enable_openthread) { - defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] } defines += [ @@ -141,10 +150,12 @@ rt_executable("all_cluster_app") { "../../common/main/main.cpp", ] - if (chip_enable_secure_dac_private_key_storage == 1) { - sources += [ - "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", - ] + if (chip_enable_secure_dac_private_key_storage || + chip_enable_secure_whole_factory_data) { + sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] + if (chip_enable_secure_whole_factory_data) { + defines += [ "ENABLE_SECURE_WHOLE_FACTORY_DATA" ] + } } else { sources += [ "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index bdec2c58956274..9356e4b8fe3617 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -37,52 +37,70 @@ The example supports: For Matter over Thread configuration : -- [`NXP RD-RW612-BGA`] board -- BLE/15.4 antenna (to plug in Ant1) +- For [`NXP RD-RW612-BGA`] board: BLE/15.4 antenna (to plug in Ant1) +- For [`NXP FRDM-RW612`] board: no external antenna needed (embedded PCB + antenna) For Matter over WiFi configuration : -- [`NXP RD-RW612-BGA`] or [`NXP RD-RW610-BGA`] board -- BLE antenna (to plug in Ant1) -- Wi-Fi antenna (to plug in Ant2) +- For [`NXP RD-RW612-BGA`] or [`NXP RD-RW610-BGA`] board: BLE antenna (to plug + in Ant1) + Wi-Fi antenna (to plug in Ant2) +- For [`NXP FRDM-RW612`] board: no external antenna needed (embedded PCB + antenna) For Matter over Wi-Fi with OpenThread Border Router : -- [`NXP RD-RW612-BGA`] board -- BLE/15.4 antenna (to plug in Ant1) -- Wi-Fi antenna (to plug in Ant2) +- For [`NXP RD-RW612-BGA`] board: BLE/15.4 antenna (to plug in Ant1) + Wi-Fi + antenna (to plug in Ant2) +- For [`NXP FRDM-RW612`] board: no external antenna needed (embedded PCB + antenna) ## Building In order to build the Project CHIP example, we recommend using a Linux -distribution (the demo-application was compiled on Ubuntu 20.04). +distribution (supported Operating Systems are listed in +[BUILDING.md](../../../../../docs/guides/BUILDING.md#prerequisites)). -- Follow instruction in [BUILDING.md](../../../../../docs/guides/BUILDING.md) - to setup the environment to be able to build Matter. +- Make sure that below prerequisites are correctly installed (as described in + [BUILDING.md](../../../../../docs/guides/BUILDING.md#prerequisites))) -- Download - [RD-RW612 SDK for Project CHIP](https://mcuxpresso.nxp.com/en/select). - Creating an nxp.com account is required before being able to download the - SDK. Once the account is created, login and follow the steps for downloading - SDK. The SDK Builder UI selection should be similar with the one from the - image below. +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ + libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ + python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` - ![MCUXpresso SDK Download](../../../../platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG) +- Step 1: checkout NXP specific submodules only - (Note: All SDK components should be selected. If size is an issue Azure RTOS - component can be omitted.) +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive +``` - Please refer to Matter release notes for getting the latest released SDK. +- Step 2: activate local environment -- Start building the application. +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh +``` + +If the script says the environment is out of date, you can update it by running +the following command: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh +``` + +- Step 3: Init NXP SDK(s) + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform common +``` + +Note: By default update_nxp_sdk.py will try to initialize all NXP SDKs. Arg "-- +help" could be used to view all available options. ``` -user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_SDK_ROOT=/home/user/Desktop/SDK_RW612/ -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive -user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/bootstrap.sh -user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/all-clusters-app/nxp/rt/rw61x/ ``` @@ -91,7 +109,7 @@ user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/all-clusters-app/nxp/rt/r - Build Matter-over-Wifi configuration with BLE commissioning (ble-wifi) : ``` -user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ gn gen --args="chip_enable_wifi=true is_sdk_package=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ gn gen --args="chip_enable_wifi=true" out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ ninja -C out/debug ``` @@ -100,7 +118,7 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x - Build Matter-over-Thread configuration with BLE commissioning. ``` -user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ gn gen --args="chip_enable_openthread=true chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true is_sdk_package=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ gn gen --args="chip_enable_openthread=true chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true" out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ ninja -C out/debug ``` @@ -113,7 +131,7 @@ Thread network on the Border Router. (ble-wifi) : ``` -user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw610$ gn gen --args="chip_enable_wifi=true chip_enable_openthread=true chip_enable_matter_cli=true is_sdk_package=true openthread_root=\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\"" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw610$ gn gen --args="chip_enable_wifi=true chip_enable_openthread=true chip_enable_matter_cli=true" out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw610$ ninja -C out/debug ``` @@ -128,12 +146,9 @@ Optional GN options that can be added when building an application: [matter CLI](README.md#testing-the-all-clusters-application-with-matter-cli-enabled), the argument `chip_enable_matter_cli=true` must be added to the _gn gen_ command. -- To switch the SDK type used, the argument `is_=true` must be added - to the _gn gen_ command (with being either sdk_package or - sdk_internal). -- By default, the RW612 A1 board revision will be chosen. To switch to an A2 - revision, the argument `board_version=\"A2\"` must be added to the _gn gen_ - command. +- By default, the `NXP RD-RW612-BGA` board revision will be chosen. To switch + to `NXP FRDM-RW612` board revision, the argument `board_version=\"frdm\"` + must be added to the _gn gen_ command. - To build the application in debug mode, the argument `is_debug=true optimize_debug=false` must be added to the _gn gen_ command. - To build with the option to have Matter certificates/keys pre-loaded in a @@ -215,9 +230,6 @@ Right click on the Project -> C/C++ Build-> Tool Chain Editor -> NXP MCU Tools - Right click on the Project -> Debug -> As->SEGGER JLink probes -> OK -> Select elf file ``` -(Note : if SDK package is used, a simpler way could be duplicating the debug -configuration from the SDK Hello World example after importing it.) - - Debug using the newly created configuration file. @@ -261,6 +273,10 @@ using the matter shell, follow instructions from In this configuration, the device can be commissioned over Wi-Fi with the 'ble-wifi' pairing method. +### NVM + +By default the file system used by the application is NVS. + ### Testing the all-clusters application without Matter CLI: 1. Prepare the board with the flashed `All-cluster application` (as shown @@ -319,8 +335,10 @@ Here are described steps to use the all-cluster-app with the Matter CLI enabled 3. The All-cluster example uses UART2 (`FlexComm0`) to print logs while running the server. To view raw UART output, a pin should be plugged to an USB to - UART adapter (connector `HD2 pin 03`), then start a terminal emulator like - PuTTY and connect to the used COM port with the following UART settings: + UART adapter (connector `HD2 pin 03` for [`NXP RD-RW612-BGA`] board and + `J5 pin 4` (`mikroBUS`: TX) for [`NXP FRDM-RW612`] board), then start a + terminal emulator like PuTTY and connect to the used COM port with the + following UART settings: - Baud rate: 115200 - 8 data bits diff --git a/examples/contact-sensor-app/nxp/README.md b/examples/contact-sensor-app/nxp/README.md new file mode 100644 index 00000000000000..473afb793f9700 --- /dev/null +++ b/examples/contact-sensor-app/nxp/README.md @@ -0,0 +1,195 @@ +# Matter NXP Contact Sensor Example Application + +This reference application implements a Contact Sensor device type. It uses +board buttons or `matter-cli` for user input and LEDs for state feedback. You +can use this example as a reference for creating your own application. + +The example is based on: + +- [Matter](https://github.com/project-chip/connectedhomeip) +- [NXP github SDK](https://github.com/nxp-mcuxpresso/mcux-sdk) + +- [Matter NXP Contact Sensor Example Application](#matter-nxp-contact-sensor-example-application) + - [Supported devices](#supported-devices) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Prerequisites for building](#prerequisites-for-building) + - [Building](#building) + - [Data model](#data-model) + - [Manufacturing data](#manufacturing-data) + - [Long Idle Time ICD Support](#long-idle-time-icd-support) + - [Low power](#low-power) + - [Flashing and debugging](#flashing-and-debugging) + +## Supported devices + +- [k32w1](k32w1/README.md) + +## Introduction + +The application showcases a contact sensor that communicates with clients over a +low-power, 802.15.4 Thread network. + +It can be commissioned into an existing Matter network using a controller such +as `chip-tool`. + +This example implements a `User-Intent Commissioning Flow`, meaning the user has +to press a button in order for the device to be ready for commissioning. The +initial commissioning is done through `ble-thread` pairing method. + +The Thread network dataset will be transferred on the device using a secure +session over Bluetooth LE. In order to start the commissioning process, the user +must enable BLE advertising on the device manually. To pair successfully, the +commissioner must know the commissioning information corresponding to the +device: setup passcode and discriminator. This data is usually encoded within a +QR code or printed to the UART console. + +## Device UI + +The example application provides a simple UI that depicts the state of the +device and offers basic user control. This UI is implemented via the +general-purpose LEDs and buttons built in the evaluation boards. Please see each +supported device readme file for details. + +## Prerequisites for building + +In order to build the example, it is recommended to use a Linux distribution. +Please visit the supported Operating Systems list in +[BUILDING.md](../../../docs/guides/BUILDING.md#prerequisites). + +- Make sure that below prerequisites are correctly installed (as described in + [BUILDING.md](../../../docs/guides/BUILDING.md#prerequisites)) + +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` + +- Step 1: checkout NXP specific submodules only + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive + ``` + +- Step 2: activate local environment + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh + ``` + + If the script says the environment is out of date, you can update it by + running the following command: + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh + ``` + +- Step 3: Init NXP SDK(s) + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform common + ``` + +Note: By default, `update_nxp_sdk.py` will try to initialize all NXP SDKs. +Please run the script with arg `--help` to view all available options. + +## Building + +There are two options for building this reference app: + +- Using `build_examples.py` framework. +- Manually generating `ninja` files using `gn`. + +For manual generation and building, please see the specific readme file for your +device. + +A list of all available contact sensor targets can be viewed in the following +table: + +| target name | description | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| nxp-device-freertos-contact-sensor-low-power | Default low-power contact sensor | +| nxp-device-freertos-contact-sensor-low-power-factory | Default low-power contact sensor with factory data | +| nxp-device-freertos-contact-sensor-low-power-lit | Low-power contact sensor as LIT ICD | +| nxp-device-freertos-contact-sensor-low-power-sw-v2 | Low-power contact sensor with software version 2 (can be used to test OTA) | +| nxp-device-freertos-contact-sensor-low-power-factory-sw-v2 | Low-power contact sensor with factory data and software version 2 (can be used to test OTA) | + +where `device` can be one of the [Supported devices](#supported-devices). + +### Data model + +There are two available data models that can be used by the application: + +| path | description | +| -------------------------------- | ------------------------------ | +| `zap-lit/contact-sensor-app.zap` | Data model for LIT ICD support | +| `zap-sit/contact-sensor-app.zap` | Data model for SIT ICD support | + +The selection is done automatically by the build system based on the ICD +configuration. + +The data model can be changed by simply replacing the gn `deps` statement +corresponding to data model target. + +### Manufacturing data + +Use `chip_with_factory_data=1` in the gn build command to enable factory data. + +For a full guide on manufacturing flow, please see +[Guide for writing manufacturing data on NXP devices](../../../docs/guides/nxp/nxp_manufacturing_flow.md). + +### Long Idle Time ICD Support + +By default, the application is compiled as a SIT ICD (Short Idle Time +Intermittently Connected Device). + +This is a list of ICD configuration gn args. + +| gn arg | default value | description | +| ------------------------------------------------------------------------------ | ------------- | ---------------------------------------------------------------------------------------------------------- | +| nxp_ot_idle_interval_ms | 2000 (ms) | OT Idle Interval duration | +| nxp_ot_active_interval_ms | 500 (ms) | OT Active Interval duration | +| nxp_idle_mode_duration_s | 600 (s) | Idle Mode Interval duration | +| nxp_active_mode_duration_ms | 10000 (ms) | Active Mode Interval duration | +| nxp_active_mode_threshold_ms | 1000 (ms) | Active Mode Threshold value | +| nxp_icd_supported_clients_per_fabric | 2 | Registration slots per fabric | +| chip_enable_icd_lit | false | Enable LIT ICD support | +| chip_persist_subscriptions | true | Try once to re-establish subscriptions from the server side after reboot. May be disabled for LIT use case | +| chip_subscription_timeout_resumption | true | Same as above, but try to re-establish timeout out subscriptions | +| using `Fibonacci Backoff` for retries pacing. May be disabled for LIT use case | + +If LIT ICD support is needed then `chip_enable_icd_lit=true` must be specified +as gn argument and the above parameters must be modified to comply with LIT +requirements (e.g.: LIT devices must configure +`chip_ot_idle_interval_ms > 15000`). Example LIT configuration: + +``` +nxp_ot_idle_interval_ms = 15000 # 15s Idle Intervals +nxp_ot_active_interval_ms = 500 # 500ms Active Intervals +nxp_idle_mode_duration_s = 3600 # 60min Idle Mode Interval +nxp_active_mode_duration_ms = 0 # 0 Active Mode Interval +nxp_active_mode_threshold_ms = 30000 # 30s Active Mode Threshold +``` + +### Low power + +The example also offers the possibility to run in low power mode. This means +that the board will go in deep sleep most of the time and the power consumption +will be very low. + +In order to build with low power support, the following gn args must be used: + +``` +chip_with_low_power = 1 +chip_openthread_ftd = false +chip_with_ot_cli = 0 +chip_logging = false +``` + +In order to maintain a low power consumption, the UI LEDs are disabled. Console +logs can be used instead, but it might affect low power timings. Also, please +note that once the board is flashed with MCUXpresso the debugger disconnects +because the board enters low power. + +## Flashing and debugging + +Please see the device specific readme file. diff --git a/examples/contact-sensor-app/nxp/k32w1/.gn b/examples/contact-sensor-app/nxp/k32w1/.gn index 885f306753076d..6a134466e0067b 100644 --- a/examples/contact-sensor-app/nxp/k32w1/.gn +++ b/examples/contact-sensor-app/nxp/k32w1/.gn @@ -28,5 +28,5 @@ default_args = { import("//args.gni") # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w1/args.gni") + import("${chip_root}/src/platform/nxp/mcxw71_k32w1/args.gni") } diff --git a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn index 119dc5cf722eac..0e24893bd06737 100644 --- a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn @@ -40,7 +40,7 @@ assert(target_os == "freertos") example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" common_example_dir = "${chip_root}/examples/platform/nxp/common" -k32w1_sdk("sdk") { +mcxw71_k32w1_sdk("sdk") { defines = [] include_dirs = [] sources = [] @@ -55,20 +55,20 @@ k32w1_sdk("sdk") { include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] include_dirs += [ - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", ] sources += [ - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", ] if (is_debug) { @@ -90,7 +90,7 @@ k32w1_sdk("sdk") { } } -k32w1_executable("contact_sensor_app") { +mcxw71_k32w1_executable("contact_sensor_app") { output_name = "chip-k32w1-contact-example" defines = [] @@ -235,7 +235,7 @@ k32w1_executable("contact_sensor_app") { cflags = [ "-Wconversion" ] - ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" + ldscript = "${nxp_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" inputs = [ ldscript ] diff --git a/examples/contact-sensor-app/nxp/k32w1/README.md b/examples/contact-sensor-app/nxp/k32w1/README.md index 7a70f746f6e445..217f06e11906b6 100644 --- a/examples/contact-sensor-app/nxp/k32w1/README.md +++ b/examples/contact-sensor-app/nxp/k32w1/README.md @@ -1,162 +1,57 @@ # Matter K32W1 Contact Sensor Example Application -Matter K32W1 Contact Sensor Example uses buttons to test changing the lock and -device states and LEDs to show the state of these changes. You can use this -example as a reference for creating your own application. - -The example is based on -[Matter](https://github.com/project-chip/connectedhomeip) and the NXP K32W1 SDK, -and a simulated contact sensor over a low-power, 802.15.4 Thread network. - -The example behaves as a Matter accessory, that is a device that can be paired -into an existing Matter network and can be controlled by this network. - -
+For generic information related to contact sensor application, please see the +[common README](../README.md). - [Matter K32W1 Contact Sensor Example Application](#matter-k32w1-contact-sensor-example-application) - [Introduction](#introduction) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - - [Thread Provisioning](#thread-provisioning) - [Device UI](#device-ui) - [Building](#building) - - [Long Idle Time ICD Support](#long-idle-time-icd-support) - - [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the `NBU` image](#flashing-the-nbu-image) - [Flashing the host image](#flashing-the-host-image) - [Debugging](#debugging) - [OTA](#ota) - - [Convert `srec` into `sb3` file](#convert-srec-into-sb3-file) - - [Convert `sb3` into `ota` file](#convert-sb3-into-ota-file) - - [OTA factory data](#ota-factory-data) - - [Running OTA](#running-ota) - - [Low power](#low-power) - - [Known issues](#known-issues) ## Introduction -![K32W1 EVK](../../../platform/nxp/k32w1/doc/images/k32w1-evk.jpg) - -The K32W1 contact sensor example application provides a working demonstration of -a connected contact sensor device, built using the Matter codebase and the NXP -K32W1 SDK. The example supports remote access (e.g.: using CHIP Tool from a -mobile phone) and control of a simulated contact sensor over a low-power, -802.15.4 Thread network. It is capable of being paired into an existing Matter -network along with other Matter-enabled devices. - -The Matter device that runs the contact sensor application is controlled by the -Matter controller device over the Thread protocol. By default, the Matter device -has Thread disabled, and it should be paired over Bluetooth LE with the Matter -controller and obtain configuration from it. The actions required before -establishing full communication are described below. - -### Bluetooth LE Advertising - -In this example, to commission the device onto a Matter network, it must be -discoverable over Bluetooth LE. For security reasons, you must start Bluetooth -LE advertising manually after powering up the device by pressing Button SW2. - -### Bluetooth LE Rendezvous +This is a contact sensor application implemented for a k32w1 device. -In this example, the commissioning procedure (called rendezvous) is done over -Bluetooth LE between a Matter device and the Matter controller, where the -controller has the commissioner role. - -To start the rendezvous, the controller must get the commissioning information -from the Matter device. The data payload is encoded within a QR code, or printed -to the UART console. - -### Thread Provisioning +The following board was used when testing this Matter reference app for a +`k32w1` device: +![K32W1 EVK](../../../platform/nxp/mcxw71_k32w1/doc/images/k32w1-evk.jpg) ## Device UI -The example application provides a simple UI that depicts the state of the -device and offers basic user control. This UI is implemented via the -general-purpose LEDs and buttons built in the K32W1 EVK board. - -**LED 2** shows the overall state of the device and its connectivity. Four -states are depicted: - -- _Short Flash On (50ms on/950ms off)_ — The device is in an - unprovisioned (unpaired) state and is waiting for a commissioning - application to connect. +The state feedback is provided through LED effects: -* _Rapid Even Flashing (100ms on/100ms off)_ — The device is in an - unprovisioned state and a commissioning application is connected via BLE. +| widget | effect | description | +| ------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------- | +| LED2 | short flash on (50ms on/950ms off) | The device is in an unprovisioned (unpaired) state and is waiting for a commissioner to connect. | +| LED2 | rapid even flashing (100ms period) | The device is in an unprovisioned state and a commissioner is connected via BLE. | +| LED2 | short flash off (950ms on/50ms off) | The device is fully provisioned, but does not yet have full network (Thread) or service connectivity. | +| LED2 | solid on | The device is fully provisioned and has full network and service connectivity. | +| RGB LED | on | The `StateValue` attribute of the `BooleanState` cluster is `true` (simulating detection). | +| RGB LED | off | The `StateValue` attribute of the `BooleanState` cluster is `false` (simulating no detection). | -- _Short Flash Off (950ms on/50ms off)_ — The device is full - provisioned, but does not yet have full network (Thread) or service - connectivity. +NOTE: `LED2` will be disabled when OTA is used. On K32W1 EVK board, `PTB0` is +wired to both `LED2` and CS (Chip Select) of the External Flash Memory. Since +the OTA image is stored in external memory, `LED2` operations will affect OTA +operation by corrupting packages and OTA will not work. -* _Solid On_ — The device is fully provisioned and has full network and - service connectivity. +The user actions are summarized below: -NOTE: LED2 will be disabled when CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR is -enabled. On K32W1 EVK board, `PTB0` is wired to `LED2` also is wired to CS (Chip -Select) External Flash Memory. OTA image is stored in external memory because of -it's size. If LED2 is enabled then it will affect External Memory CS and OTA -will not work. - -**RGB LED** shows the state of the simulated contact sensor. when the LED is -lit, the sensor is contacted, when not lit, the sensor is non-contacted. - -**Button SW2**. SHORT press function is overloaded depending on the device type -and commissioning state. If the device is not commissioned, a SHORT press of the -button will enable Bluetooth LE advertising for a predefined period of time. If -the device is commissioned and is acting as a LIT ICD then a SHORT press of the -button will enable Active Mode. A LONG Press of Button SW2 initiates a factory -reset. After an initial period of 3 seconds, LED 2 and RGB LED will flash in -unison to signal the pending reset. After 6 seconds will cause the device to -reset its persistent configuration and initiate a reboot. The reset action can -be cancelled by press SW2 button at any point before the 6 second limit. - -**Button SW3** can be used to change the state of the simulated contact sensor. -The button behaves as a toggle, swapping the state every time it is short -pressed. When long pressed, it does a clean soft reset that takes into account -Matter shutdown procedure. +| button | action | state | output | +| ------ | ----------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| SW2 | short press | not commissioned | Enable BLE advertising | +| SW2 | short press | commissioned + device is LIT | Enable Active Mode | +| SW2 | long press | NA | Initiate a factory reset (can be cancelled by pressing the button again within the factory reset timeout limit - 6 seconds by default) | +| SW3 | short press | NA | Toggle attribute `StateValue` value | +| SW3 | long press | NA | Clean soft reset of the device (takes into account proper Matter shutdown procedure) | ## Building -In order to build the Project CHIP example, we recommend using a Linux -distribution. Supported Operating Systems and prerequisites are listed in -[BUILDING](../../../../docs/guides/BUILDING.md). - -- Make sure that below prerequisites are correctly installed - -``` -sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ - libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ - python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev -``` - -- Step 1: checkout NXP specific submodules only - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive -``` - -- Step 2: activate local environment - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh -``` - -If the script says the environment is out of date, you can update it by running -the following command: - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh -``` - -- Step 3: Init NXP SDK(s) - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform common_sdk -``` - -Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP -SDKs. Arg "-- help" could be used to view all available options. +Manually building requires running the following commands: ``` user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w1 @@ -164,55 +59,11 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w1$ user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w1$ ninja -C out/debug ``` -In case that Openthread CLI is needed, chip_with_ot_cli build argument must be -set to 1. - -After a successful build, the `elf` and `srec` files are found in `out/debug/` - -`see the files prefixed with chip-k32w1-contact-example`. - -## Long Idle Time ICD Support - -By default, contact-sensor is compiled as SIT ICD (Short Idle Time -Intermittently Connected Device) - see rules from k32w1_sdk.gni: - -``` -chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals -chip_ot_active_interval_ms = 500 # 500ms Active Intervals - -nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval -nxp_active_mode_duration_ms = 10000 # 10s Active Mode Interval -nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold -nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric -``` - -If LIT ICD support is needed then `chip_enable_icd_lit=true` must be specified -as gn argument and the above parameters can be modified to comply with LIT -requirements (e.g.: LIT devices must configure -`chip_ot_idle_interval_ms > 15000`). Example LIT configuration: - -``` -chip_ot_idle_interval_ms = 15000 # 15s Idle Intervals -chip_ot_active_interval_ms = 500 # 500ms Active Intervals - -nxp_idle_mode_duration_s = 3600 # 60min Idle Mode Interval -nxp_active_mode_duration_ms = 0 # 0 Active Mode Interval -nxp_active_mode_threshold_ms = 30000 # 30s Active Mode Threshold -``` - -ICD parameters that may be disabled once LIT functionality is enabled: - -``` -chip_persist_subscriptions: try once to re-establish subscriptions from the server side after reboot -chip_subscription_timeout_resumption: same as above + try to re-establish timeout out subscriptions -using Fibonacci backoff for retries pacing. -``` - -## Manufacturing data - -Use `chip_with_factory_data=1` in the gn build command to enable factory data. +Please note that running `gn gen out/debug` without `--args` option will use the +default gn args values found in `args.gni`. -For a full guide on manufacturing flow, please see -[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). +After a successful build, the `elf` and `srec` files are found in `out/debug/`. +See the files prefixed with `chip-k32w1-contact-example`. ## Flashing @@ -222,7 +73,7 @@ Two images must be written to the board: one for the host (CM33) and one for the The image needed on the host side is the one generated in `out/debug/` while the one needed on the `NBU` side can be found in the downloaded NXP-SDK package at path - -`middleware\wireless\ieee-802.15.4\bin\k32w1\k32w1_nbu_ble_15_4_dyn_matter_$version.sb3`. +`middleware\wireless\ieee-802.15.4\bin\k32w1\k32w1_nbu_ble_15_4_dyn_matter.sb3`. ### Flashing the `NBU` image @@ -244,29 +95,26 @@ build process. If debugging is needed then jump directly to the [Debugging](#debugging) section. Otherwise, if only flashing is needed then -[JLink 7.84b](https://www.segger.com/downloads/jlink/) can be used: +[JLink 7.84b or greater](https://www.segger.com/downloads/jlink/) can be used: - Plug K32W1 to the USB port (no need to keep the SW4 button pressed while - doing this) - -- Create a new file, `commands_script`, with the following content (change - application name accordingly): - -```bash -reset -halt -loadfile chip-k32w1-contact-example.srec -reset -go -quit -``` + doing this, e.g. ISP mode is not needed for host flashing) -- copy the application and `commands_script` in the same folder that JLink - executable is placed. Execute: +- Connect JLink to the device: -```bash -$ jlink -device K32W1480 -if SWD -speed 4000 -autoconnect 1 -CommanderScript commands_script -``` + ```bash + JLinkExe -device K32W1480 -if SWD -speed 4000 -autoconnect 1 + ``` + +- Run the following commands: + ```bash + reset + halt + loadfile chip-k32w1-contact-example.srec + reset + go + quit + ``` ## Debugging @@ -275,7 +123,7 @@ One option for debugging would be to use MCUXpresso IDE. - Drag-and-drop the zip file containing the NXP SDK in the "Installed SDKs" tab: -![Installed SDKs](../../../platform/nxp/k32w1/doc/images/installed_sdks.jpg) +![Installed SDKs](../../../platform/nxp/mcxw71_k32w1/doc/images/installed_sdks.jpg) - Import any demo application from the installed SDK: @@ -283,7 +131,7 @@ One option for debugging would be to use MCUXpresso IDE. Import SDK example(s).. -> choose a demo app (demo_apps -> hello_world) -> Finish ``` -![Import demo](../../../platform/nxp/k32w1/doc/images/import_demo.jpg) +![Import demo](../../../platform/nxp/mcxw71_k32w1/doc/images/import_demo.jpg) - Flash the previously imported demo application on the board: @@ -302,7 +150,7 @@ resulted after ot-nxp compilation. File -> Import -> C/C++ -> Existing Code as Makefile Project ``` -![New Project](../../../platform/nxp/k32w1/doc/images/new_project.jpg) +![New Project](../../../platform/nxp/mcxw71_k32w1/doc/images/new_project.jpg) - Replace the path of the existing demo application with the path of the K32W1 application: @@ -311,199 +159,9 @@ File -> Import -> C/C++ -> Existing Code as Makefile Project Run -> Debug Configurations... -> C/C++ Application ``` -![Debug K32W1](../../../platform/nxp/k32w1/doc/images/debug_k32w1.jpg) +![Debug K32W1](../../../platform/nxp/mcxw71_k32w1/doc/images/debug_k32w1.jpg) ## OTA -### Convert `srec` into `sb3` file - -The OTA image files must be encrypted using Over The Air Programming Tool -([OTAP](https://www.nxp.com/design/microcontrollers-developer-resources/connectivity-tool-suite:CONNECTIVITY-TOOL-SUITE?#downloads)). -Bootloader will load the new OTA image only if it detects that the file was -encrypted with the `OTAP` correct keys. - -`.srec` file is input for Over The air Programming (`OTAP`) application -(unencrypted) and it's converted to `.sb3` format (encrypted). - -In `OTAP` application - -- select OTA protocol => `OTAP` Matter -- Browse File -- follow default options (KW45/K32W148, Preserve NVM) -- image information: will update "Application Core (MCU)" - this will generate - the image only for the CM33 core -- keep other settings at default values - -### Convert `sb3` into `ota` file - -In order to build an OTA image, use NXP wrapper over the standard tool -`src/app/ota_image_tool.py`: - -- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py`. - -The tool can be used to generate an OTA image with the following format: - -``` - | OTA image header | TLV1 | TLV2 | ... | TLVn | -``` - -where each TLV is in the form `|tag|length|value|`. - -Note that "standard" TLV format is used. Matter TLV format is only used for -factory data TLV value. - -Please see more in the -[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). - -Here is an example that generates an OTA image with application update TLV from -a `sb3` file: - -``` -./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 43033 -vs "1.0" -da sha256 --app-input-file ~/binaries/chip-k32w1-43033.sb3 ~/binaries/chip-k32w1-43033.ota - -``` - -A note regarding OTA image header version (`-vn` option). An application binary -has its own software version (given by -`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION`, which can be overwritten). For -having a correct OTA process, the OTA header version should be the same as the -binary embedded software version. A user can set a custom software version in -the gn build args by setting `chip_software_version` to the wanted version. - -### OTA factory data - -A user can update the factory data through OTA, at the same time the application -firmware is updated by enabling the following processor in the `gn args`: - -- `chip_enable_ota_factory_data_processor=1` to enable default factory data - update processor (disabled by default). - -The OTA image used must be updated to include the new factory data. - -[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). - -### Running OTA - -The OTA topology used for OTA testing is illustrated in the figure below. -Topology is similar with the one used for Matter Test Events. - -![OTA_TOPOLOGY](../../../platform/nxp/k32w1/doc/images/ota_topology.JPG) - -The concept for OTA is the next one: - -- there is an OTA Provider Application that holds the OTA image. In our case, - this is a Linux application running on an Ubuntu based-system; -- the OTA Requestor functionality is embedded inside the Contact Sensor - Application. It will be used for requesting OTA blocks from the OTA - Provider; -- the controller (a linux application called chip-tool) will be used for - commissioning both the device and the OTA Provider App. The device will be - commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the - OTA Provider Application will be commissioned using the _onnetwork_ option - of chip-tool; -- during commissioning, each device is assigned a node id by the chip-tool - (can be specified manually by the user). Using the node id of the device and - of the contact sensor application, chip-tool triggers the OTA transfer by - invoking the _announce-ota-provider_ command - basically, the OTA Requestor - is informed of the node id of the OTA Provider Application. - -_Computer #1_ can be any system running an Ubuntu distribution. We recommand -using CSA official instructions from -[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are -proposed. Also, CSA official instructions document point to the OS/Docker images -that should be used on the RPis. For compatibility reasons, we recommand -compiling chip-tool and OTA Provider applications with the same commit id that -was used for compiling the Contact Sensor Application. Also, please note that -there is a single controller (chip-tool) running on Computer #1 which is used -for commissioning both the device and the OTA Provider Application. If needed, -[these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be -used for connecting the RPis to WiFi. - -Build the Linux OTA provider application: - -``` -user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false -``` - -Build Linux chip-tool: - -``` -user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool-app -``` - -Start the OTA Provider Application: - -``` -user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* -user@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-k32w1-43033.ota -``` - -Provision the OTA provider application and assign node id _1_. Also, grant ACL -entries to allow OTA requestors: - -``` -user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing onnetwork 1 20202021 -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 1 0 -``` - -Provision the device and assign node id _2_: - -``` -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing ble-thread 2 hex: 20202021 3840 -``` - -Start the OTA process: - -``` -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0 -``` - -## Low power - -The example also offers the possibility to run in low power mode. This means -that the board will go in deep sleep most of the time and the power consumption -will be very low. - -In order to build with low power support, the `chip_with_low_power=1` must be -provided to the build system. In this case, please note that the GN build -arguments `chip_openthread_ftd` and `chip_with_ot_cli` must be set to `false/0` -and `chip_logging` must be set to `false` to disable logging. - -In order to maintain a low power consumption, the LEDs showing the state of the -contact sensor and the internal state are disabled. Console logs can be used -instead. Also, please note that once the board is flashed with MCUXpresso the -debugger disconnects because the board enters low power. - -### Known issues - -- SRP cache on the openthread border router needs to flushed each time a new - commissioning process is attempted. For this, factory reset the device, then - execute _ot-ctl server disable_ followed by _ot-ctl server enable_. After - this step, the commissioning process of the device can start; -- Due to some MDNS issues, the commissioning of the OTA Provider Application - may fail. Please make sure that the SRP cache is disabled (_ot-ctl srp - server disable_) on the openthread border router while commissioning the OTA - Provider Application; -- No other Docker image should be running (e.g.: Docker image needed by Test - Harness) except the OTBR one. A docker image can be killed using the - command: - -``` -user@computer1:~/connectedhomeip$ : sudo docker kill $container_id -``` - -- In order to avoid MDNS issues, only one interface should be active at one - time. E.g.: if WiFi is used then disable the Ethernet interface and also - disable multicast on that interface: - -``` -user@computer1:~/connectedhomeip$ sudo ip link set dev eth0 down -user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast -``` - -- If OTBR Docker image is used, then the "-B" parameter should point to the - interface used for the backbone. - -- If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected. - Otherwise, issues related to BLE-WiFi combo may appear. +Please see +[k32w1 OTA guide](../../../../docs/guides/nxp/nxp_mcxw71_ota_guide.md). diff --git a/examples/contact-sensor-app/nxp/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w1/args.gni index cb952c94bd74d1..b1c31aa7eb642a 100644 --- a/examples/contact-sensor-app/nxp/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w1/args.gni @@ -23,6 +23,7 @@ nxp_device = "K32W1480" chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true +chip_generate_link_map_file = true chip_system_config_provide_statistics = false chip_system_config_use_open_thread_inet_endpoints = true diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index 081b5891b9c5f6..f487ff415f1330 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -83,10 +83,18 @@ rt_sdk("sdk") { include_dirs += [ "${example_platform_dir}/board/" ] sources += [ "${example_platform_dir}/board/pin_mux.c" ] sources += [ "${example_platform_dir}/board/hardware_init.c" ] - sources += [ "${example_platform_dir}/board/clock_config.c" ] - sources += [ "${example_platform_dir}/board/board.c" ] sources += [ "${example_platform_dir}/board/peripherals.c" ] + if (board_version == "frdm") { + include_dirs += [ "${example_platform_dir}/board/frdmrw612/" ] + sources += [ "${example_platform_dir}/board/frdmrw612/clock_config.c" ] + sources += [ "${example_platform_dir}/board/frdmrw612/board.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/rdrw612bga/" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/clock_config.c" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/board.c" ] + } + # Indicate the path to CHIPProjectConfig.h include_dirs += [ "include/config" ] @@ -98,7 +106,7 @@ rt_sdk("sdk") { # For matter with BR feature, increase FreeRTOS heap size if (chip_enable_wifi && chip_enable_openthread) { - defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] } defines += [ @@ -143,9 +151,7 @@ rt_executable("laundry-washer") { ] if (chip_enable_secure_dac_private_key_storage == 1) { - sources += [ - "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", - ] + sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] } else { sources += [ "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", diff --git a/examples/lighting-app/nxp/README.md b/examples/lighting-app/nxp/README.md new file mode 100644 index 00000000000000..74d0f9dc294813 --- /dev/null +++ b/examples/lighting-app/nxp/README.md @@ -0,0 +1,137 @@ +# Matter NXP Lighting Example Application + +This reference application implements an On/Off Light device type. It uses board +buttons or `matter-cli` for user input and LEDs for state feedback. You can use +this example as a reference for creating your own application. + +The example is based on: + +- [Matter](https://github.com/project-chip/connectedhomeip) +- [NXP github SDK](https://github.com/nxp-mcuxpresso/mcux-sdk) + +- [Matter NXP Lighting Example Application](#matter-nxp-lighting-example-application) + - [Supported devices](#supported-devices) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Prerequisites for building](#prerequisites-for-building) + - [Building](#building) + - [Data model](#data-model) + - [Manufacturing data](#manufacturing-data) + - [Flashing and debugging](#flashing-and-debugging) + +## Supported devices + +- [k32w1](k32w1/README.md) + +## Introduction + +The application showcases a light bulb device that communicates with clients +over a low-power, 802.15.4 Thread network. + +It can be commissioned into an existing Matter network using a controller such +as `chip-tool`. + +This example implements a `User-Intent Commissioning Flow`, meaning the user has +to press a button in order for the device to be ready for commissioning. The +initial commissioning is done through `ble-thread` pairing method. + +The Thread network dataset will be transferred on the device using a secure +session over Bluetooth LE. In order to start the commissioning process, the user +must enable BLE advertising on the device manually. To pair successfully, the +commissioner must know the commissioning information corresponding to the +device: setup passcode and discriminator. This data is usually encoded within a +QR code or printed to the UART console. + +## Device UI + +The example application provides a simple UI that depicts the state of the +device and offers basic user control. This UI is implemented via the +general-purpose LEDs and buttons built in the evaluation boards. Please see each +supported device readme file for details. + +## Prerequisites for building + +In order to build the example, it is recommended to use a Linux distribution. +Please visit the supported Operating Systems list in +[BUILDING.md](../../../docs/guides/BUILDING.md#prerequisites). + +- Make sure that below prerequisites are correctly installed (as described in + [BUILDING.md](../../../docs/guides/BUILDING.md#prerequisites)) + +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` + +- Step 1: checkout NXP specific submodules only + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive + ``` + +- Step 2: activate local environment + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh + ``` + + If the script says the environment is out of date, you can update it by + running the following command: + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh + ``` + +- Step 3: Init NXP SDK(s) + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform common + ``` + +Note: By default, `update_nxp_sdk.py` will try to initialize all NXP SDKs. +Please run the script with arg `--help` to view all available options. + +## Building + +There are two options for building this reference app: + +- Using `build_examples.py` framework. +- Manually generating `ninja` files using `gn`. + +For manual generation and building, please see the specific readme file for your +device. + +A list of all available contact sensor targets can be viewed in the following +table: + +| target name | description | +| --------------------------------------------------- | ------------------------------------------------------------------------------- | +| nxp-device-freertos-lighting | Default lighting app | +| nxp-device-freertos-lighting-factory | Default lighting app with factory data | +| nxp-device-freertos-lighting-rotating-id | Lighting app with rotating device id support | +| nxp-device-freertos-lighting-factory-dac-conversion | Lighting app that leverages a secure enclave to secure the DAC private key | +| nxp-device-freertos-lighting-sw-v2 | Lighting app with software version 2 (can be used to test OTA) | +| nxp-device-freertos-lighting-factory-sw-v2 | Lighting app with factory data and software version 2 (can be used to test OTA) | + +where `device` can be one of the [Supported devices](#supported-devices). + +### Data model + +The application uses an NXP specific data model file: + +| path | description | +| ----------------------------- | --------------------------------------- | +| `zap-lit/lighting-on-off.zap` | Data model for On/Off Light device type | + +The data model can be changed by simply replacing the gn `deps` statement +corresponding to data model target. + +### Manufacturing data + +Use `chip_with_factory_data=1` in the gn build command to enable factory data. + +For a full guide on manufacturing flow, please see +[Guide for writing manufacturing data on NXP devices](../../../docs/guides/nxp/nxp_manufacturing_flow.md). + +## Flashing and debugging + +Please see the device specific readme file. diff --git a/examples/lighting-app/nxp/k32w1/.gn b/examples/lighting-app/nxp/k32w1/.gn index afa5bfea46aca8..5d6e10a31e334d 100644 --- a/examples/lighting-app/nxp/k32w1/.gn +++ b/examples/lighting-app/nxp/k32w1/.gn @@ -27,5 +27,5 @@ default_args = { import("//args.gni") # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w1/args.gni") + import("${chip_root}/src/platform/nxp/mcxw71_k32w1/args.gni") } diff --git a/examples/lighting-app/nxp/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w1/BUILD.gn index b6e6db814ad221..9544ca8486a2ff 100644 --- a/examples/lighting-app/nxp/k32w1/BUILD.gn +++ b/examples/lighting-app/nxp/k32w1/BUILD.gn @@ -45,7 +45,7 @@ assert(target_os == "freertos") example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" common_example_dir = "${chip_root}/examples/platform/nxp/common" -k32w1_sdk("sdk") { +mcxw71_k32w1_sdk("sdk") { defines = [] include_dirs = [] sources = [] @@ -60,20 +60,20 @@ k32w1_sdk("sdk") { include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] include_dirs += [ - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", ] sources += [ - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", - "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", + "${nxp_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", ] if (is_debug) { @@ -104,7 +104,7 @@ k32w1_sdk("sdk") { } } -k32w1_executable("light_app") { +mcxw71_k32w1_executable("light_app") { output_name = "chip-k32w1-light-example" defines = [] @@ -237,9 +237,9 @@ k32w1_executable("light_app") { if (use_smu2_static) { ldscript = "${example_platform_dir}/app/ldscripts/k32w1_app.ld" - base_ldscript_dir = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc" + base_ldscript_dir = "${nxp_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc" } else { - ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" + ldscript = "${nxp_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" } inputs = [ ldscript ] diff --git a/examples/lighting-app/nxp/k32w1/README.md b/examples/lighting-app/nxp/k32w1/README.md index 349deef640727d..ab54aab153e272 100644 --- a/examples/lighting-app/nxp/k32w1/README.md +++ b/examples/lighting-app/nxp/k32w1/README.md @@ -1,167 +1,63 @@ # Matter K32W1 Lighting Example Application -Matter K32W1 Lighting Example demonstrates how to remotely control a light bulb. -The light bulb is simulated using one of the LEDs from the expansion board. It -uses buttons to test turn on/turn off of the light bulb. You can use this -example as a reference for creating your own application. - -The example is based on -[Matter](https://github.com/project-chip/connectedhomeip) and the NXP K32W1 SDK, -and supports remote access and control of a light bulb over a low-power, -802.15.4 Thread network. - -The example behaves as a Matter accessory, that is a device that can be paired -into an existing Matter network and can be controlled by this network. - -
+For generic information related to on/off light application, please see the +[common README](../README.md). - [Matter K32W1 Lighting Example Application](#matter-k32w1-lighting-example-application) - [Introduction](#introduction) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - - [Thread Provisioning](#thread-provisioning) - [Device UI](#device-ui) - [Building](#building) - [`SMU2` Memory](#smu2-memory) - [LED PWM](#led-pwm) - - [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the `NBU` image](#flashing-the-nbu-image) - [Flashing the host image](#flashing-the-host-image) - [Debugging](#debugging) - - [OTA](#ota) - - [Convert `srec` into `sb3` file](#convert-srec-into-sb3-file) - - [Convert `sb3` into `ota` file](#convert-sb3-into-ota-file) - - [OTA factory data](#ota-factory-data) - - [Running OTA](#running-ota) - - [Known issues](#known-issues) - [Running RPC console](#running-rpc-console) - - + - [OTA](#ota) ## Introduction -![K32W1 EVK](../../../platform/nxp/k32w1/doc/images/k32w1-evk.jpg) - -The K32W1 lighting example application provides a working demonstration of a -light bulb device, built using the Matter codebase and the NXP K32W1 SDK. The -example supports remote access (e.g.: using CHIP Tool from a mobile phone) and -control of a light bulb over a low-power, 802.15.4 Thread network. It is capable -of being paired into an existing Matter network along with other Matter-enabled -devices. - -The Matter device that runs the lighting application is controlled by the Matter -controller device over the Thread protocol. By default, the Matter device has -Thread disabled, and it should be paired over Bluetooth LE with the Matter -controller and obtain configuration from it. The actions required before -establishing full communication are described below. +This is an on/off lighting application implemented for a k32w1 device. -### Bluetooth LE Advertising +The following board was used when testing this Matter reference app for a +`k32w1` device: +![K32W1 EVK](../../../platform/nxp/mcxw71_k32w1/doc/images/k32w1-evk.jpg) -In this example, to commission the device onto a Matter network, it must be -discoverable over Bluetooth LE. For security reasons, you must start Bluetooth -LE advertising manually after powering up the device by pressing Button SW2. +## Device UI -### Bluetooth LE Rendezvous +The state feedback is provided through LED effects: -In this example, the commissioning procedure (called rendezvous) is done over -Bluetooth LE between a Matter device and the Matter controller, where the -controller has the commissioner role. +| widget | effect | description | +| ------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------- | +| LED2 | short flash on (50ms on/950ms off) | The device is in an unprovisioned (unpaired) state and is waiting for a commissioner to connect. | +| LED2 | rapid even flashing (100ms period) | The device is in an unprovisioned state and a commissioner is connected via BLE. | +| LED2 | short flash off (950ms on/50ms off) | The device is fully provisioned, but does not yet have full network (Thread) or service connectivity. | +| LED2 | solid on | The device is fully provisioned and has full network and service connectivity. | +| RGB LED | on | The `OnOff` attribute of the `On/Off` cluster is `true` (simulating device turned on). | +| RGB LED | off | The `OnOff` attribute of the `On/Off` cluster is `false` (simulating device turned off). | -To start the rendezvous, the controller must get the commissioning information -from the Matter device. The data payload is encoded within a QR code, or printed -to the UART console. +NOTE: `LED2` will be disabled when OTA is used. On K32W1 EVK board, `PTB0` is +wired to both `LED2` and CS (Chip Select) of the External Flash Memory. Since +the OTA image is stored in external memory, `LED2` operations will affect OTA +operation by corrupting packages and OTA will not work. -### Thread Provisioning +The user actions are summarized below: -## Device UI +| button | action | output | +| ------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| SW2 | short press | Enable BLE advertising | +| SW2 | long press | Initiate a factory reset (can be cancelled by pressing the button again within the factory reset timeout limit - 6 seconds by default) | +| SW3 | short press | Toggle attribute `OnOff` value | +| SW3 | long press | Clean soft reset of the device (takes into account proper Matter shutdown procedure) | The example application provides a simple UI that depicts the state of the device and offers basic user control. This UI is implemented via the general-purpose LEDs and buttons built in the K32W1 EVK board. -**LED 2** shows the overall state of the device and its connectivity. Four -states are depicted: - -- _Short Flash On (50ms on/950ms off)_ — The device is in an - unprovisioned (unpaired) state and is waiting for a commissioning - application to connect. - -* _Rapid Even Flashing (100ms on/100ms off)_ — The device is in an - unprovisioned state and a commissioning application is connected via BLE. - -- _Short Flash Off (950ms on/50ms off)_ — The device is full - provisioned, but does not yet have full network (Thread) or service - connectivity. - -* _Solid On_ — The device is fully provisioned and has full network and - service connectivity. - -NOTE: LED2 will be disabled when CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR is -enabled. On K32W1 EVK board, `PTB0` is wired to LED2 also is wired to CS (Chip -Select) External Flash Memory. OTA image is stored in external memory because of -it's size. If LED2 is enabled then it will affect External Memory CS and OTA -will not work. - -**RGB LED** shows the state of the simulated light bulb. When the LED is lit the -light bulb is on; when not lit, the light bulb is off. - -**Button SW2** can be used to start BLE advertising. A SHORT press of the button -will enable Bluetooth LE advertising for a predefined period of time. A LONG -Press Button SW2 initiates a factory reset. After an initial period of 3 -seconds, LED 2 and RGB LED will flash in unison to signal the pending reset. -After 6 seconds will cause the device to reset its persistent configuration and -initiate a reboot. The reset action can be cancelled by press SW2 button at any -point before the 6 second limit. - -**Button SW3** can be used to change the state of the simulated light bulb. This -can be used to mimic a user manually operating a switch. The button behaves as a -toggle, swapping the state every time it is short pressed. When long pressed, it -does a clean soft reset that takes into account Matter shutdown procedure. - ## Building -In order to build the Project CHIP example, we recommend using a Linux -distribution. Supported Operating Systems and prerequisites are listed in -[BUILDING](../../../../docs/guides/BUILDING.md). - -- Make sure that below prerequisites are correctly installed - -``` -sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ - libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ - python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev -``` - -- Step 1: checkout NXP specific submodules only - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive -``` - -- Step 2: activate local environment - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh -``` - -If the script says the environment is out of date, you can update it by running -the following command: - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh -``` - -- Step 3: Init NXP SDK(s) - -``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform common_sdk -``` - -Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP -SDKs. Arg "-- help" could be used to view all available options. - -- Start building the application. +Manually building requires running the following commands: ``` user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w1 @@ -169,37 +65,40 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w1$ gn ge user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w1$ ninja -C out/debug ``` -In case that Openthread CLI is needed, `chip_with_ot_cli` build argument must be -set to 1. +Please note that running `gn gen out/debug` without `--args` option will use the +default gn args values found in `args.gni`. -After a successful build, the `elf` and `srec` files are found in `out/debug/` - -see the files prefixed with `chip-k32w1-light-example`. +After a successful build, the `elf` and `srec` files are found in `out/debug/`. +See the files prefixed with `chip-k32w1-light-example`. ### `SMU2` Memory -Some Matter instances and global variables can be placed in the `NBU` `SMU2` -memory. When compiling with OpenThread FTD support (`chip_openthread_ftd=true`) -and with `use_smu2_static=true`, the following components are placed in `SMU2` -memory: +Additional memory is provided to the application by moving some Matter instances +and global variables in the shared memory area from `NBU` domain. -- `gImageProcessor` from OTAImageProcessorImpl.cpp. -- `gApplicationProcessor` from OTAHooks.cpp. -- `Server::sServer` from Server.cpp. -- `ThreadStackManagerImpl::sInstance` from ThreadStackManagerImpl.cpp. - -These instances and global variables are placed in `SMU2` memory through name -matching in the application linker script. They should not be changed or, if -changed, the names must be updated in `k32w1_app.ld`. See +Note: These instances and global variables are placed in `SMU2` memory through +name matching in the application linker script. They should not be changed or, +if changed, the names must be updated in `k32w1_app.ld`. See [k32w1_app.ld](../../../platform/nxp/k32w1/app/ldscripts/k32w1_app.ld) for names and `SMU2` memory range size. -The OpenThread buffers can be allocated from a 13KB `SMU2` range after a -successful commissioning process until a factory reset is initiated. This way, -the OpenThread buffers will be dynamically allocated instead of statically, -freeing some `SRAM`. To enable this feature compile with OpenThread FTD support -(`chip_openthread_ftd=true`) and with `use_smu2_dynamic=true`. +When compiling the application as an OT Full Thread Device +(`chip_openthread_ftd=true`), using `use_smu2_static=true` gn arg will cause the +following symbols to be moved to `SMU2` area: + +| symbol name | file | +| ----------------------------------- | ---------------------------- | +| `gImageProcessor` | `OTAImageProcessorImpl.cpp` | +| `gApplicationProcessor` | `OTAHooks.cpp` | +| `Server::sServer` | `Server.cpp` | +| `ThreadStackManagerImpl::sInstance` | `ThreadStackManagerImpl.cpp` | -`use_smu2_static` and `use_smu2_dynamic` are set to `true` by default. +Additionally, using `use_smu2_dynamic=true` will cause the OpenThread buffers to +be dynamically allocated from a 13KB `SMU2` range after a successful +commissioning process. + +`use_smu2_static` and `use_smu2_dynamic` are set to `true` in the default +example. ### LED PWM @@ -208,17 +107,10 @@ pins. In order to enable the dimming feature, the pins need to be configured in PWM mode and synced with channels of the `TPM` (Timer PWM Module). To enable this feature, compile the application with: `chip_config_dimmable_led=true` -If the feature is enabled, the LED brightness can be controlled using **Level -control** cluster +If the feature is enabled, the LED brightness can be controlled using +`LevelControl` cluster [commands](../../../../docs/guides/chip_tool_guide.md#step-7-control-application-data-model-clusters). -## Manufacturing data - -Use `chip_with_factory_data=1` in the gn build command to enable factory data. - -For a full guide on manufacturing flow, please see -[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). - ## Flashing Two images must be written to the board: one for the host (CM33) and one for the @@ -227,7 +119,7 @@ Two images must be written to the board: one for the host (CM33) and one for the The image needed on the host side is the one generated in `out/debug/` while the one needed on the `NBU` side can be found in the downloaded NXP-SDK package at path - -`middleware\wireless\ieee-802.15.4\bin\k32w1\k32w1_nbu_ble_15_4_dyn_matter_$version.sb3`. +`middleware\wireless\ieee-802.15.4\bin\k32w1\k32w1_nbu_ble_15_4_dyn_matter.sb3`. ### Flashing the `NBU` image @@ -249,29 +141,26 @@ build process. If debugging is needed then jump directly to the [Debugging](#debugging) section. Otherwise, if only flashing is needed then -[JLink 7.84b](https://www.segger.com/downloads/jlink/) can be used: +[JLink 7.84b or greater](https://www.segger.com/downloads/jlink/) can be used: - Plug K32W1 to the USB port (no need to keep the SW4 button pressed while - doing this) - -- Create a new file, `commands_script`, with the following content (change - application name accordingly): - -```bash -reset -halt -loadfile chip-k32w1-light-example.srec -reset -go -quit -``` + doing this, e.g. ISP mode is not needed for host flashing) -- copy the application and `commands_script` in the same folder that JLink - executable is placed. Execute: +- Connect JLink to the device: -```bash -$ jlink -device K32W1480 -if SWD -speed 4000 -autoconnect 1 -CommanderScript commands_script -``` + ```bash + JLinkExe -device K32W1480 -if SWD -speed 4000 -autoconnect 1 + ``` + +- Run the following commands: + ```bash + reset + halt + loadfile chip-k32w1-light-example.srec + reset + go + quit + ``` ## Debugging @@ -280,7 +169,7 @@ One option for debugging would be to use MCUXpresso IDE. - Drag-and-drop the zip file containing the NXP SDK in the "Installed SDKs" tab: -![Installed SDKs](../../../platform/nxp/k32w1/doc/images/installed_sdks.jpg) +![Installed SDKs](../../../platform/nxp/mcxw71_k32w1/doc/images/installed_sdks.jpg) - Import any demo application from the installed SDK: @@ -288,7 +177,7 @@ One option for debugging would be to use MCUXpresso IDE. Import SDK example(s).. -> choose a demo app (demo_apps -> hello_world) -> Finish ``` -![Import demo](../../../platform/nxp/k32w1/doc/images/import_demo.jpg) +![Import demo](../../../platform/nxp/mcxw71_k32w1/doc/images/import_demo.jpg) - Flash the previously imported demo application on the board: @@ -307,7 +196,7 @@ resulted after ot-nxp compilation. File -> Import -> C/C++ -> Existing Code as Makefile Project ``` -![New Project](../../../platform/nxp/k32w1/doc/images/new_project.jpg) +![New Project](../../../platform/nxp/mcxw71_k32w1/doc/images/new_project.jpg) - Replace the path of the existing demo application with the path of the K32W1 application: @@ -316,185 +205,7 @@ File -> Import -> C/C++ -> Existing Code as Makefile Project Run -> Debug Configurations... -> C/C++ Application ``` -![Debug K32W1](../../../platform/nxp/k32w1/doc/images/debug_k32w1.jpg) - -## OTA - -### Convert `srec` into `sb3` file - -The OTA image files must be encrypted using Over The Air Programming Tool -([OTAP](https://www.nxp.com/design/microcontrollers-developer-resources/connectivity-tool-suite:CONNECTIVITY-TOOL-SUITE?#downloads)). -Bootloader will load the new OTA image only if it detects that the file was -encrypted with the `OTAP` correct keys. - -`.srec` file is input for Over The air Programming (`OTAP`) application -(unencrypted) and it's converted to `.sb3` format (encrypted). - -In `OTAP` application - -- select OTA protocol => `OTAP` Matter -- Browse File -- follow default options (KW45/K32W148, Preserve NVM) -- image information: will update "Application Core (MCU)" - this will generate - the image only for the CM33 core -- keep other settings at default values - -### Convert `sb3` into `ota` file - -In order to build an OTA image, use NXP wrapper over the standard tool -`src/app/ota_image_tool.py`: - -- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py` - -The tool can be used to generate an OTA image with the following format: - -``` - | OTA image header | TLV1 | TLV2 | ... | TLVn | -``` - -where each TLV is in the form `|tag|length|value|`. - -Note that "standard" TLV format is used. Matter TLV format is only used for -factory data TLV value. - -Please see more in the -[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). - -Here is an example that generates an OTA image with application update TLV from -a sb3 file: - -``` -./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 43033 -vs "1.0" -da sha256 --app-input-file ~/binaries/chip-k32w1-43033.sb3 ~/binaries/chip-k32w1-43033.ota - -``` - -A note regarding OTA image header version (`-vn` option). An application binary -has its own software version (given by -`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION`, which can be overwritten). For -having a correct OTA process, the OTA header version should be the same as the -binary embedded software version. A user can set a custom software version in -the gn build args by setting `chip_software_version` to the wanted version. - -### OTA factory data - -A user can update the factory data through OTA, at the same time the application -firmware is updated by enabling the following processor in the `gn args`: - -- `chip_enable_ota_factory_data_processor=1` to enable default factory data - update processor (disabled by default). - -The OTA image used must be updated to include the new factory data. - -[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). - -### Running OTA - -The OTA topology used for OTA testing is illustrated in the figure below. -Topology is similar with the one used for Matter Test Events. - -![OTA_TOPOLOGY](../../../platform/nxp/k32w1/doc/images/ota_topology.JPG) - -The concept for OTA is the next one: - -- there is an OTA Provider Application that holds the OTA image. In our case, - this is a Linux application running on an Ubuntu based-system; -- the OTA Requestor functionality is embedded inside the Lighting Application. - It will be used for requesting OTA blocks from the OTA Provider; -- the controller (a linux application called chip-tool) will be used for - commissioning both the device and the OTA Provider App. The device will be - commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the - OTA Provider Application will be commissioned using the _onnetwork_ option - of chip-tool; -- during commissioning, each device is assigned a node id by the chip-tool - (can be specified manually by the user). Using the node id of the device and - of the lighting application, chip-tool triggers the OTA transfer by invoking - the _announce-ota-provider_ command - basically, the OTA Requestor is - informed of the node id of the OTA Provider Application. - -_Computer #1_ can be any system running an Ubuntu distribution. We recommand -using CSA official instructions from -[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are -proposed. Also, CSA official instructions document point to the OS/Docker images -that should be used on the RPis. For compatibility reasons, we recommand -compiling chip-tool and OTA Provider applications with the same commit id that -was used for compiling the Lighting Application. Also, please note that there is -a single controller (chip-tool) running on Computer #1 which is used for -commissioning both the device and the OTA Provider Application. If needed, -[these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be -used for connecting the RPis to WiFi. - -Build the Linux OTA provider application: - -``` -user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false -``` - -Build Linux chip-tool: - -``` -user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool-app -``` - -Start the OTA Provider Application: - -``` -user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* -user@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-k32w1-43033.ota -``` - -Provision the OTA provider application and assign node id _1_. Also, grant ACL -entries to allow OTA requestors: - -``` -user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing onnetwork 1 20202021 -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 1 0 -``` - -Provision the device and assign node id _2_: - -``` -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing ble-thread 2 hex: 20202021 3840 -``` - -Start the OTA process: - -``` -user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0 -``` - -### Known issues - -- SRP cache on the openthread border router needs to flushed each time a new - commissioning process is attempted. For this, factory reset the device, then - execute _ot-ctl server disable_ followed by _ot-ctl server enable_. After - this step, the commissioning process of the device can start; -- Due to some MDNS issues, the commissioning of the OTA Provider Application - may fail. Please make sure that the SRP cache is disabled (_ot-ctl srp - server disable_) on the openthread border router while commissioning the OTA - Provider Application; -- No other Docker image should be running (e.g.: Docker image needed by Test - Harness) except the OTBR one. A docker image can be killed using the - command: - -``` -user@computer1:~/connectedhomeip$ : sudo docker kill $container_id -``` - -- In order to avoid MDNS issues, only one interface should be active at one - time. E.g.: if WiFi is used then disable the Ethernet interface and also - disable multicast on that interface: - -``` -user@computer1:~/connectedhomeip$ sudo ip link set dev eth0 down -user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast -``` - -- If OTBR Docker image is used, then the "-B" parameter should point to the - interface used for the backbone. - -- If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected. - Otherwise, issues related to BLE-WiFi combo may appear. +![Debug K32W1](../../../platform/nxp/mcxw71_k32w1/doc/images/debug_k32w1.jpg) ## Running RPC console @@ -506,7 +217,7 @@ client. An example of an RPC client is the `chip-console`, which can be accessed by running: `chip-console --device /dev/tty. -b 115200 -o pw_log.out` -The console should already have been installed in the virtual environment. From +The console should have already been installed in the virtual environment. From the `chip-console`, a user can send specific commands to the device. For button commands, please run `rpcs.chip.rpc.Button.Event(index)` based on the @@ -520,3 +231,8 @@ table below: | 3 | Soft reset the device | To reboot the device, please run `rpcs.chip.rpc.Device.Reboot()`. + +## OTA + +Please see +[k32w1 OTA guide](../../../../docs/guides/nxp/nxp_mcxw71_ota_guide.md). diff --git a/examples/lighting-app/nxp/k32w1/args.gni b/examples/lighting-app/nxp/k32w1/args.gni index 7d5e752aae6934..5c854bc1c3c187 100644 --- a/examples/lighting-app/nxp/k32w1/args.gni +++ b/examples/lighting-app/nxp/k32w1/args.gni @@ -23,6 +23,7 @@ chip_config_dimmable_led = false chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true +chip_generate_link_map_file = true is_debug = false @@ -34,5 +35,5 @@ chip_system_config_provide_statistics = false chip_system_config_use_open_thread_inet_endpoints = true chip_with_lwip = false -use_smu2_static = false -use_smu2_dynamic = false +use_smu2_static = true +use_smu2_dynamic = true diff --git a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp index bc7a8dca431c42..2e40fdefb2e119 100644 --- a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp +++ b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp @@ -120,9 +120,8 @@ void chip::NXP::App::CommonDeviceCallbacks::OnInternetConnectivityChange(const C char ip_addr[Inet::IPAddress::kMaxStringLength]; event->InternetConnectivityChange.ipAddress.ToString(ip_addr); ChipLogProgress(DeviceLayer, "IPv6 Server ready at: [%s]:%d", ip_addr, CHIP_PORT); -#if !CHIP_ENABLE_OPENTHREAD // No need to do this for OT mDNS server + chip::app::DnssdServer::Instance().StartServer(); -#endif } else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) { diff --git a/examples/platform/nxp/k32w1/app/ldscripts/k32w1_app.ld b/examples/platform/nxp/mcxw71_k32w1/app/ldscripts/k32w1_app.ld similarity index 100% rename from examples/platform/nxp/k32w1/app/ldscripts/k32w1_app.ld rename to examples/platform/nxp/mcxw71_k32w1/app/ldscripts/k32w1_app.ld diff --git a/examples/platform/nxp/k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h b/examples/platform/nxp/mcxw71_k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h similarity index 100% rename from examples/platform/nxp/k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h rename to examples/platform/nxp/mcxw71_k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h diff --git a/examples/platform/nxp/k32w1/app/project_include/openthread/OpenThreadConfig.h b/examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h similarity index 100% rename from examples/platform/nxp/k32w1/app/project_include/openthread/OpenThreadConfig.h rename to examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h diff --git a/examples/platform/nxp/k32w1/app/support/BUILD.gn b/examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn similarity index 100% rename from examples/platform/nxp/k32w1/app/support/BUILD.gn rename to examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn diff --git a/examples/platform/nxp/k32w1/app/support/FreeRtosHooks.c b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.c similarity index 100% rename from examples/platform/nxp/k32w1/app/support/FreeRtosHooks.c rename to examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.c diff --git a/examples/platform/nxp/k32w1/app/support/FreeRtosHooks.h b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h similarity index 100% rename from examples/platform/nxp/k32w1/app/support/FreeRtosHooks.h rename to examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h diff --git a/examples/platform/nxp/k32w1/app/support/Memconfig.cpp b/examples/platform/nxp/mcxw71_k32w1/app/support/Memconfig.cpp similarity index 100% rename from examples/platform/nxp/k32w1/app/support/Memconfig.cpp rename to examples/platform/nxp/mcxw71_k32w1/app/support/Memconfig.cpp diff --git a/examples/platform/nxp/k32w1/board/peripherals.c b/examples/platform/nxp/mcxw71_k32w1/board/peripherals.c similarity index 100% rename from examples/platform/nxp/k32w1/board/peripherals.c rename to examples/platform/nxp/mcxw71_k32w1/board/peripherals.c diff --git a/examples/platform/nxp/k32w1/board/peripherals.h b/examples/platform/nxp/mcxw71_k32w1/board/peripherals.h similarity index 100% rename from examples/platform/nxp/k32w1/board/peripherals.h rename to examples/platform/nxp/mcxw71_k32w1/board/peripherals.h diff --git a/examples/platform/nxp/k32w1/button/ButtonManager.cpp b/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp similarity index 100% rename from examples/platform/nxp/k32w1/button/ButtonManager.cpp rename to examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp diff --git a/examples/platform/nxp/k32w1/button/ButtonManager.h b/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.h similarity index 100% rename from examples/platform/nxp/k32w1/button/ButtonManager.h rename to examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.h diff --git a/examples/platform/nxp/k32w1/clusters/Identify.cpp b/examples/platform/nxp/mcxw71_k32w1/clusters/Identify.cpp similarity index 100% rename from examples/platform/nxp/k32w1/clusters/Identify.cpp rename to examples/platform/nxp/mcxw71_k32w1/clusters/Identify.cpp diff --git a/examples/platform/nxp/k32w1/doc/images/debug_k32w1.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/debug_k32w1.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/debug_k32w1.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/debug_k32w1.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/import_demo.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/import_demo.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/import_demo.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/import_demo.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/installed_sdks.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/installed_sdks.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/installed_sdks.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/installed_sdks.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/k32w1-evk.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/k32w1-evk.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/k32w1-evk.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/k32w1-evk.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/mcux-sdk-download.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/mcux-sdk-download.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/mcux-sdk-download.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/mcux-sdk-download.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/new_project.jpg b/examples/platform/nxp/mcxw71_k32w1/doc/images/new_project.jpg similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/new_project.jpg rename to examples/platform/nxp/mcxw71_k32w1/doc/images/new_project.jpg diff --git a/examples/platform/nxp/k32w1/doc/images/ota_topology.JPG b/examples/platform/nxp/mcxw71_k32w1/doc/images/ota_topology.JPG similarity index 100% rename from examples/platform/nxp/k32w1/doc/images/ota_topology.JPG rename to examples/platform/nxp/mcxw71_k32w1/doc/images/ota_topology.JPG diff --git a/examples/platform/nxp/k32w1/factory_data/source/AppFactoryDataExample.cpp b/examples/platform/nxp/mcxw71_k32w1/factory_data/source/AppFactoryDataExample.cpp similarity index 100% rename from examples/platform/nxp/k32w1/factory_data/source/AppFactoryDataExample.cpp rename to examples/platform/nxp/mcxw71_k32w1/factory_data/source/AppFactoryDataExample.cpp diff --git a/examples/platform/nxp/k32w1/operational_keystore/OperationalKeystore.cpp b/examples/platform/nxp/mcxw71_k32w1/operational_keystore/OperationalKeystore.cpp similarity index 100% rename from examples/platform/nxp/k32w1/operational_keystore/OperationalKeystore.cpp rename to examples/platform/nxp/mcxw71_k32w1/operational_keystore/OperationalKeystore.cpp diff --git a/examples/platform/nxp/k32w1/ota/OtaUtils.cpp b/examples/platform/nxp/mcxw71_k32w1/ota/OtaUtils.cpp similarity index 100% rename from examples/platform/nxp/k32w1/ota/OtaUtils.cpp rename to examples/platform/nxp/mcxw71_k32w1/ota/OtaUtils.cpp diff --git a/examples/platform/nxp/k32w1/rpc/AppRpc.cpp b/examples/platform/nxp/mcxw71_k32w1/rpc/AppRpc.cpp similarity index 100% rename from examples/platform/nxp/k32w1/rpc/AppRpc.cpp rename to examples/platform/nxp/mcxw71_k32w1/rpc/AppRpc.cpp diff --git a/examples/platform/nxp/k32w1/util/LedDimmer.cpp b/examples/platform/nxp/mcxw71_k32w1/util/LedDimmer.cpp similarity index 100% rename from examples/platform/nxp/k32w1/util/LedDimmer.cpp rename to examples/platform/nxp/mcxw71_k32w1/util/LedDimmer.cpp diff --git a/examples/platform/nxp/k32w1/util/LedOnOff.cpp b/examples/platform/nxp/mcxw71_k32w1/util/LedOnOff.cpp similarity index 100% rename from examples/platform/nxp/k32w1/util/LedOnOff.cpp rename to examples/platform/nxp/mcxw71_k32w1/util/LedOnOff.cpp diff --git a/examples/platform/nxp/k32w1/util/LightingManagerDimmable.cpp b/examples/platform/nxp/mcxw71_k32w1/util/LightingManagerDimmable.cpp similarity index 100% rename from examples/platform/nxp/k32w1/util/LightingManagerDimmable.cpp rename to examples/platform/nxp/mcxw71_k32w1/util/LightingManagerDimmable.cpp diff --git a/examples/platform/nxp/k32w1/util/LightingManagerDimmable.h b/examples/platform/nxp/mcxw71_k32w1/util/LightingManagerDimmable.h similarity index 100% rename from examples/platform/nxp/k32w1/util/LightingManagerDimmable.h rename to examples/platform/nxp/mcxw71_k32w1/util/LightingManagerDimmable.h diff --git a/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp b/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp index 50992a049f01a5..489c867f0ea254 100644 --- a/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp +++ b/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp @@ -25,6 +25,11 @@ #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA #include "FactoryDataProvider.h" +#ifdef ENABLE_SECURE_WHOLE_FACTORY_DATA +static uint8_t aes256TestKey[] + __attribute__((aligned)) = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; +#endif #else #include #endif @@ -47,6 +52,12 @@ CHIP_ERROR NXP::App::AppFactoryData_PreMatterStackInit(void) CHIP_ERROR NXP::App::AppFactoryData_PostMatterStackInit(void) { #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#ifdef ENABLE_SECURE_WHOLE_FACTORY_DATA + /* Please Note, because currently we only support AES-256 key provisioning and de-wrap, so the trasfterred AES key should be 256 + * bit size*/ + FactoryDataPrvdImpl().SetEncryptionMode(FactoryDataProvider::encrypt_ecb); + FactoryDataPrvdImpl().SetAes256Key(&aes256TestKey[0]); +#endif FactoryDataPrvdImpl().Init(); SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 409fa9efbbce0a..711ebf0d655f20 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -83,10 +83,18 @@ rt_sdk("sdk") { include_dirs += [ "${example_platform_dir}/board/" ] sources += [ "${example_platform_dir}/board/pin_mux.c" ] sources += [ "${example_platform_dir}/board/hardware_init.c" ] - sources += [ "${example_platform_dir}/board/clock_config.c" ] - sources += [ "${example_platform_dir}/board/board.c" ] sources += [ "${example_platform_dir}/board/peripherals.c" ] + if (board_version == "frdm") { + include_dirs += [ "${example_platform_dir}/board/frdmrw612/" ] + sources += [ "${example_platform_dir}/board/frdmrw612/clock_config.c" ] + sources += [ "${example_platform_dir}/board/frdmrw612/board.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/rdrw612bga/" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/clock_config.c" ] + sources += [ "${example_platform_dir}/board/rdrw612bga/board.c" ] + } + # Indicate the path to CHIPProjectConfig.h include_dirs += [ "include/config" ] @@ -98,7 +106,7 @@ rt_sdk("sdk") { # For matter with BR feature, increase FreeRTOS heap size if (chip_enable_wifi && chip_enable_openthread) { - defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] } } @@ -139,9 +147,7 @@ rt_executable("thermostat") { ] if (chip_enable_secure_dac_private_key_storage == 1) { - sources += [ - "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", - ] + sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] } else { sources += [ "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 00678e8b0cc246..3592400fc0c631 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -126,8 +126,7 @@ def __init__(self, enable_wifi: bool = False, disable_ipv4: bool = False, enable_shell: bool = False, - enable_ota: bool = False, - is_sdk_package: bool = True): + enable_ota: bool = False): super(NxpBuilder, self).__init__( root=app.BuildRoot(root, board, os_env), runner=runner) @@ -149,7 +148,6 @@ def __init__(self, self.enable_wifi = enable_wifi self.enable_ota = enable_ota self.enable_shell = enable_shell - self.is_sdk_package = is_sdk_package def GnBuildArgs(self): args = [] @@ -198,11 +196,6 @@ def GnBuildArgs(self): # thread is enabled by default on kw32 if self.board == NxpBoard.RW61X: args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') - if self.enable_wifi: - args.append('openthread_root=\\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\\"') - - if self.is_sdk_package: - args.append('is_sdk_package=true') return args diff --git a/scripts/setup/nxp/update_nxp_sdk.py b/scripts/setup/nxp/update_nxp_sdk.py deleted file mode 100755 index da948306f887d7..00000000000000 --- a/scripts/setup/nxp/update_nxp_sdk.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import argparse -import logging -import os -import shutil -import subprocess -import sys -from dataclasses import dataclass - -CHIP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')) - - -@dataclass(init=False) -class NxpSdk: - sdk_name: str - sdk_target_location: str - sdk_manifest_path: str - - def __init__(self, name, sdk_target_location): - self.sdk_name = name - self.sdk_target_location = sdk_target_location - self.sdk_manifest_path = os.path.abspath(os.path.join(sdk_target_location, 'manifest')) - - -def NxpSdk_k32w0(): - rel_path_k32w0 = 'third_party/nxp/nxp_matter_support/github_sdk/k32w0' - sdk = NxpSdk('k32w0', os.path.abspath(os.path.join(CHIP_ROOT, rel_path_k32w0))) - return sdk - - -ALL_PLATFORM_SDK = [ - NxpSdk_k32w0(), -] - -ALL_PLATFORM_NAME = [p.sdk_name for p in ALL_PLATFORM_SDK] - - -def clean_sdk_local_changes(sdk_location): - logging.warning("SDK will be cleaned all local modification(s) will be lost") - # Cleaning all local modifications - git_clean_command = "git reset --hard && git clean -xdf" - command = ['west', 'forall', '-c', git_clean_command, '-a'] - subprocess.run(command, cwd=sdk_location, check=True) - - -def init_nxp_sdk_version(nxp_sdk, force): - print("Init SDK in: " + nxp_sdk.sdk_target_location) - west_path = os.path.join(nxp_sdk.sdk_target_location, '.west') - if os.path.exists(west_path): - if not force: - logging.error("SDK is already initialized, use --force to force init") - sys.exit(1) - shutil.rmtree(west_path) - - command = ['west', 'init', '-l', nxp_sdk.sdk_manifest_path, '--mf', 'west.yml'] - subprocess.run(command, check=True) - update_nxp_sdk_version(nxp_sdk, force) - - -def update_nxp_sdk_version(nxp_sdk, force): - print("Update SDK in " + nxp_sdk.sdk_target_location) - if not os.path.exists(os.path.join(nxp_sdk.sdk_target_location, '.west')): - logging.error("--update-only error SDK is not initialized") - sys.exit(1) - command = ['west', 'update', '--fetch', 'smart'] - try: - subprocess.run(command, cwd=nxp_sdk.sdk_target_location, check=True) - except (RuntimeError, subprocess.CalledProcessError) as exception: - if force: - if nxp_sdk.sdk_name == 'k32w0': - logging.error('Force update not yet supported for %s platform', nxp_sdk.sdk_name) - else: - # In case of force update option and in case of update failure: - # 1. try to clean all local modications if any - # 2. Retry the west update command. It should be successfull now as all local modifications have been cleaned - clean_sdk_local_changes(nxp_sdk.sdk_target_location) - subprocess.run(command, cwd=nxp_sdk.sdk_target_location, check=True) - else: - logging.exception( - 'Error SDK cannot be updated, local changes should be cleaned manually or use --force to force update %s', exception) - - -def main(): - - parser = argparse.ArgumentParser(description='Checkout or update relevant NXP SDK') - parser.add_argument( - "--update-only", help="Update NXP SDK to the correct version. Would fail if the SDK does not exist", action="store_true") - parser.add_argument('--platform', nargs='+', choices=ALL_PLATFORM_NAME, default=ALL_PLATFORM_NAME, - help='Allows to select which SDK for a particular NXP platform to initialize') - parser.add_argument('--force', action='store_true', - help='Force SDK initialization, hard clean will be done in case of failure - WARNING -- All local SDK modification(s) will be lost') - - args = parser.parse_args() - - for current_plat in args.platform: - nxp_sdk = [p for p in ALL_PLATFORM_SDK if p.sdk_name == current_plat][0] - if args.update_only: - update_nxp_sdk_version(nxp_sdk, args.force) - else: - init_nxp_sdk_version(nxp_sdk, args.force) - - -if __name__ == '__main__': - main() diff --git a/scripts/tools/nxp/factory_data_generator/generate.py b/scripts/tools/nxp/factory_data_generator/generate.py index b3ee98562b6c3a..945f8bde641749 100755 --- a/scripts/tools/nxp/factory_data_generator/generate.py +++ b/scripts/tools/nxp/factory_data_generator/generate.py @@ -106,7 +106,7 @@ def generate(self): return data - def to_bin(self, klv, out, aes128_key): + def to_bin(self, klv, out, aes_key): fullContent = bytearray() with open(out, "wb") as file: for entry in klv: @@ -115,7 +115,7 @@ def to_bin(self, klv, out, aes128_key): fullContent += entry[2] size = len(fullContent) - if (aes128_key is None): + if (aes_key is None): # Calculate 4 bytes of hashing hashing = hashlib.sha256(fullContent).hexdigest() hashing = hashing[0:8] @@ -146,7 +146,7 @@ def to_bin(self, klv, out, aes128_key): logging.info("Size of final generated binary is: {} bytes".format(size)) file.write(fullContent) else: - # In case a aes128_key is given the data will be encrypted + # In case a aes_key is given the data will be encrypted # Always add a padding to be 16 bytes aligned padding_len = size % 16 padding_len = 16 - padding_len @@ -156,7 +156,7 @@ def to_bin(self, klv, out, aes128_key): size = len(fullContent) logging.info("(After padding) Size of generated binary is: {} bytes".format(size)) from Crypto.Cipher import AES - cipher = AES.new(bytes.fromhex(aes128_key), AES.MODE_ECB) + cipher = AES.new(bytes.fromhex(aes_key), AES.MODE_ECB) fullContentCipher = cipher.encrypt(fullContent) # Add 4 bytes of hashing to generated binary to check for integrity @@ -229,6 +229,8 @@ def main(): help="[base64 str] Already generated spake2p verifier") optional.add_argument("--aes128_key", help="[hex] AES 128 bits key used to encrypt the whole dataset") + optional.add_argument("--aes256_key", + help="[hex] AES 256 bits key used to encrypt the whole dataset") optional.add_argument("--date", type=ManufacturingDate, help="[str] Manufacturing Date (YYYY-MM-DD)") optional.add_argument("--part_number", type=PartNumber, @@ -252,7 +254,12 @@ def main(): klv = KlvGenerator(args) data = klv.generate() - klv.to_bin(data, args.out, args.aes128_key) + aes_key = None + if args.aes256_key: + aes_key = args.aes256_key + elif args.aes128_key: + aes_key = args.aes128_key + klv.to_bin(data, args.out, aes_key) if __name__ == "__main__": diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.cpp b/src/platform/nxp/common/ConfigurationManagerImpl.cpp index ad8f00eaf3a4cb..09fb98abac6a3f 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/common/ConfigurationManagerImpl.cpp @@ -106,7 +106,6 @@ CHIP_ERROR ConfigurationManagerImpl::Init() { CHIP_ERROR err; uint32_t rebootCount = 0; - bool failSafeArmed; #if CONFIG_BOOT_REASON_SDK_SUPPORT uint8_t rebootCause = POWER_GetResetCause(); diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index cbdb866ae71973..9c3eb7fb7a88e8 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -48,21 +48,23 @@ extern "C" { #include "wlan.h" #include "wm_net.h" -#include } #include #if CHIP_DEVICE_CONFIG_ENABLE_THREAD -#include +#include +#include "border_agent.h" #include "br_rtos_manager.h" +#include "infra_if.h" #endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ #endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ #if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include "ConnectivityManagerImpl.h" #include #endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ @@ -319,7 +321,6 @@ int ConnectivityManagerImpl::_WlanEventCallback(enum wlan_event_reason wlanEvent void ConnectivityManagerImpl::OnStationConnected() { - CHIP_ERROR err; ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; @@ -332,7 +333,6 @@ void ConnectivityManagerImpl::OnStationConnected() void ConnectivityManagerImpl::OnStationDisconnected() { - CHIP_ERROR err; ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; @@ -353,9 +353,6 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() const ip6_addr_t * addr6; CHIP_ERROR err; ChipDeviceEvent event; -#if CHIP_ENABLE_OPENTHREAD - otIp6Address newIpAddress; -#endif // If the WiFi station is currently in the connected state... if (_IsWiFiStationConnected()) @@ -392,11 +389,6 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() { haveIPv6Conn = true; addr6 = netif_ip6_addr(netif, i); -#if CHIP_ENABLE_OPENTHREAD - // We are using ot mDNS sever and need to add IP address to server list - memcpy(&newIpAddress.mFields.m32, addr6->addr, sizeof(Inet::IPAddress)); - otMdnsServerAddAddress(ThreadStackMgrImpl().OTInstance(), &newIpAddress); -#endif break; } } @@ -428,20 +420,29 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_NoChange; event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); - if (haveIPv6Conn) - { - event.InternetConnectivityChange.ipAddress = IPAddress(*addr6); #if CHIP_ENABLE_OPENTHREAD - // Start the Border Router services including MDNS Server - StartBrServices(); + // In case of boot, start the Border Router services including MDNS Server, otherwise inform of link state change + // The posted event will signal the application to restart the Matter mDNS server instance + bool bLinkState = event.InternetConnectivityChange.IPv6 == kConnectivity_Established ? true : false; + BrHandleStateChange(bLinkState); #endif + if (haveIPv6Conn) + { + event.InternetConnectivityChange.ipAddress = IPAddress(*addr6); } err = PlatformMgr().PostEvent(&event); VerifyOrDie(err == CHIP_NO_ERROR); ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv6", (haveIPv6Conn) ? "ESTABLISHED" : "LOST"); } + +#if CHIP_ENABLE_OPENTHREAD + if (haveIPv6Conn && UpdateIp6AddrList()) + { + UpdateMdnsHost(); + } +#endif } void ConnectivityManagerImpl::_NetifExtCallback(struct netif * netif, netif_nsc_reason_t reason, @@ -463,7 +464,6 @@ void ConnectivityManagerImpl::_NetifExtCallback(struct netif * netif, netif_nsc_ void ConnectivityManagerImpl::StartWiFiManagement() { struct netif * netif = nullptr; - EventBits_t bits; int32_t result; LOCK_TCPIP_CORE(); @@ -484,35 +484,107 @@ void ConnectivityManagerImpl::StartWiFiManagement() } } #if CHIP_ENABLE_OPENTHREAD -void ConnectivityManagerImpl::StartBrServices() +void ConnectivityManagerImpl::BrHandleStateChange(bool bLinkState) { if (mBorderRouterInit == false) { - struct netif * extNetIfPtr = static_cast(net_get_mlan_handle()); - struct netif * thrNetIfPtr = ThreadStackMgrImpl().ThreadNetIf(); - otInstance * thrInstancePtr; - - // Initalize internal interface variables, these can be used by other modules like the DNSSD Impl to - // get the underlying IP interface - Inet::InterfaceId tmpExtIf(extNetIfPtr); - Inet::InterfaceId tmpThrIf(thrNetIfPtr); - mExternalNetIf = tmpExtIf; - mThreadNetIf = tmpThrIf; - - // Need to wait for the wifi to be connected because the mlan netif can be !=null but not initialized - // properly. If the thread netif is !=null it means that it was fully initialized - - // Lock OT task - if ((thrNetIfPtr) && (mWiFiStationState == kWiFiStationState_Connected)) + if (bLinkState) { - mBorderRouterInit = true; - // Check if OT instance is init - thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + struct netif * extNetIfPtr = static_cast(net_get_mlan_handle()); + struct netif * thrNetIfPtr = ThreadStackMgrImpl().ThreadNetIf(); + otInstance * thrInstancePtr; + + // Need to wait for the wifi to be connected because the mlan netif can be !=null but not initialized + // properly. If the thread netif is !=null it means that it was fully initialized - BrInitServices(thrInstancePtr, extNetIfPtr, thrNetIfPtr); - otMdnsServerStart(thrInstancePtr); + // Lock OT task ? + if ((thrNetIfPtr) && (mWiFiStationState == kWiFiStationState_Connected)) + { + // Initalize internal interface variables, these can be used by other modules like the DNSSD Impl to + // get the underlying IP interface + Inet::InterfaceId tmpExtIf(extNetIfPtr); + Inet::InterfaceId tmpThrIf(thrNetIfPtr); + mExternalNetIf = tmpExtIf; + mThreadNetIf = tmpThrIf; + + mBorderRouterInit = true; + // Check if OT instance is init + thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + BrInitPlatform(thrInstancePtr, extNetIfPtr, thrNetIfPtr); + BrInitServices(); + + UpdateIp6AddrList(); + UpdateMdnsHost(); + BorderAgentInit(thrInstancePtr, mHostname); + } } } + else + { + InfraIfLinkState(bLinkState); + } +} + +void ConnectivityManagerImpl::UpdateMdnsHost() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + otMdnsHost mdnsHost; + + if (strlen(mHostname) == 0) + { + uint8_t macBuffer[ConfigurationManager::kPrimaryMACAddressLength]; + MutableByteSpan mac(macBuffer); + err = DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac); + SuccessOrExit(err); + + chip::Dnssd::MakeHostName(mHostname, sizeof(mHostname), mac); + } + + mdnsHost.mAddresses = mIp6AddrList; + mdnsHost.mAddressesLength = mIp6AddrNum; + mdnsHost.mHostName = mHostname; + mdnsHost.mInfraIfIndex = netif_get_index(mExternalNetIf.GetPlatformInterface()); + + // Allways use ID 0 for host + otMdnsRegisterHost(ThreadStackMgrImpl().OTInstance(), &mdnsHost, 0, nullptr); + +exit: + return; +} + +bool ConnectivityManagerImpl::UpdateIp6AddrList() +{ + const ip6_addr_t * addr6 = nullptr; + bool bAddrChange = false; + uint32_t newIp6AddrNum = 0; + struct netif * extNetIfPtr = mExternalNetIf.GetPlatformInterface(); + uint32_t lwipIterator, addrListIterator; + + for (lwipIterator = 0; lwipIterator < LWIP_IPV6_NUM_ADDRESSES; lwipIterator++) + { + if (ip6_addr_ispreferred(netif_ip6_addr_state(extNetIfPtr, lwipIterator)) && (mIp6AddrNum <= kMaxIp6Addr)) + { + addr6 = netif_ip6_addr(extNetIfPtr, lwipIterator); + for (addrListIterator = 0; addrListIterator < kMaxIp6Addr; addrListIterator++) + { + if (0 == memcmp(&mIp6AddrList[addrListIterator].mFields.m32, addr6->addr, sizeof(Inet::IPAddress))) + { + break; + } + } + if (addrListIterator == kMaxIp6Addr) + { + bAddrChange |= true; + } + memcpy(&mIp6AddrList[newIp6AddrNum++].mFields.m32, addr6->addr, sizeof(Inet::IPAddress)); + } + } + + bAddrChange |= (newIp6AddrNum != mIp6AddrNum) ? true : false; + mIp6AddrNum = newIp6AddrNum; + + return bAddrChange; } Inet::InterfaceId ConnectivityManagerImpl::GetThreadInterface() @@ -532,7 +604,6 @@ CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, uint #if CHIP_DEVICE_CONFIG_ENABLE_WPA CHIP_ERROR ret = CHIP_NO_ERROR; struct wlan_network * pNetworkData = (struct wlan_network *) malloc(sizeof(struct wlan_network)); - int result; VerifyOrExit(pNetworkData != NULL, ret = CHIP_ERROR_NO_MEMORY); VerifyOrExit(ssidLen <= IEEEtypes_SSID_SIZE, ret = CHIP_ERROR_INVALID_ARGUMENT); diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.h b/src/platform/nxp/common/ConnectivityManagerImpl.h index 82ce24f814d544..9327e4d2d1ec9b 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.h +++ b/src/platform/nxp/common/ConnectivityManagerImpl.h @@ -20,6 +20,7 @@ #pragma once +#include #include #include #include @@ -93,6 +94,7 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #if CHIP_ENABLE_OPENTHREAD Inet::InterfaceId GetExternalInterface(); Inet::InterfaceId GetThreadInterface(); + const char * GetHostName() { return sInstance.mHostname; } #endif #endif @@ -144,8 +146,14 @@ class ConnectivityManagerImpl final : public ConnectivityManager, static netif_ext_callback_t sNetifCallback; #if CHIP_ENABLE_OPENTHREAD + static constexpr uint8_t kMaxIp6Addr = 3; + Inet::InterfaceId mThreadNetIf; Inet::InterfaceId mExternalNetIf; + + char mHostname[chip::Dnssd::kHostNameMaxLength + 1] = ""; + otIp6Address mIp6AddrList[kMaxIp6Addr]; + uint32_t mIp6AddrNum = 0; #endif static int _WlanEventCallback(enum wlan_event_reason event, void * data); @@ -155,9 +163,12 @@ class ConnectivityManagerImpl final : public ConnectivityManager, void OnStationDisconnected(void); void UpdateInternetConnectivityState(void); #if CHIP_ENABLE_OPENTHREAD - void StartBrServices(void); + void BrHandleStateChange(bool bLinkState); + void UpdateMdnsHost(void); + bool UpdateIp6AddrList(void); #endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ -#endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ +#endif + /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ }; inline bool ConnectivityManagerImpl::_HaveIPv4InternetConnectivity(void) diff --git a/src/platform/nxp/common/DnssdImpl.cpp b/src/platform/nxp/common/DnssdImpl.cpp index 743e4ab30cafa1..d0069cebcf1c4a 100644 --- a/src/platform/nxp/common/DnssdImpl.cpp +++ b/src/platform/nxp/common/DnssdImpl.cpp @@ -24,7 +24,8 @@ #include -#include +#include +#include using namespace ::chip::DeviceLayer; using namespace chip::DeviceLayer::Internal; @@ -32,9 +33,7 @@ using namespace chip::DeviceLayer::Internal; namespace chip { namespace Dnssd { -#define LOCAL_DOMAIN_STRING_SIZE 7 -#define ARPA_DOMAIN_STRING_SIZE 22 -#define MATTER_DNS_TXT_SIZE 128 +#define USE_MDNS_NEXT_SERVICE_API 1 // Support both operational and commissionable discovery, so buffers sizes must be worst case. static constexpr uint8_t kMaxMdnsServiceTxtEntriesNumber = @@ -47,6 +46,9 @@ static constexpr size_t kTotalMdnsServiceTxtKeySize = static constexpr size_t kTotalMdnsServiceTxtBufferSize = kTotalMdnsServiceTxtKeySize + kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtValueSize; +// For each fabric we can register one _matter._tcp and one _matterc._udp service +static constexpr uint32_t kServiceListSize = CHIP_CONFIG_MAX_FABRICS * 2; + static const char * GetProtocolString(DnssdServiceProtocol protocol) { return protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp"; @@ -63,99 +65,192 @@ struct mDnsQueryCtx void * matterCtx; chip::Dnssd::DnssdService mMdnsService; DnsServiceTxtEntries mServiceTxtEntry; - char mServiceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1]; + char mServiceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1]; CHIP_ERROR error; + union + { + otMdnsBrowser mBrowseInfo; + otMdnsSrvResolver mSrvInfo; + otMdnsTxtResolver mTxtInfo; + otMdnsAddressResolver mAddrInfo; + }; + union + { + DnsBrowseCallback mDnsBrowseCallback; + DnsResolveCallback mDnsResolveCallback; + }; - mDnsQueryCtx(void * context, CHIP_ERROR aError) + mDnsQueryCtx(void * context, DnsBrowseCallback aBrowseCallback) { - matterCtx = context; - error = aError; + matterCtx = context; + mDnsBrowseCallback = aBrowseCallback; + error = CHIP_NO_ERROR; } + mDnsQueryCtx(void * context, DnsResolveCallback aResolveCallback) + { + matterCtx = context; + mDnsResolveCallback = aResolveCallback; + error = CHIP_NO_ERROR; + } +}; + +enum ResolveStep : uint8_t +{ + kResolveStepSrv = 0, + kResolveStepTxt, + kResolveStepIpAddr, }; static const char * GetProtocolString(DnssdServiceProtocol protocol); -static void OtBrowseCallback(otError aError, const otDnsBrowseResponse * aResponse, void * aContext); -static void OtServiceCallback(otError aError, const otDnsServiceResponse * aResponse, void * aContext); +static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult); +static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult); +static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult); +static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult); static void DispatchBrowseEmpty(intptr_t context); static void DispatchBrowse(intptr_t context); -static void DispatchBrowseNoMemory(intptr_t context); -void DispatchAddressResolve(intptr_t context); -void DispatchResolve(intptr_t context); -void DispatchResolveNoMemory(intptr_t context); +static void DispatchTxtResolve(intptr_t context); +static void DispatchAddressResolve(intptr_t context); +static void DispatchResolve(intptr_t context); +static void DispatchResolveError(intptr_t context); -static DnsBrowseCallback mDnsBrowseCallback; -static DnsResolveCallback mDnsResolveCallback; +static void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType); -CHIP_ERROR ResolveBySrp(DnssdService * mdnsReq, otInstance * thrInstancePtr, char * instanceName, void * context); -CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * context); +static CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq); +static CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context); +static CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, + const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, + DnsServiceTxtEntries & serviceTxtEntries); -CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, - const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, - DnsServiceTxtEntries & serviceTxtEntries); +static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType); static bool bBrowseInProgress = false; +// ID 0 is reserved for host +static uint32_t mRegisterServiceId = 1; +static uint8_t mNetifIndex = 0; + +// Matter currently only supports one browse and resolve operation at a time so there is no need to create a list +// If the Matter implementation evolves in the future this functionality can be extended to a list. +static mDnsQueryCtx * mBrowseContext = nullptr; +static mDnsQueryCtx * mResolveContext = nullptr; + +#if USE_MDNS_NEXT_SERVICE_API +static otMdnsService * mServiceList[kServiceListSize]; +static uint32_t mServiceListFreeIndex; +#endif CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) { CHIP_ERROR error = CHIP_NO_ERROR; otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + struct netif * extNetif = (ConnectivityManagerImpl().GetExternalInterface()).GetPlatformInterface(); - uint8_t macBuffer[ConfigurationManager::kPrimaryMACAddressLength]; - MutableByteSpan mac(macBuffer); - char hostname[kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; - ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac)); - MakeHostName(hostname, sizeof(hostname), mac); - snprintf(hostname + strlen(hostname), sizeof(hostname), ".local."); + // Don't try to do anything until the mDNS server is started + VerifyOrExit(otMdnsIsEnabled(thrInstancePtr), error = CHIP_ERROR_INCORRECT_STATE); - error = MapOpenThreadError(otMdnsServerSetHostName(thrInstancePtr, hostname)); + mNetifIndex = netif_get_index(extNetif); +exit: initCallback(context, error); return error; } void ChipDnssdShutdown() { - otMdnsServerStop(ThreadStackMgrImpl().OTInstance()); + otMdnsSetEnabled(ThreadStackMgrImpl().OTInstance(), false, 0); } +#if USE_MDNS_NEXT_SERVICE_API +CHIP_ERROR ChipDnssdRemoveServices() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + otMdnsIterator * iterator = nullptr; + ChipError error = CHIP_NO_ERROR; + otError otError = OT_ERROR_NONE; + otMdnsEntryState state; + + const char * hostName = ConnectivityManagerImpl().GetHostName(); + + iterator = otMdnsAllocateIterator(thrInstancePtr); + VerifyOrExit(iterator != nullptr, error = CHIP_ERROR_NO_MEMORY); + + mServiceListFreeIndex = 0; + + while (mServiceListFreeIndex <= kServiceListSize) + { + // allocate memory for new entry if the entry is not allready allocated from previous iteration + if (mServiceList[mServiceListFreeIndex] == nullptr) + { + mServiceList[mServiceListFreeIndex] = static_cast(Platform::MemoryAlloc(sizeof(otMdnsService))); + VerifyOrExit(mServiceList[mServiceListFreeIndex] != nullptr, error = CHIP_ERROR_NO_MEMORY); + } + + otError = otMdnsGetNextService(thrInstancePtr, iterator, mServiceList[mServiceListFreeIndex], &state); + if (otError == OT_ERROR_NOT_FOUND) + { + Platform::MemoryFree(mServiceList[mServiceListFreeIndex]); + mServiceList[mServiceListFreeIndex] = nullptr; + break; + } + + if ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mHostName, hostName)) && + ((0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matter._tcp")) || + (0 == strcmp(mServiceList[mServiceListFreeIndex]->mServiceType, "_matterc._udp")))) + { + mServiceListFreeIndex++; + } + } +exit: + if (iterator != nullptr) + { + otMdnsFreeIterator(thrInstancePtr, iterator); + } + return error; +} +#else CHIP_ERROR ChipDnssdRemoveServices() { otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + + otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); - otMdnsServerMarkServiceForRemoval(thrInstancePtr, nullptr, "_matter._tcp.local."); - otMdnsServerMarkServiceForRemoval(thrInstancePtr, nullptr, "_matterc._udp.local."); + otServiceData.mServiceType = "_matter._tcp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); + otServiceData.mServiceType = "_matterc._udp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_MARK_FOR_UNREGISTER); return CHIP_NO_ERROR; } +#endif CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) { ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otError otErr; - otDnsTxtEntry aTxtEntry; - uint32_t txtBufferOffset = 0; + uint32_t txtBufferOffset = 0; + otError otErr = OT_ERROR_NONE; + otMdnsService otServiceData = { 0 }; + +#if USE_MDNS_NEXT_SERVICE_API + bool bRegisterService = true; +#endif + + char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + 1] = ""; + snprintf(serviceType, sizeof(serviceType), "%s.%s", service->mType, GetProtocolString(service->mProtocol)); - char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1] = - ""; - char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; // secure space for the raw TXT data in the worst-case scenario relevant for Matter: // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize] = { 0 }; - if ((strcmp(service->mHostName, "") != 0) && (nullptr == otMdnsServerGetHostName(thrInstancePtr))) - { - char hostname[kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; - snprintf(hostname, sizeof(hostname), "%s.local.", service->mHostName); - otMdnsServerSetHostName(thrInstancePtr, hostname); - } - - snprintf(serviceType, sizeof(serviceType), "%s.%s.local.", service->mType, GetProtocolString(service->mProtocol)); - snprintf(fullInstName, sizeof(fullInstName), "%s.%s", service->mName, serviceType); + // Don't try to do anything until the mDNS server is started + VerifyOrReturnValue(otMdnsIsEnabled(thrInstancePtr), CHIP_NO_ERROR); + // Create TXT Data as one string from multiple key entries for (uint32_t i = 0; i < service->mTextEntrySize; i++) { uint32_t keySize = strlen(service->mTextEntries[i].mKey); @@ -174,56 +269,124 @@ CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCal txtBufferOffset += service->mTextEntries[i].mDataSize; } } - aTxtEntry.mKey = nullptr; - aTxtEntry.mValue = txtBuffer; - aTxtEntry.mValueLength = txtBufferOffset; - otErr = otMdnsServerAddService(thrInstancePtr, fullInstName, serviceType, service->mSubTypes, service->mSubTypeSize, - service->mPort, &aTxtEntry, 1); - // Ignore duplicate error and threat it as error none - if (otErr == OT_ERROR_DUPLICATED) - otErr = OT_ERROR_NONE; +#if USE_MDNS_NEXT_SERVICE_API + for (uint32_t i = 0; i < mServiceListFreeIndex; i++) + { + if ((0 == strcmp(mServiceList[i]->mHostName, service->mHostName)) && + (0 == strcmp(mServiceList[i]->mServiceInstance, service->mName)) && + (0 == strcmp(mServiceList[i]->mServiceType, serviceType))) + { + if ((mServiceList[i]->mTxtDataLength == txtBufferOffset) && + (0 == memcmp(txtBuffer, mServiceList[i]->mTxtData, txtBufferOffset))) + { + // In this case the service is + bRegisterService = false; + } + Platform::MemoryFree(mServiceList[i]); + if (i < --mServiceListFreeIndex) + { + // move last element in place of the removed one + mServiceList[i] = mServiceList[mServiceListFreeIndex]; + mServiceList[mServiceListFreeIndex] = nullptr; + } + else + { + mServiceList[i] = nullptr; + } + break; + } + } +#endif + if (bRegisterService) + { + if (strcmp(service->mHostName, "") != 0) + { + otServiceData.mHostName = service->mHostName; + } + + otServiceData.mServiceInstance = service->mName; + otServiceData.mServiceType = serviceType; + otServiceData.mSubTypeLabels = service->mSubTypes; + otServiceData.mSubTypeLabelsLength = service->mSubTypeSize; + otServiceData.mPort = service->mPort; + otServiceData.mTtl = service->mTtlSeconds; + otServiceData.mTxtData = txtBuffer; + otServiceData.mTxtDataLength = txtBufferOffset; + + otErr = otMdnsRegisterService(thrInstancePtr, &otServiceData, mRegisterServiceId++, NULL); + } return MapOpenThreadError(otErr); } +#if USE_MDNS_NEXT_SERVICE_API +CHIP_ERROR ChipDnssdFinalizeServiceUpdate() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + for (uint32_t i = 0; i < mServiceListFreeIndex; i++) + { + if (mServiceList[i] != nullptr) + { + otMdnsUnregisterService(thrInstancePtr, mServiceList[i]); + Platform::MemoryFree(mServiceList[i]); + mServiceList[i] = nullptr; + } + } + + mServiceListFreeIndex = 0; + return CHIP_NO_ERROR; +} + +#else CHIP_ERROR ChipDnssdFinalizeServiceUpdate() { - otMdnsServerRemoveMarkedServices(ThreadStackMgrImpl().OTInstance()); + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsService otServiceData = { 0 }; + + otServiceData.mHostName = ConnectivityManagerImpl().GetHostName(); + + otServiceData.mServiceType = "_matter._tcp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); + otServiceData.mServiceType = "_matterc._udp"; + otMdnsUnregisterServiceType(thrInstancePtr, &otServiceData, OT_MDNS_SERVICE_UNREGISTER_MARKED_SERVICE); + return CHIP_NO_ERROR; } +#endif CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier) { - *browseIdentifier = reinterpret_cast(nullptr); - CHIP_ERROR error = CHIP_NO_ERROR; - CHIP_ERROR srpBrowseError = CHIP_NO_ERROR; - char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = ""; // +1 for null-terminator + *browseIdentifier = reinterpret_cast(nullptr); + CHIP_ERROR error = CHIP_NO_ERROR; + CHIP_ERROR srpBrowseError = CHIP_NO_ERROR; + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); if (type == nullptr || callback == nullptr) return CHIP_ERROR_INVALID_ARGUMENT; - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - mDnsBrowseCallback = callback; - - mDnsQueryCtx * browseContext = Platform::New(context, CHIP_NO_ERROR); - VerifyOrReturnError(browseContext != nullptr, CHIP_ERROR_NO_MEMORY); + mBrowseContext = Platform::New(context, callback); + VerifyOrReturnError(mBrowseContext != nullptr, CHIP_ERROR_NO_MEMORY); - // First try to browse the service in the SRP cache, use default.service.arpa as domain name - snprintf(serviceType, sizeof(serviceType), "%s.%s.default.service.arpa.", type, GetProtocolString(protocol)); + // First try to browse the service in the SRP cache + snprintf(mBrowseContext->mServiceType, sizeof(mBrowseContext->mServiceType), "%s.%s", type, GetProtocolString(protocol)); // After browsing in the SRP cache we will continue with regular mDNS browse - srpBrowseError = BrowseBySrp(thrInstancePtr, serviceType, context); + srpBrowseError = BrowseBySrp(thrInstancePtr, mBrowseContext->mServiceType, mBrowseContext); // Proceed to generate a mDNS query - snprintf(browseContext->mServiceType, sizeof(browseContext->mServiceType), "%s.%s.local.", type, GetProtocolString(protocol)); + mBrowseContext->mBrowseInfo.mServiceType = mBrowseContext->mServiceType; + mBrowseContext->mBrowseInfo.mSubTypeLabel = nullptr; + mBrowseContext->mBrowseInfo.mInfraIfIndex = mNetifIndex; + mBrowseContext->mBrowseInfo.mCallback = OtBrowseCallback; - error = MapOpenThreadError(otMdnsServerBrowse(thrInstancePtr, browseContext->mServiceType, OtBrowseCallback, browseContext)); + error = MapOpenThreadError(otMdnsStartBrowser(thrInstancePtr, &mBrowseContext->mBrowseInfo)); if (CHIP_NO_ERROR == error) { bBrowseInProgress = true; - *browseIdentifier = reinterpret_cast(browseContext); + *browseIdentifier = reinterpret_cast(mBrowseContext); } else { @@ -231,12 +394,13 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Ine { // In this case, we need to send a final browse indication to signal the Matter App that there are no more // browse results coming - browseContext->error = error; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + mBrowseContext->error = error; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(mBrowseContext)); } else { - Platform::Delete(browseContext); + Platform::Delete(mBrowseContext); + mBrowseContext = nullptr; } } return error; @@ -249,54 +413,73 @@ CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) otError error = OT_ERROR_INVALID_ARGS; // browseContext is only valid when bBrowseInProgress is true. The Matter stack can call this function even with a browseContext - // that has been freed in DispatchBrowseEmpty before. + // that has been freed in DispatchBrowseEmpty. if ((true == bBrowseInProgress) && (browseContext)) { - browseContext->error = MapOpenThreadError(otMdnsServerStopQuery(thrInstancePtr, browseContext->mServiceType)); + browseContext->error = MapOpenThreadError(otMdnsStopBrowser(thrInstancePtr, &browseContext->mBrowseInfo)); // browse context will be freed in DispatchBrowseEmpty - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + DispatchBrowseEmpty(reinterpret_cast(browseContext)); } return MapOpenThreadError(error); } CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) { - ChipError error; + ChipError error = CHIP_ERROR_NOT_FOUND; + if (browseResult == nullptr || callback == nullptr) return CHIP_ERROR_INVALID_ARGUMENT; otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - mDnsResolveCallback = callback; - char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = ""; // +1 for null-terminator - char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = - ""; + mResolveContext = Platform::New(context, callback); + VerifyOrReturnError(mResolveContext != nullptr, CHIP_ERROR_NO_MEMORY); // First try to find the service in the SRP cache, use default.service.arpa as domain name - snprintf(serviceType, sizeof(serviceType), "%s.%s.default.service.arpa.", browseResult->mType, + snprintf(mResolveContext->mServiceType, sizeof(mResolveContext->mServiceType), "%s.%s", browseResult->mType, GetProtocolString(browseResult->mProtocol)); - snprintf(fullInstName, sizeof(fullInstName), "%s.%s", browseResult->mName, serviceType); - error = ResolveBySrp(browseResult, thrInstancePtr, fullInstName, context); + error = ResolveBySrp(thrInstancePtr, mResolveContext->mServiceType, mResolveContext, browseResult); + // If the SRP cache returns not found, proceed to generate a MDNS query if (CHIP_ERROR_NOT_FOUND == error) { - // If the SRP cache returns not found, proceed to generate a MDNS query - memset(serviceType, 0, sizeof(serviceType)); - memset(fullInstName, 0, sizeof(fullInstName)); + // The otMdnsSrvResolver structure contains only pointers to instance name and service type strings + // Use the memory from mMdnsService.mName to store the instance name string we are looking for + Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), browseResult->mName); - snprintf(serviceType, sizeof(serviceType), "%s.%s.local.", browseResult->mType, GetProtocolString(browseResult->mProtocol)); - snprintf(fullInstName, sizeof(fullInstName), "%s.%s", browseResult->mName, serviceType); + mResolveContext->mSrvInfo.mInfraIfIndex = mNetifIndex; + mResolveContext->mSrvInfo.mCallback = OtServiceCallback; + mResolveContext->mSrvInfo.mServiceInstance = mResolveContext->mMdnsService.mName; + mResolveContext->mSrvInfo.mServiceType = mResolveContext->mServiceType; - return MapOpenThreadError(otMdnsServerResolveService(thrInstancePtr, fullInstName, OtServiceCallback, context)); + return MapOpenThreadError(otMdnsStartSrvResolver(thrInstancePtr, &mResolveContext->mSrvInfo)); } else { return error; } } +void ChipDnssdResolveNoLongerNeeded(const char * instanceName) +{ + if (mResolveContext != nullptr) + { + if (strcmp(instanceName, mResolveContext->mMdnsService.mName) == 0) + { + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &mResolveContext->mSrvInfo); + + Platform::Delete(mResolveContext); + mResolveContext = nullptr; + } + } +} + +CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} -CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * context) +CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context) { const otSrpServerHost * host = nullptr; const otSrpServerService * service = nullptr; @@ -304,24 +487,26 @@ CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * c while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) { - service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE, serviceName, nullptr); - if (service != nullptr) + while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) { - mDnsQueryCtx * serviceContext; - - serviceContext = Platform::New(context, CHIP_NO_ERROR); - if (serviceContext != nullptr) + if ((false == otSrpServerServiceIsDeleted(service)) && + (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName)))) { - if (CHIP_NO_ERROR == - FromSrpCacheToMdnsData(service, host, nullptr, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry)) + mDnsQueryCtx * serviceContext = Platform::New(context->matterCtx, context->mDnsBrowseCallback); + if (serviceContext != nullptr) { - // Set error to CHIP_NO_ERROR to signal that there was at least one service found in the cache - error = CHIP_NO_ERROR; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(serviceContext)); - } - else - { - Platform::Delete(serviceContext); + if (CHIP_NO_ERROR == + FromSrpCacheToMdnsData(service, host, nullptr, serviceContext->mMdnsService, + serviceContext->mServiceTxtEntry)) + { + // Set error to CHIP_NO_ERROR to signal that there was at least one service found in the cache + error = CHIP_NO_ERROR; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(serviceContext)); + } + else + { + Platform::Delete(serviceContext); + } } } } @@ -329,7 +514,7 @@ CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * c return error; } -CHIP_ERROR ResolveBySrp(DnssdService * mdnsReq, otInstance * thrInstancePtr, char * instanceName, void * context) +CHIP_ERROR ResolveBySrp(otInstance * thrInstancePtr, char * serviceName, mDnsQueryCtx * context, DnssdService * mdnsReq) { const otSrpServerHost * host = nullptr; const otSrpServerService * service = nullptr; @@ -337,34 +522,27 @@ CHIP_ERROR ResolveBySrp(DnssdService * mdnsReq, otInstance * thrInstancePtr, cha while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) { - service = otSrpServerHostFindNextService( - host, service, (OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE), nullptr, instanceName); - if (service != nullptr) + while ((service = otSrpServerHostGetNextService(host, service)) != nullptr) { - error = CHIP_NO_ERROR; - mDnsQueryCtx * serviceContext; - - serviceContext = Platform::New(context, CHIP_NO_ERROR); - if (serviceContext != nullptr) + if ((false == otSrpServerServiceIsDeleted(service)) && + (0 == strncmp(otSrpServerServiceGetServiceName(service), serviceName, strlen(serviceName))) && + (0 == strncmp(otSrpServerServiceGetInstanceName(service), mdnsReq->mName, strlen(mdnsReq->mName)))) { - error = - FromSrpCacheToMdnsData(service, host, mdnsReq, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry); + error = FromSrpCacheToMdnsData(service, host, mdnsReq, context->mMdnsService, context->mServiceTxtEntry); if (error == CHIP_NO_ERROR) { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(serviceContext)); - } - else - { - Platform::Delete(serviceContext); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(context)); } + break; } - else - { - error = CHIP_ERROR_NO_MEMORY; - } + } + + if (error == CHIP_NO_ERROR) + { break; } } + return error; } @@ -480,35 +658,36 @@ CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSr return CHIP_NO_ERROR; } -CHIP_ERROR FromOtDnsResponseToMdnsData(otDnsServiceInfo & serviceInfo, const char * serviceType, - chip::Dnssd::DnssdService & mdnsService, DnsServiceTxtEntries & serviceTxtEntries, - otError error) +static CHIP_ERROR FromServiceTypeToMdnsData(chip::Dnssd::DnssdService & mdnsService, const char * aServiceType) { char protocol[chip::Dnssd::kDnssdProtocolTextMaxSize + 1]; + const char * protocolSubstringStart; + size_t substringSize; - if (strchr(serviceType, '.') == nullptr) - return CHIP_ERROR_INVALID_ARGUMENT; - - // Extract from the ... the part. - size_t substringSize = strchr(serviceType, '.') - serviceType; + // Extract from the . the part. + substringSize = strchr(aServiceType, '.') - aServiceType; if (substringSize >= ArraySize(mdnsService.mType)) { return CHIP_ERROR_INVALID_ARGUMENT; } - Platform::CopyString(mdnsService.mType, substringSize + 1, serviceType); + Platform::CopyString(mdnsService.mType, ArraySize(mdnsService.mType), aServiceType); - // Extract from the ... the part. - const char * protocolSubstringStart = serviceType + substringSize + 1; + // Extract from the .. the . part. + protocolSubstringStart = aServiceType + substringSize; + // Check that the protocolSubstringStart starts wit a '.' to be sure we are in the right place if (strchr(protocolSubstringStart, '.') == nullptr) + { return CHIP_ERROR_INVALID_ARGUMENT; + } - substringSize = strchr(protocolSubstringStart, '.') - protocolSubstringStart; + // Jump over '.' in protocolSubstringStart and substract the string terminator from the size + substringSize = strlen(++protocolSubstringStart) - 1; if (substringSize >= ArraySize(protocol)) { return CHIP_ERROR_INVALID_ARGUMENT; } - Platform::CopyString(protocol, substringSize + 1, protocolSubstringStart); + Platform::CopyString(protocol, ArraySize(protocol), protocolSubstringStart); if (strncmp(protocol, "_udp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) { @@ -523,274 +702,236 @@ CHIP_ERROR FromOtDnsResponseToMdnsData(otDnsServiceInfo & serviceInfo, const cha mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; } - // Check if SRV record was included in DNS response. - if (error != OT_ERROR_NOT_FOUND) - { - if (strchr(serviceInfo.mHostNameBuffer, '.') == nullptr) - return CHIP_ERROR_INVALID_ARGUMENT; + return CHIP_NO_ERROR; +} - // Extract from the .. the part. - substringSize = strchr(serviceInfo.mHostNameBuffer, '.') - serviceInfo.mHostNameBuffer; - if (substringSize >= ArraySize(mdnsService.mHostName)) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - Platform::CopyString(mdnsService.mHostName, substringSize + 1, serviceInfo.mHostNameBuffer); +static void OtBrowseCallback(otInstance * aInstance, const otMdnsBrowseResult * aResult) +{ + CHIP_ERROR error; - mdnsService.mPort = serviceInfo.mPort; - } + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); - // All mDNS replies come from the External Netif - mdnsService.mInterface = ConnectivityManagerImpl().GetExternalInterface(); + mDnsQueryCtx * tmpContext = Platform::New(mBrowseContext->matterCtx, mBrowseContext->mDnsBrowseCallback); + VerifyOrReturn(tmpContext != nullptr); - // Check if AAAA record was included in DNS response. - if (!otIp6IsAddressUnspecified(&serviceInfo.mHostAddress)) - { - mdnsService.mAddressType = Inet::IPAddressType::kIPv6; - mdnsService.mAddress = std::optional(ToIPAddress(serviceInfo.mHostAddress)); - } + Platform::CopyString(tmpContext->mMdnsService.mName, sizeof(tmpContext->mMdnsService.mName), aResult->mServiceInstance); + error = FromServiceTypeToMdnsData(tmpContext->mMdnsService, aResult->mServiceType); - // Check if TXT record was included in DNS response. - if (serviceInfo.mTxtDataSize != 0) + if (CHIP_NO_ERROR == error) { - otDnsTxtEntryIterator iterator; - otDnsInitTxtEntryIterator(&iterator, serviceInfo.mTxtData, serviceInfo.mTxtDataSize); - - otDnsTxtEntry txtEntry; - chip::FixedBufferAllocator alloc(serviceTxtEntries.mBuffer); - - uint8_t entryIndex = 0; - while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) - { - if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) - continue; - - serviceTxtEntries.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); - serviceTxtEntries.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); - serviceTxtEntries.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; - entryIndex++; - } - - ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); - - mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; - mdnsService.mTextEntrySize = entryIndex; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(tmpContext)); } else { - mdnsService.mTextEntrySize = 0; + Platform::Delete(tmpContext); } - - return CHIP_NO_ERROR; -} - -void ChipDnssdResolveNoLongerNeeded(const char * instanceName) {} - -CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface) -{ - return CHIP_ERROR_NOT_IMPLEMENTED; } -static void OtBrowseCallback(otError aError, const otDnsBrowseResponse * aResponse, void * aContext) +static void OtServiceCallback(otInstance * aInstance, const otMdnsSrvResult * aResult) { CHIP_ERROR error; - // type buffer size is kDnssdTypeAndProtocolMaxSize + . + kMaxDomainNameSize + . + termination character - char type[Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 3]; - // hostname buffer size is kHostNameMaxLength + . + kMaxDomainNameSize + . + termination character - char hostname[Dnssd::kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 3]; - // secure space for the raw TXT data in the worst-case scenario relevant for Matter: - // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data - uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize]; - mDnsQueryCtx * browseContext = reinterpret_cast(aContext); - otDnsServiceInfo serviceInfo; - uint16_t index = 0; + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); + + VerifyOrReturn(mResolveContext != nullptr); + + error = FromServiceTypeToMdnsData(mResolveContext->mMdnsService, aResult->mServiceType); + mResolveContext->error = error; + + if (CHIP_NO_ERROR == error) + { + Platform::CopyString(mResolveContext->mMdnsService.mName, sizeof(mResolveContext->mMdnsService.mName), + aResult->mServiceInstance); + Platform::CopyString(mResolveContext->mMdnsService.mHostName, sizeof(mResolveContext->mMdnsService.mHostName), + aResult->mHostName); - /// TODO: check this code, might be remvoed, or if not free browseContext - if (mDnsBrowseCallback == nullptr) + mResolveContext->mMdnsService.mPort = aResult->mPort; + mResolveContext->mMdnsService.mTtlSeconds = aResult->mTtl; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchTxtResolve, reinterpret_cast(mResolveContext)); + } + else { - ChipLogError(DeviceLayer, "Invalid dns browse callback"); - return; + HandleResolveCleanup(*mResolveContext, kResolveStepSrv); } +} - VerifyOrExit(aError == OT_ERROR_NONE, error = MapOpenThreadError(aError)); +static void OtTxtCallback(otInstance * aInstance, const otMdnsTxtResult * aResult) +{ + bool bSendDispatch = true; - error = MapOpenThreadError(otDnsBrowseResponseGetServiceName(aResponse, type, sizeof(type))); + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn(aResult->mTtl > 0); - VerifyOrExit(error == CHIP_NO_ERROR, ); + VerifyOrReturn(mResolveContext != nullptr); - char serviceName[Dnssd::Common::kInstanceNameMaxLength + 1]; - while (otDnsBrowseResponseGetServiceInstance(aResponse, index, serviceName, sizeof(serviceName)) == OT_ERROR_NONE) + // Check if TXT record was included in the response. + if (aResult->mTxtDataLength != 0) { - serviceInfo.mHostNameBuffer = hostname; - serviceInfo.mHostNameBufferSize = sizeof(hostname); - serviceInfo.mTxtData = txtBuffer; - serviceInfo.mTxtDataSize = sizeof(txtBuffer); - - otError err = otDnsBrowseResponseGetServiceInfo(aResponse, serviceName, &serviceInfo); - error = MapOpenThreadError(err); + otDnsTxtEntryIterator iterator; + otDnsInitTxtEntryIterator(&iterator, aResult->mTxtData, aResult->mTxtDataLength); - VerifyOrExit(err == OT_ERROR_NOT_FOUND || err == OT_ERROR_NONE, ); + otDnsTxtEntry txtEntry; + chip::FixedBufferAllocator alloc(mResolveContext->mServiceTxtEntry.mBuffer); - mDnsQueryCtx * tmpContext = Platform::New(browseContext->matterCtx, CHIP_NO_ERROR); + uint8_t entryIndex = 0; + while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) + { + if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) + continue; - VerifyOrExit(tmpContext != nullptr, error = CHIP_ERROR_NO_MEMORY); + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); + mResolveContext->mServiceTxtEntry.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; + entryIndex++; + } - error = FromOtDnsResponseToMdnsData(serviceInfo, type, tmpContext->mMdnsService, tmpContext->mServiceTxtEntry, err); - if (CHIP_NO_ERROR == error) + if (alloc.AnyAllocFailed()) { - // Invoke callback for every service one by one instead of for the whole - // list due to large memory size needed to allocate on stack. - static_assert(ArraySize(tmpContext->mMdnsService.mName) >= ArraySize(serviceName), - "The target buffer must be big enough"); - Platform::CopyString(tmpContext->mMdnsService.mName, serviceName); - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(tmpContext)); + bSendDispatch = false; } else { - Platform::Delete(tmpContext); + mResolveContext->mMdnsService.mTextEntries = mResolveContext->mServiceTxtEntry.mTxtEntries; + mResolveContext->mMdnsService.mTextEntrySize = entryIndex; } - index++; } - -exit: - // Invoke callback to notify about end-of-browse when OT_ERROR_RESPONSE_TIMEOUT is received, otherwise ignore errors - if (aError == OT_ERROR_RESPONSE_TIMEOUT) + else { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + mResolveContext->mMdnsService.mTextEntrySize = 0; } -} -static void OtServiceCallback(otError aError, const otDnsServiceResponse * aResponse, void * aContext) -{ - CHIP_ERROR error; - otError otErr; - otDnsServiceInfo serviceInfo; - mDnsQueryCtx * serviceContext; - bool bStopQuery = false; - - // If error is timeout we don't need to inform the Matter app and we can just exit - VerifyOrReturn(aError != OT_ERROR_RESPONSE_TIMEOUT, ); - - bStopQuery = true; - serviceContext = Platform::New(aContext, MapOpenThreadError(aError)); - VerifyOrExit(serviceContext != nullptr, error = CHIP_ERROR_NO_MEMORY); - - // type buffer size is kDnssdTypeAndProtocolMaxSize + . + kMaxDomainNameSize + . + termination character - char type[Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 3]; - // hostname buffer size is kHostNameMaxLength + . + kMaxDomainNameSize + . + termination character - char hostname[Dnssd::kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 3]; - // secure space for the raw TXT data in the worst-case scenario relevant for Matter: - // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data - uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize]; - if (mDnsResolveCallback == nullptr) + if (bSendDispatch) { - ChipLogError(DeviceLayer, "Invalid dns resolve callback"); - return; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchAddressResolve, reinterpret_cast(mResolveContext)); } - - VerifyOrExit(aError == OT_ERROR_NONE, error = MapOpenThreadError(aError)); - - error = MapOpenThreadError(otDnsServiceResponseGetServiceName(aResponse, serviceContext->mMdnsService.mName, - sizeof(serviceContext->mMdnsService.mName), type, sizeof(type))); - - VerifyOrExit(error == CHIP_NO_ERROR, ); - - serviceInfo.mHostNameBuffer = hostname; - serviceInfo.mHostNameBufferSize = sizeof(hostname); - serviceInfo.mTxtData = txtBuffer; - serviceInfo.mTxtDataSize = sizeof(txtBuffer); - - otErr = otDnsServiceResponseGetServiceInfo(aResponse, &serviceInfo); - error = MapOpenThreadError(otErr); - - VerifyOrExit(error == CHIP_NO_ERROR, ); - - error = FromOtDnsResponseToMdnsData(serviceInfo, type, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry, otErr); - -exit: - if (serviceContext == nullptr) + else { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveNoMemory, reinterpret_cast(aContext)); - return; + HandleResolveCleanup(*mResolveContext, kResolveStepTxt); } +} - serviceContext->error = error; +static void OtAddressCallback(otInstance * aInstance, const otMdnsAddressResult * aResult) +{ + // Ingnore reponses with TTL 0, the record is no longer valid and was removed from the mDNS cache + VerifyOrReturn((aResult->mAddressesLength > 0) && (aResult->mAddresses[0].mTtl > 0)); - // If IPv6 address in unspecified (AAAA record not present), send additional DNS query to obtain IPv6 address. - if (otIp6IsAddressUnspecified(&serviceInfo.mHostAddress)) - { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchAddressResolve, reinterpret_cast(serviceContext)); - } - else - { - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(serviceContext)); - } + VerifyOrReturn(mResolveContext != nullptr); - if (bStopQuery) - { - char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + - 1] = ""; - snprintf(fullInstName, sizeof(fullInstName), "%s.%s", serviceContext->mMdnsService.mName, type); + mResolveContext->mMdnsService.mAddressType = Inet::IPAddressType::kIPv6; + mResolveContext->mMdnsService.mAddress = std::optional(ToIPAddress(aResult->mAddresses[0].mAddress)); - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - otMdnsServerStopQuery(thrInstancePtr, fullInstName); - } + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(mResolveContext)); } -void DispatchBrowseEmpty(intptr_t context) +static void DispatchBrowseEmpty(intptr_t context) { auto * browseContext = reinterpret_cast(context); - mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error); + browseContext->mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error); Platform::Delete(browseContext); + mBrowseContext = nullptr; bBrowseInProgress = false; } -void DispatchBrowse(intptr_t context) +static void DispatchBrowse(intptr_t context) { auto * browseContext = reinterpret_cast(context); - mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error); + browseContext->mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error); Platform::Delete(browseContext); } -void DispatchBrowseNoMemory(intptr_t context) +static void DispatchTxtResolve(intptr_t context) { - mDnsBrowseCallback(reinterpret_cast(context), nullptr, 0, true, CHIP_ERROR_NO_MEMORY); + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + otError error; + + // Stop SRV resolver before starting TXT one, ignore error as it will only happen if mMDS module is not initialized + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mSrvInfo); + + resolveContext->mTxtInfo.mServiceInstance = resolveContext->mMdnsService.mName; + resolveContext->mTxtInfo.mServiceType = resolveContext->mServiceType; + resolveContext->mTxtInfo.mCallback = OtTxtCallback; + resolveContext->mTxtInfo.mInfraIfIndex = mNetifIndex; + + error = otMdnsStartTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); + if (error != OT_ERROR_NONE) + { + resolveContext->error = MapOpenThreadError(error); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); + } } -void DispatchAddressResolve(intptr_t context) +static void DispatchAddressResolve(intptr_t context) { - CHIP_ERROR error = CHIP_ERROR_NO_MEMORY; // ResolveAddress(context, OnDnsAddressResolveResult); + otError error; + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + // Stop TXT resolver before starting address one, ignore error as it will only happen if mMDS module is not initialized + otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mTxtInfo); - // In case of address resolve failure, fill the error code field and dispatch method to end resolve process. - if (error != CHIP_NO_ERROR) - { - mDnsQueryCtx * resolveContext = reinterpret_cast(context); - resolveContext->error = error; + resolveContext->mAddrInfo.mCallback = OtAddressCallback; + resolveContext->mAddrInfo.mHostName = resolveContext->mMdnsService.mHostName; + resolveContext->mAddrInfo.mInfraIfIndex = mNetifIndex; - DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(resolveContext)); + error = otMdnsStartIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); + if (error != OT_ERROR_NONE) + { + resolveContext->error = MapOpenThreadError(error); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveError, reinterpret_cast(resolveContext)); } } -void DispatchResolve(intptr_t context) +static void DispatchResolve(intptr_t context) { mDnsQueryCtx * resolveContext = reinterpret_cast(context); Dnssd::DnssdService & service = resolveContext->mMdnsService; Span ipAddrs; + // Stop Address resolver, we have finished resolving the service + otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext->mAddrInfo); + if (service.mAddress.has_value()) { ipAddrs = Span(&*service.mAddress, 1); } - mDnsResolveCallback(resolveContext->matterCtx, &service, ipAddrs, resolveContext->error); + // Signal that the context will be freed and that the resolve operation is stopped because Matter will + // try do stop it again on the mDnsResolveCallback + mResolveContext = nullptr; + + resolveContext->mDnsResolveCallback(resolveContext->matterCtx, &service, ipAddrs, resolveContext->error); Platform::Delete(resolveContext); } -void DispatchResolveNoMemory(intptr_t context) +static void DispatchResolveError(intptr_t context) { + mDnsQueryCtx * resolveContext = reinterpret_cast(context); Span ipAddrs; - mDnsResolveCallback(reinterpret_cast(context), nullptr, ipAddrs, CHIP_ERROR_NO_MEMORY); + + // Signal that the context will be freed and that the resolve operation is stopped because Matter will + // try do stop it again on the mDnsResolveCallback + mResolveContext = nullptr; + + resolveContext->mDnsResolveCallback(resolveContext->matterCtx, nullptr, ipAddrs, resolveContext->error); + Platform::Delete(resolveContext); +} + +void HandleResolveCleanup(mDnsQueryCtx & resolveContext, ResolveStep stepType) +{ + switch (stepType) + { + case kResolveStepSrv: + otMdnsStopSrvResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mSrvInfo); + break; + case kResolveStepTxt: + otMdnsStopTxtResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mTxtInfo); + break; + case kResolveStepIpAddr: + otMdnsStopIp6AddressResolver(ThreadStackMgrImpl().OTInstance(), &resolveContext.mAddrInfo); + break; + } + + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(&resolveContext)); } } // namespace Dnssd diff --git a/src/platform/nxp/common/NXPConfig.h b/src/platform/nxp/common/NXPConfig.h index 432acfa196abbb..03d6174763fb69 100644 --- a/src/platform/nxp/common/NXPConfig.h +++ b/src/platform/nxp/common/NXPConfig.h @@ -59,7 +59,7 @@ namespace Internal { constexpr inline uint16_t config_key(uint8_t chipId, uint8_t pdmId) { - return static_cast(chipId) << 8 | pdmId; + return (uint16_t) (static_cast(chipId) << 8 | pdmId); } /** diff --git a/src/platform/nxp/common/ram_storage.c b/src/platform/nxp/common/ram_storage.c index bfd1869710ebf6..b966b38816e2a7 100644 --- a/src/platform/nxp/common/ram_storage.c +++ b/src/platform/nxp/common/ram_storage.c @@ -319,13 +319,9 @@ int ramStorageSavetoFlash(const char * file_name, uint8_t * buffer, uint32_t buf void ramStorageDump(const ramBufferDescriptor * pBuffer) { - uint16_t i = 0; - uint16_t j = 0; - uint16_t valueLength = 0; - uint16_t readLength; - int currentIndex = 0; + uint16_t i = 0; + uint16_t j = 0; const struct settingsBlock * currentBlock; - rsError error = RS_ERROR_NOT_FOUND; (void) OSA_MutexLock((osa_mutex_handle_t) mRamStorageMutexId, osaWaitForever_c); diff --git a/src/platform/nxp/k32w1/BLEManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.cpp similarity index 98% rename from src/platform/nxp/k32w1/BLEManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.cpp index fe3ebd0c0b5027..1eefdf5ef16ffc 100644 --- a/src/platform/nxp/k32w1/BLEManagerImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.cpp @@ -28,7 +28,7 @@ messaging_t gHci2Host_TaskQueue; /*! Event for the Host Task Queue */ OSA_EVENT_HANDLE_DEFINE(gHost_TaskEvent); -#include +#include extern "C" bleResult_t Hci_Reset(void); diff --git a/src/platform/nxp/k32w1/BLEManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w1/BLEManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.h diff --git a/src/platform/nxp/k32w1/BUILD.gn b/src/platform/nxp/mcxw71_k32w1/BUILD.gn similarity index 96% rename from src/platform/nxp/k32w1/BUILD.gn rename to src/platform/nxp/mcxw71_k32w1/BUILD.gn index 89e9ad06e918f4..9e190474031296 100644 --- a/src/platform/nxp/k32w1/BUILD.gn +++ b/src/platform/nxp/mcxw71_k32w1/BUILD.gn @@ -24,7 +24,7 @@ import("${nxp_sdk_build_root}/nxp_sdk.gni") import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") assert(chip_device_platform == "nxp") -assert(nxp_platform == "k32w1") +assert(nxp_platform == "mcxw71_k32w1") assert(chip_with_low_power == 0 || (chip_with_low_power == 1 && chip_with_ot_cli == 0), @@ -43,7 +43,7 @@ source_set("nxp_factory_data") { "${chip_root}/src/credentials/CertificationDeclaration.h", ] - defines = [ "PLATFORM_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/k32w1/FactoryDataProviderImpl.h\"" ] + defines = [ "PLATFORM_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.h\"" ] deps = [ ":nxp_platform", @@ -151,8 +151,8 @@ static_library("nxp_platform") { "${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h", "${chip_root}/src/credentials/examples/ExampleDACs.h", "${chip_root}/src/credentials/examples/ExamplePAI.h", - "${chip_root}/src/platform/nxp/k32w1/BLEManagerImpl.h", - "${chip_root}/src/platform/nxp/k32w1/SMU2Manager.h", + "${chip_root}/src/platform/nxp/mcxw71_k32w1/BLEManagerImpl.h", + "${chip_root}/src/platform/nxp/mcxw71_k32w1/SMU2Manager.h", ] public_deps = [ "${chip_root}/src/platform:platform_base" ] diff --git a/src/platform/nxp/k32w1/BlePlatformConfig.h b/src/platform/nxp/mcxw71_k32w1/BlePlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w1/BlePlatformConfig.h rename to src/platform/nxp/mcxw71_k32w1/BlePlatformConfig.h diff --git a/src/platform/nxp/k32w1/CHIPCryptoPalK32W1.cpp b/src/platform/nxp/mcxw71_k32w1/CHIPCryptoPalK32W1.cpp similarity index 100% rename from src/platform/nxp/k32w1/CHIPCryptoPalK32W1.cpp rename to src/platform/nxp/mcxw71_k32w1/CHIPCryptoPalK32W1.cpp diff --git a/src/platform/nxp/k32w1/CHIPDevicePlatformConfig.h b/src/platform/nxp/mcxw71_k32w1/CHIPDevicePlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w1/CHIPDevicePlatformConfig.h rename to src/platform/nxp/mcxw71_k32w1/CHIPDevicePlatformConfig.h diff --git a/src/platform/nxp/k32w1/CHIPDevicePlatformEvent.h b/src/platform/nxp/mcxw71_k32w1/CHIPDevicePlatformEvent.h similarity index 100% rename from src/platform/nxp/k32w1/CHIPDevicePlatformEvent.h rename to src/platform/nxp/mcxw71_k32w1/CHIPDevicePlatformEvent.h diff --git a/src/platform/nxp/k32w1/CHIPPlatformConfig.h b/src/platform/nxp/mcxw71_k32w1/CHIPPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w1/CHIPPlatformConfig.h rename to src/platform/nxp/mcxw71_k32w1/CHIPPlatformConfig.h diff --git a/src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.cpp similarity index 99% rename from src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.cpp index fc6815d20fd157..34e7faa8e57531 100644 --- a/src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.cpp @@ -30,7 +30,7 @@ #include #include #if defined(USE_SMU2_DYNAMIC) -#include +#include #endif // #include diff --git a/src/platform/nxp/k32w1/ConfigurationManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.h similarity index 98% rename from src/platform/nxp/k32w1/ConfigurationManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.h index ba6dd2e721340b..c732ad6230b828 100644 --- a/src/platform/nxp/k32w1/ConfigurationManagerImpl.h +++ b/src/platform/nxp/mcxw71_k32w1/ConfigurationManagerImpl.h @@ -26,7 +26,7 @@ #pragma once #if (CHIP_PLAT_NVM_SUPPORT == 1) -#include +#include #else #include #endif diff --git a/src/platform/nxp/k32w1/ConnectivityManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/ConnectivityManagerImpl.cpp similarity index 100% rename from src/platform/nxp/k32w1/ConnectivityManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/ConnectivityManagerImpl.cpp diff --git a/src/platform/nxp/k32w1/ConnectivityManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/ConnectivityManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w1/ConnectivityManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/ConnectivityManagerImpl.h diff --git a/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/mcxw71_k32w1/DiagnosticDataProviderImpl.cpp similarity index 99% rename from src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/DiagnosticDataProviderImpl.cpp index 090feb53adde4a..9b60fabfca98bf 100644 --- a/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/DiagnosticDataProviderImpl.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include diff --git a/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.h b/src/platform/nxp/mcxw71_k32w1/DiagnosticDataProviderImpl.h similarity index 100% rename from src/platform/nxp/k32w1/DiagnosticDataProviderImpl.h rename to src/platform/nxp/mcxw71_k32w1/DiagnosticDataProviderImpl.h diff --git a/src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp b/src/platform/nxp/mcxw71_k32w1/FactoryDataDriverImpl.cpp similarity index 98% rename from src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/FactoryDataDriverImpl.cpp index ae50e2361b8257..473c4932ee1ba1 100644 --- a/src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/FactoryDataDriverImpl.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include using namespace chip::DeviceLayer::PersistedStorage; diff --git a/src/platform/nxp/k32w1/FactoryDataDriverImpl.h b/src/platform/nxp/mcxw71_k32w1/FactoryDataDriverImpl.h similarity index 100% rename from src/platform/nxp/k32w1/FactoryDataDriverImpl.h rename to src/platform/nxp/mcxw71_k32w1/FactoryDataDriverImpl.h diff --git a/src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp b/src/platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.cpp similarity index 99% rename from src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.cpp index f3af97803b13d0..c55940e8838395 100644 --- a/src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ #include -#include +#include #include #include "fsl_adapter_flash.h" diff --git a/src/platform/nxp/k32w1/FactoryDataProviderImpl.h b/src/platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.h similarity index 100% rename from src/platform/nxp/k32w1/FactoryDataProviderImpl.h rename to src/platform/nxp/mcxw71_k32w1/FactoryDataProviderImpl.h diff --git a/src/platform/nxp/k32w1/InetPlatformConfig.h b/src/platform/nxp/mcxw71_k32w1/InetPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w1/InetPlatformConfig.h rename to src/platform/nxp/mcxw71_k32w1/InetPlatformConfig.h diff --git a/src/platform/nxp/k32w1/K32W1Config.cpp b/src/platform/nxp/mcxw71_k32w1/K32W1Config.cpp similarity index 99% rename from src/platform/nxp/k32w1/K32W1Config.cpp rename to src/platform/nxp/mcxw71_k32w1/K32W1Config.cpp index 6f578f8ed01624..c4ac984244d6bd 100644 --- a/src/platform/nxp/k32w1/K32W1Config.cpp +++ b/src/platform/nxp/mcxw71_k32w1/K32W1Config.cpp @@ -25,7 +25,7 @@ /* this file behaves like a config.h, comes first */ #include -#include +#include #include #include diff --git a/src/platform/nxp/k32w1/K32W1Config.h b/src/platform/nxp/mcxw71_k32w1/K32W1Config.h similarity index 100% rename from src/platform/nxp/k32w1/K32W1Config.h rename to src/platform/nxp/mcxw71_k32w1/K32W1Config.h diff --git a/src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.cpp b/src/platform/nxp/mcxw71_k32w1/K32W1PersistentStorageOpKeystore.cpp similarity index 100% rename from src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.cpp rename to src/platform/nxp/mcxw71_k32w1/K32W1PersistentStorageOpKeystore.cpp diff --git a/src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.h b/src/platform/nxp/mcxw71_k32w1/K32W1PersistentStorageOpKeystore.h similarity index 100% rename from src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.h rename to src/platform/nxp/mcxw71_k32w1/K32W1PersistentStorageOpKeystore.h diff --git a/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/KeyValueStoreManagerImpl.cpp similarity index 99% rename from src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/KeyValueStoreManagerImpl.cpp index f70c6abb6c9e83..5b1d89de4e263e 100644 --- a/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/KeyValueStoreManagerImpl.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/KeyValueStoreManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w1/KeyValueStoreManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/KeyValueStoreManagerImpl.h diff --git a/src/platform/nxp/k32w1/Logging.cpp b/src/platform/nxp/mcxw71_k32w1/Logging.cpp similarity index 100% rename from src/platform/nxp/k32w1/Logging.cpp rename to src/platform/nxp/mcxw71_k32w1/Logging.cpp diff --git a/src/platform/nxp/k32w1/LowPowerHooks.cpp b/src/platform/nxp/mcxw71_k32w1/LowPowerHooks.cpp similarity index 100% rename from src/platform/nxp/k32w1/LowPowerHooks.cpp rename to src/platform/nxp/mcxw71_k32w1/LowPowerHooks.cpp diff --git a/src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp b/src/platform/nxp/mcxw71_k32w1/OTAFirmwareProcessor.cpp similarity index 98% rename from src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp rename to src/platform/nxp/mcxw71_k32w1/OTAFirmwareProcessor.cpp index 33eed513ba033c..2ea4d47cc655a1 100644 --- a/src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp +++ b/src/platform/nxp/mcxw71_k32w1/OTAFirmwareProcessor.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include "OtaSupport.h" diff --git a/src/platform/nxp/k32w1/OTAFirmwareProcessor.h b/src/platform/nxp/mcxw71_k32w1/OTAFirmwareProcessor.h similarity index 100% rename from src/platform/nxp/k32w1/OTAFirmwareProcessor.h rename to src/platform/nxp/mcxw71_k32w1/OTAFirmwareProcessor.h diff --git a/src/platform/nxp/k32w1/OTAHooks.cpp b/src/platform/nxp/mcxw71_k32w1/OTAHooks.cpp similarity index 97% rename from src/platform/nxp/k32w1/OTAHooks.cpp rename to src/platform/nxp/mcxw71_k32w1/OTAHooks.cpp index 3bbabaa274fba4..c476e705fd67be 100644 --- a/src/platform/nxp/k32w1/OTAHooks.cpp +++ b/src/platform/nxp/mcxw71_k32w1/OTAHooks.cpp @@ -21,10 +21,10 @@ #include -#include +#include #if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #include -#include +#include #endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #include "OtaSupport.h" diff --git a/src/platform/nxp/k32w1/PlatformManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/PlatformManagerImpl.cpp similarity index 96% rename from src/platform/nxp/k32w1/PlatformManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/PlatformManagerImpl.cpp index 964884e77523c6..9a52321e48fce8 100644 --- a/src/platform/nxp/k32w1/PlatformManagerImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/PlatformManagerImpl.cpp @@ -33,10 +33,10 @@ #ifdef EXTERNAL_CONFIGURATIONMANAGERIMPL_HEADER #include EXTERNAL_CONFIGURATIONMANAGERIMPL_HEADER #else -#include +#include #endif -#include -#include +#include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include diff --git a/src/platform/nxp/k32w1/PlatformManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/PlatformManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w1/PlatformManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/PlatformManagerImpl.h diff --git a/src/platform/nxp/k32w1/SMU2Manager.cpp b/src/platform/nxp/mcxw71_k32w1/SMU2Manager.cpp similarity index 100% rename from src/platform/nxp/k32w1/SMU2Manager.cpp rename to src/platform/nxp/mcxw71_k32w1/SMU2Manager.cpp diff --git a/src/platform/nxp/k32w1/SMU2Manager.h b/src/platform/nxp/mcxw71_k32w1/SMU2Manager.h similarity index 100% rename from src/platform/nxp/k32w1/SMU2Manager.h rename to src/platform/nxp/mcxw71_k32w1/SMU2Manager.h diff --git a/src/platform/nxp/k32w1/SystemPlatformConfig.h b/src/platform/nxp/mcxw71_k32w1/SystemPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w1/SystemPlatformConfig.h rename to src/platform/nxp/mcxw71_k32w1/SystemPlatformConfig.h diff --git a/src/platform/nxp/k32w1/SystemTimeSupport.cpp b/src/platform/nxp/mcxw71_k32w1/SystemTimeSupport.cpp similarity index 100% rename from src/platform/nxp/k32w1/SystemTimeSupport.cpp rename to src/platform/nxp/mcxw71_k32w1/SystemTimeSupport.cpp diff --git a/src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp b/src/platform/nxp/mcxw71_k32w1/ThreadStackManagerImpl.cpp similarity index 98% rename from src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp rename to src/platform/nxp/mcxw71_k32w1/ThreadStackManagerImpl.cpp index c7b16ffd3e5c6a..b85052bf993920 100644 --- a/src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/mcxw71_k32w1/ThreadStackManagerImpl.cpp @@ -35,7 +35,7 @@ #include #if defined(USE_SMU2_DYNAMIC) -#include +#include #endif #include diff --git a/src/platform/nxp/k32w1/ThreadStackManagerImpl.h b/src/platform/nxp/mcxw71_k32w1/ThreadStackManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w1/ThreadStackManagerImpl.h rename to src/platform/nxp/mcxw71_k32w1/ThreadStackManagerImpl.h diff --git a/src/platform/nxp/k32w1/args.gni b/src/platform/nxp/mcxw71_k32w1/args.gni similarity index 89% rename from src/platform/nxp/k32w1/args.gni rename to src/platform/nxp/mcxw71_k32w1/args.gni index 1c984c386ea086..68e1cdeeec672e 100644 --- a/src/platform/nxp/k32w1/args.gni +++ b/src/platform/nxp/mcxw71_k32w1/args.gni @@ -19,26 +19,18 @@ import("//build_overrides/openthread.gni") declare_args() { chip_with_ot_cli = 0 chip_with_low_power = 0 - sdk_release = false - k32w1_sdk_root = "" # The key storage solution. Developers can select between "littlefs", "nvs" # and the older "fwk_nvm". chip_key_storage = "nvs" chip_use_plain_dac_key = false - - k32w1_sdk_root = "${nxp_sdk_matter_support_root}/github_sdk/common_sdk/repo" -} - -if (sdk_release || getenv("NXP_SDK_ROOT") != "") { - k32w1_sdk_root = getenv("NXP_SDK_ROOT") } openthread_root = "//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread" -nxp_platform = "k32w1" -nxp_sdk_name = "k32w1_sdk" +nxp_platform = "mcxw71_k32w1" +nxp_sdk_name = "mcxw71_k32w1_sdk" nxp_device_layer = "nxp/${nxp_platform}" nxp_use_lwip = false diff --git a/src/platform/nxp/k32w1/ble_function_mux.c b/src/platform/nxp/mcxw71_k32w1/ble_function_mux.c similarity index 100% rename from src/platform/nxp/k32w1/ble_function_mux.c rename to src/platform/nxp/mcxw71_k32w1/ble_function_mux.c diff --git a/src/platform/nxp/k32w1/ble_function_mux.h b/src/platform/nxp/mcxw71_k32w1/ble_function_mux.h similarity index 100% rename from src/platform/nxp/k32w1/ble_function_mux.h rename to src/platform/nxp/mcxw71_k32w1/ble_function_mux.h diff --git a/src/platform/nxp/k32w1/gatt_db.h b/src/platform/nxp/mcxw71_k32w1/gatt_db.h similarity index 100% rename from src/platform/nxp/k32w1/gatt_db.h rename to src/platform/nxp/mcxw71_k32w1/gatt_db.h diff --git a/src/platform/nxp/k32w1/gatt_uuid128.h b/src/platform/nxp/mcxw71_k32w1/gatt_uuid128.h similarity index 100% rename from src/platform/nxp/k32w1/gatt_uuid128.h rename to src/platform/nxp/mcxw71_k32w1/gatt_uuid128.h diff --git a/src/platform/nxp/k32w1/k32w1-chip-mbedtls-config.h b/src/platform/nxp/mcxw71_k32w1/k32w1-chip-mbedtls-config.h similarity index 100% rename from src/platform/nxp/k32w1/k32w1-chip-mbedtls-config.h rename to src/platform/nxp/mcxw71_k32w1/k32w1-chip-mbedtls-config.h diff --git a/src/platform/nxp/k32w1/ram_storage.c b/src/platform/nxp/mcxw71_k32w1/ram_storage.c similarity index 100% rename from src/platform/nxp/k32w1/ram_storage.c rename to src/platform/nxp/mcxw71_k32w1/ram_storage.c diff --git a/src/platform/nxp/k32w1/ram_storage.h b/src/platform/nxp/mcxw71_k32w1/ram_storage.h similarity index 100% rename from src/platform/nxp/k32w1/ram_storage.h rename to src/platform/nxp/mcxw71_k32w1/ram_storage.h diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 1793b50884dd30..447ef2905bb300 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -13,11 +13,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") import("${chip_root}/src/platform/device.gni") -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") + +# If external SDK is used, do not import ${nxp_sdk_name}.gni +if (!nxp_external_sdk) { + import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +} + import("${nxp_sdk_build_root}/nxp_sdk.gni") assert(chip_device_platform == "nxp") @@ -43,8 +49,16 @@ config("nxp_platform_config") { "CONFIG_CHIP_ENCRYPTED_FACTORY_DATA=1", ] - if (chip_enable_secure_dac_private_key_storage == 1) { + if (chip_enable_secure_dac_private_key_storage) { + assert(chip_enable_secure_dac_private_key_storage && + !chip_enable_secure_whole_factory_data, + "please select only one protection solution") defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderImpl.h\"" ] + } else if (chip_enable_secure_whole_factory_data) { + assert(chip_enable_secure_whole_factory_data && + !chip_enable_secure_dac_private_key_storage, + "please select only one protection solution") + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h\"" ] } else { defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] } @@ -56,6 +70,11 @@ config("nxp_platform_config") { } static_library("nxp_platform") { + output_name = "libCHIP_NXP_Port_RW61x" + cflags = [ + "-Wno-conversion", + "-Wno-sign-compare", + ] deps = [] defines = [] sources = [ @@ -78,20 +97,22 @@ static_library("nxp_platform") { "PlatformManagerImpl.cpp", ] - if (rt_nvm_component == "nvm_fwk" || rt_nvm_component == "littlefs") { + if (nxp_nvm_component == "nvm_fwk" || nxp_nvm_component == "littlefs") { sources += [ "../../common/NXPConfig.cpp", "../../common/ram_storage.c", "../../common/ram_storage.h", ] - } else if (rt_nvm_component == "key_storage") { + } else if (nxp_nvm_component == "key_storage") { sources += [ "../../common/NXPConfigKS.cpp" ] + } else if (nxp_nvm_component == "nvs") { + sources += [ "../../common/NXPConfigNVS.cpp" ] } if (chip_enable_ble) { sources += [ # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr - "${nxp_sdk_build_root}/${nxp_sdk_name}/sdk_hook/zephyr/random/random.cpp", + "${nxp_sdk_build_root}/rt_sdk/sdk_hook/zephyr/random/random.cpp", "../../common/ble_zephyr/BLEAdvertisingArbiter.cpp", "../../common/ble_zephyr/BLEManagerImpl.cpp", "../../common/ble_zephyr/BLEManagerImpl.h", @@ -100,14 +121,17 @@ static_library("nxp_platform") { public_deps = [ "${chip_root}/src/platform:platform_base" ] - deps += [ "${chip_root}/src/platform/logging:headers" ] + deps += [ + "${chip_root}/src/lib/dnssd:constants", + "${chip_root}/src/platform/logging:headers", + ] # define CHIP_PLAT_NVM_SUPPORT - See NXPConfig.cpp for definition - if (rt_nvm_component == "nvm_fwk") { + if (nxp_nvm_component == "nvm_fwk") { defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] - } else if (rt_nvm_component == "littlefs") { + } else if (nxp_nvm_component == "littlefs") { defines += [ "CHIP_PLAT_NVM_SUPPORT=2" ] - } else if (rt_nvm_component == "key_storage") { + } else if (nxp_nvm_component == "key_storage") { defines += [ "CHIP_PLAT_NVM_SUPPORT=3" ] } @@ -157,14 +181,16 @@ static_library("nxp_platform") { "../../common/factory_data/FactoryDataProvider.cpp", "../../common/factory_data/FactoryDataProvider.h", ] - if (chip_enable_secure_dac_private_key_storage == 1) { + if (chip_enable_secure_dac_private_key_storage) { sources += [ - # TO BE MOVED TO THE SDK - "ELSFactoryData.c", - "ELSFactoryData.h", "FactoryDataProviderImpl.cpp", "FactoryDataProviderImpl.h", ] + } else if (chip_enable_secure_whole_factory_data) { + sources += [ + "FactoryDataProviderEncImpl.cpp", + "FactoryDataProviderEncImpl.h", + ] } else { sources += [ "../../common/factory_data/FactoryDataProviderFwkImpl.cpp", @@ -175,10 +201,6 @@ static_library("nxp_platform") { deps += [ "${chip_root}/src/credentials:credentials_header" ] } - if (chip_convert_dac_private_key == 1) { - defines += [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ] - } - deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] public_deps += [ diff --git a/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h b/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h index caa7e32a9e3000..45b080fe52e9b3 100644 --- a/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h +++ b/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h @@ -35,7 +35,7 @@ /* In src/crypto/CHIPCryptoPALmbedTLS.cpp we verify kMAX_Hash_SHA256_Context_Size >= sizeof(mbedtls_sha256_context) * sizeof(mbedtls_sha256_context) is 392 bytes with els_pkc mbedtls port */ -#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 98) +#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 120) // ==================== Security Adaptations ==================== diff --git a/src/platform/nxp/rt/rw61x/ELSFactoryData.c b/src/platform/nxp/rt/rw61x/ELSFactoryData.c deleted file mode 100644 index a440c42569ffbd..00000000000000 --- a/src/platform/nxp/rt/rw61x/ELSFactoryData.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright 2023 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "ELSFactoryData.h" - -uint8_t * append_u32(uint8_t * pos, uint32_t val) -{ - *pos++ = 4; - *pos++ = (val >> 24) & 0xFF; - *pos++ = (val >> 16) & 0xFF; - *pos++ = (val >> 8) & 0xFF; - *pos++ = val & 0xFF; - return pos; -} - -uint8_t * append_u16(uint8_t * pos, uint32_t val) -{ - *pos++ = 2; - *pos++ = (val >> 8) & 0xFF; - *pos++ = val & 0xFF; - return pos; -} - -void write_uint32_msb_first(uint8_t * pos, uint32_t data) -{ - pos[0] = ((data) >> 24) & 0xFF; - pos[1] = ((data) >> 16) & 0xFF; - pos[2] = ((data) >> 8) & 0xFF; - pos[3] = ((data) >> 0) & 0xFF; -} - -void printf_buffer(const char * name, const unsigned char * buffer, size_t size) -{ -#define PP_BYTES_PER_LINE (32) - char line_buffer[PP_BYTES_PER_LINE * 2 + 2]; - const unsigned char * pos = buffer; - size_t remaining = size; - while (remaining > 0) - { - size_t block_size = remaining > PP_BYTES_PER_LINE ? PP_BYTES_PER_LINE : remaining; - uint32_t len = 0; - for (size_t i = 0; i < block_size; i++) - { - line_buffer[len++] = nibble_to_char[((*pos) & 0xf0) >> 4]; - line_buffer[len++] = nibble_to_char[(*pos++) & 0x0f]; - } - line_buffer[len++] = '\n'; - line_buffer[len++] = '\0'; - PRINTF("%s (%p): %s", name, pos, line_buffer); - remaining -= block_size; - } -} - -uint32_t get_required_keyslots(mcuxClEls_KeyProp_t prop) -{ - return prop.bits.ksize == MCUXCLELS_KEYPROPERTY_KEY_SIZE_128 ? 1U : 2U; -} - -bool els_is_active_keyslot(mcuxClEls_KeyIndex_t keyIdx) -{ - mcuxClEls_KeyProp_t key_properties; - key_properties.word.value = ((const volatile uint32_t *) (&ELS->ELS_KS0))[keyIdx]; - return key_properties.bits.kactv; -} - -status_t els_enable() -{ - PLOG_INFO("Enabling ELS..."); - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Enable_Async()); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Enable_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_Enable_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -status_t els_get_key_properties(mcuxClEls_KeyIndex_t key_index, mcuxClEls_KeyProp_t * key_properties) -{ - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_GetKeyProperties(key_index, key_properties)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_GetKeyProperties) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_GetKeyProperties failed: 0x%08lx", result); - return STATUS_ERROR_GENERIC; - } - - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -mcuxClEls_KeyIndex_t els_get_free_keyslot(uint32_t required_keyslots) -{ - for (mcuxClEls_KeyIndex_t keyIdx = 0U; keyIdx <= (MCUXCLELS_KEY_SLOTS - required_keyslots); keyIdx++) - { - bool is_valid_keyslot = true; - for (uint32_t i = 0U; i < required_keyslots; i++) - { - if (els_is_active_keyslot(keyIdx + i)) - { - is_valid_keyslot = false; - break; - } - } - - if (is_valid_keyslot) - { - return keyIdx; - } - } - return MCUXCLELS_KEY_SLOTS; -} - -status_t els_derive_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyProp_t key_prop, const uint8_t * dd, - mcuxClEls_KeyIndex_t * dst_key_index) -{ - uint32_t required_keyslots = get_required_keyslots(key_prop); - - *dst_key_index = els_get_free_keyslot(required_keyslots); - - if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) - { - PLOG_ERROR("no free keyslot found"); - return STATUS_ERROR_GENERIC; - } - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Ckdf_Sp800108_Async(src_key_index, *dst_key_index, key_prop, dd)); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Ckdf_Sp800108_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_Ckdf_Sp800108_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -status_t els_delete_key(mcuxClEls_KeyIndex_t key_index) -{ - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_KeyDelete_Async(key_index)); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyDelete_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_KeyDelete_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -status_t els_import_key(const uint8_t * wrapped_key, size_t wrapped_key_size, mcuxClEls_KeyProp_t key_prop, - mcuxClEls_KeyIndex_t unwrap_key_index, mcuxClEls_KeyIndex_t * dst_key_index) -{ - uint32_t required_keyslots = get_required_keyslots(key_prop); - *dst_key_index = els_get_free_keyslot(required_keyslots); - - if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) - { - PLOG_ERROR("no free keyslot found"); - return STATUS_ERROR_GENERIC; - } - - mcuxClEls_KeyImportOption_t options; - options.bits.kfmt = MCUXCLELS_KEYIMPORT_KFMT_RFC3394; - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( - result, token, mcuxClEls_KeyImport_Async(options, wrapped_key, wrapped_key_size, unwrap_key_index, *dst_key_index)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyImport_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_KeyImport_Async failed: 0x%08lx", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08lx", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -status_t els_keygen(mcuxClEls_KeyIndex_t key_index, uint8_t * public_key, size_t * public_key_size) -{ - status_t status = STATUS_SUCCESS; - - mcuxClEls_EccKeyGenOption_t key_gen_options; - key_gen_options.word.value = 0u; - key_gen_options.bits.kgsign = MCUXCLELS_ECC_PUBLICKEY_SIGN_DISABLE; - key_gen_options.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_DETERMINISTIC; - key_gen_options.bits.skip_pbk = MCUXCLELS_ECC_GEN_PUBLIC_KEY; - - mcuxClEls_KeyProp_t key_properties; - status = els_get_key_properties(key_index, &key_properties); - STATUS_SUCCESS_OR_EXIT_MSG("get_key_properties failed: 0x%08x", status); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( - result, token, - mcuxClEls_EccKeyGen_Async(key_gen_options, (mcuxClEls_KeyIndex_t) 0, key_index, key_properties, NULL, &public_key[0])); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyGen_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PRINTF("Css_EccKeyGen_Async failed: 0x%08lx\r\n", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PRINTF("Css_EccKeyGen_Async WaitForOperation failed: 0x%08lx\r\n", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); -exit: - return status; -} - -status_t calculate_psa_import_blob_cmac(uint8_t * psa_import_blob, size_t psa_import_blob_length_before_mac, - size_t psa_import_blob_size) -{ - status_t status = STATUS_SUCCESS; - mcuxClEls_KeyIndex_t mac_key_index = MCUXCLELS_KEY_SLOTS; - - assert(psa_import_blob_size >= psa_import_blob_length_before_mac + AES_BLOCK_SIZE); - - uint8_t * pos = &psa_import_blob[psa_import_blob_length_before_mac]; - uint8_t mac[AES_BLOCK_SIZE] = { 0 }; - uint32_t missing_bytes_to_fill_block = AES_BLOCK_SIZE - (psa_import_blob_length_before_mac % AES_BLOCK_SIZE); - - mcuxClEls_CmacOption_t cmac_options = { 0U }; - cmac_options.bits.initialize = MCUXCLELS_CMAC_INITIALIZE_ENABLE; - cmac_options.bits.finalize = MCUXCLELS_CMAC_FINALIZE_ENABLE; - cmac_options.bits.extkey = MCUXCLELS_CMAC_EXTERNAL_KEY_DISABLE; - // ELS needs us to pad the message, it does not do that itself :-( - if (missing_bytes_to_fill_block != 0) - { - memset(pos, 0, missing_bytes_to_fill_block); - *pos = 0x80; - } - - PLOG_INFO("Deriving cmac key for integrity protection on key blob..."); - status = els_derive_key(DIE_INT_MK_SK_INDEX, mac_key_prop, ckdf_derivation_data_mac, &mac_key_index); - STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( - result, token, - mcuxClEls_Cmac_Async(cmac_options, mac_key_index, NULL, 0, psa_import_blob, psa_import_blob_length_before_mac, mac)); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Cmac_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_Cmac_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x\n", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - status = els_delete_key(mac_key_index); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - - memcpy(pos, mac, sizeof(mac)); -exit: - return status; -} - -status_t create_psa_import_blob(const uint8_t * els_key_blob, size_t els_key_blob_size, const psa_key_attributes_t * attributes, - uint8_t * output, size_t * output_size) -{ - assert(els_key_blob_size <= 48); - assert(sizeof(key_blob_magic) < 0x80); - - status_t status = STATUS_SUCCESS; - // clang-format off - size_t required_output_size = 0 - + 2 + sizeof(key_blob_magic) - + 2 + 4 // key_id - + 2 + 4 // algorithms - + 2 + 4 // usage - + 2 + 2 // type - + 2 + 4 // bits - + 2 + 4 // lifetime - + 2 + 4 // device lifecycle - + 2 + 4 // wrapping key id - + 2 + 4 // wrapping algorithm - + 2 + 4 // signing key id - + 2 + 4 // signing algorithm - + 2 + els_key_blob_size // key blob from S50 - + 2 + AES_BLOCK_SIZE; // CMAC - // clang-format on - - if (*output_size < required_output_size) - { - PLOG_ERROR("key blob buffer too small"); - return STATUS_ERROR_GENERIC; - } - *output_size = required_output_size; - - uint32_t key_id = psa_get_key_id(attributes); - uint32_t key_alg = psa_get_key_algorithm(attributes); - uint32_t key_usage = psa_get_key_usage_flags(attributes); - uint16_t key_type = psa_get_key_type(attributes); - uint32_t key_bits = psa_get_key_bits(attributes); - uint32_t key_lifetime = psa_get_key_lifetime(attributes); - uint32_t device_lifecycle = 0x1; // 0x01: OPEN, 0x02: CLOSED, 0x04: CLOSED_LOCKED - uint32_t wrapping_key_id = NXP_DIE_INT_IMPORT_KEK_SK; - uint32_t signing_key_id = NXP_DIE_INT_IMPORT_AUTH_SK; - - PLOG_INFO("Creating key blob..."); - uint8_t * pos = output; - - *pos++ = 0x40; - *pos++ = sizeof(key_blob_magic); - memcpy(pos, key_blob_magic, sizeof(key_blob_magic)); - pos += sizeof(key_blob_magic); - - *pos++ = 0x41; - pos = append_u32(pos, key_id); - - *pos++ = 0x42; - pos = append_u32(pos, key_alg); - - *pos++ = 0x43; - pos = append_u32(pos, key_usage); - - *pos++ = 0x44; - pos = append_u16(pos, key_type); - - *pos++ = 0x45; - pos = append_u32(pos, key_bits); - - *pos++ = 0x46; - pos = append_u32(pos, key_lifetime); - - *pos++ = 0x47; - pos = append_u32(pos, device_lifecycle); - - *pos++ = 0x50; - pos = append_u32(pos, wrapping_key_id); - - *pos++ = 0x51; - pos = append_u32(pos, 0x01); // ELS RFC3394 wrapping - - *pos++ = 0x53; - pos = append_u32(pos, signing_key_id); - - *pos++ = 0x54; - pos = append_u32(pos, 0x01); // CMAC - - *pos++ = 0x55; - *pos++ = els_key_blob_size; - memcpy(pos, els_key_blob, els_key_blob_size); - pos += els_key_blob_size; - - // signature - *pos++ = 0x5E; - *pos++ = AES_BLOCK_SIZE; - size_t psa_import_blob_length_before_mac = pos - output; - - status = calculate_psa_import_blob_cmac(output, psa_import_blob_length_before_mac, *output_size); - return status; -} - -status_t import_die_int_wrapped_key_into_els(const uint8_t * wrapped_key, size_t wrapped_key_size, - mcuxClEls_KeyProp_t key_properties, mcuxClEls_KeyIndex_t * index_output) -{ - status_t status = STATUS_SUCCESS; - mcuxClEls_KeyIndex_t index_unwrap = MCUXCLELS_KEY_SLOTS; - - PLOG_INFO("Deriving wrapping key for import of die_int wrapped key on ELS..."); - status = els_derive_key(DIE_INT_MK_SK_INDEX, wrap_out_key_prop, ckdf_derivation_data_wrap_out, &index_unwrap); - STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); - - status = els_import_key(wrapped_key, wrapped_key_size, key_properties, index_unwrap, index_output); - STATUS_SUCCESS_OR_EXIT_MSG("import_wrapped_key failed: 0x%08x", status); - - status = els_delete_key(index_unwrap); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - index_unwrap = MCUXCLELS_KEY_SLOTS; - -exit: - if (index_unwrap < MCUXCLELS_KEY_SLOTS) - { - (void) els_delete_key(index_unwrap); - } - return status; -} - -status_t ELS_sign_hash(uint8_t * digest, mcuxClEls_EccByte_t * ecc_signature, mcuxClEls_EccSignOption_t * sign_options, - mcuxClEls_KeyIndex_t key_index) -{ - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, - mcuxClEls_EccSign_Async( // Perform signature generation. - *sign_options, // Set the prepared configuration. - key_index, // Set index of private key in keystore. - digest, NULL, (size_t) 0U, // Pre-hashed data to sign. Note that inputLength parameter is - // ignored since pre-hashed data has a fixed length. - ecc_signature // Output buffer, which the operation will write the signature to. - )); - PLOG_DEBUG_BUFFER("mcuxClEls_EccSign_Async ecc_signature", ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccSign_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_EccSign_Async failed. token: 0x%08x, result: 0x%08x", token, result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed. token: 0x%08x, result: 0x%08x", token, result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} diff --git a/src/platform/nxp/rt/rw61x/ELSFactoryData.h b/src/platform/nxp/rt/rw61x/ELSFactoryData.h deleted file mode 100644 index 0ac259a66a4158..00000000000000 --- a/src/platform/nxp/rt/rw61x/ELSFactoryData.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2023 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __ELS_FACTORY_DATA_H__ -#define __ELS_FACTORY_DATA_H__ - -#include -#include - -#include "fsl_common.h" -#include "mbedtls/bignum.h" -#include "mbedtls/ecp.h" -#include "mcuxClAes.h" -#include "mcuxClEls_Cipher.h" -#include "mcuxClEls_Cmac.h" -#include "mcuxClEls_Ecc.h" -#include "mcuxClEls_Hash.h" -#include "mcuxClEls_Kdf.h" -#include "mcuxClEls_KeyManagement.h" -#include "mcuxClEls_Rng.h" -#include "mcuxClEls_Types.h" -#include "mcuxClHash_Constants.h" - -#include "psa/crypto.h" -#include "psa/crypto_values.h" - -#include "mbedtls/ecdh.h" -#include "mbedtls/entropy.h" -#include "mbedtls/nist_kw.h" - -#define BLOCK_SIZE_16_BYTES 16 -#define SHA256_OUTPUT_SIZE 32 -#define HASH_ID 0xCE47BA5E -#define HASH_LEN 4 -#define CBC_INITIAL_VECTOR_SIZE 16 - -#define STATUS_SUCCESS 0 -#define STATUS_ERROR_GENERIC 1 - -#define AES_BLOCK_SIZE 16U -#define DIE_INT_MK_SK_INDEX 0U - -#define ELS_BLOB_METADATA_SIZE 8 -#define MAX_ELS_KEY_SIZE 32 -#define ELS_WRAP_OVERHEAD 8 - -#if FACTORY_DATA_PROVIDER_LOG -#define PLOG_ERROR(...) \ - for (;;) \ - { \ - PRINTF("ERROR "); \ - PRINTF(__VA_ARGS__); \ - PRINTF(" (%s:%d)\n", __FILE__, __LINE__); \ - break; \ - } -#else -#define PLOG_ERROR(...) -#endif - -#if FACTORY_DATA_PROVIDER_LOG -#define PLOG_INFO(...) \ - for (;;) \ - { \ - PRINTF("INFO "); \ - PRINTF(__VA_ARGS__); \ - PRINTF("\n"); \ - break; \ - } -#else -#define PLOG_INFO(...) -#endif - -#if FACTORY_DATA_PROVIDER_LOG -#define PLOG_DEBUG(...) \ - for (;;) \ - { \ - PRINTF("DEBUG "); \ - PRINTF(__VA_ARGS__); \ - PRINTF("\n"); \ - break; \ - } -#else -#define PLOG_DEBUG(...) -#endif - -#if FACTORY_DATA_PROVIDER_LOG -#define PLOG_DEBUG_BUFFER(...) printf_buffer(__VA_ARGS__) -#else -#define PLOG_DEBUG_BUFFER(...) -#endif - -#define RET_MBEDTLS_SUCCESS_OR_EXIT_MSG(MSG, ...) \ - if (0 != ret) \ - { \ - status = STATUS_ERROR_GENERIC; \ - PLOG_ERROR(MSG, __VA_ARGS__); \ - goto exit; \ - } - -#define STATUS_SUCCESS_OR_EXIT_MSG(MSG, ...) \ - if (STATUS_SUCCESS != status) \ - { \ - PLOG_ERROR(MSG, __VA_ARGS__); \ - goto exit; \ - } - -// common flags -#define PSA_KEY_LOCATION_NXP_FLAG 0x400000U -#define PSA_KEY_LOCATION_EL2GO_FLAG 0x200000U -#define PSA_KEY_LOCATION_S50_FLAG 0x000001U -#define PSA_KEY_LOCATION_COMMON_FLAG \ - (PSA_KEY_LOCATION_VENDOR_FLAG | PSA_KEY_LOCATION_NXP_FLAG | PSA_KEY_LOCATION_EL2GO_FLAG | PSA_KEY_LOCATION_S50_FLAG) - -// key/data -#define PSA_KEY_LOCATION_KEY_FLAG 0x000000 -#define PSA_KEY_LOCATION_DATA_FLAG 0x008000 - -// blob/encrypted -#define PSA_KEY_LOCATION_BLOB_STORAGE_FLAG 0x000000 -#define PSA_KEY_LOCATION_ENC_STORAGE_FLAG 0x000100 -#define PSA_KEY_LOCATION_TEMP_STORAGE_FLAG 0x000200 -#define PSA_KEY_LOCATION_KEY_GEN_STORAGE_FLAG 0x000300 - -#define PSA_KEY_LOCATION_S50_BLOB_STORAGE \ - ((PSA_KEY_LOCATION_COMMON_FLAG | PSA_KEY_LOCATION_BLOB_STORAGE_FLAG | PSA_KEY_LOCATION_KEY_FLAG)) -#define MCUXCLPSADRIVER_IS_S50_BLOB_STORAGE(location) ((location) == PSA_KEY_LOCATION_S50_BLOB_STORAGE) -#define PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location) ((location) << 8 | (persistence)) - -#define NXP_DIE_INT_IMPORT_KEK_SK 0x7FFF817CU -#define NXP_DIE_INT_IMPORT_AUTH_SK 0x7FFF817EU - -const mcuxClEls_KeyProp_t keypair_prop = { .bits = { - .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, - .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, - .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, - - } }; - -const mcuxClEls_KeyProp_t shared_secret_prop = { - .bits = - { - .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_128, - .uckdf = MCUXCLELS_KEYPROPERTY_CKDF_TRUE, - .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, - .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, - - - }, -}; - -const mcuxClEls_KeyProp_t wrap_in_key_prop = { - .bits = - { - .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_128, - .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, - .ukuok = MCUXCLELS_KEYPROPERTY_KUOK_TRUE, - .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, - .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, - - }, -}; - -const uint8_t ckdf_derivation_data_wrap_in[12] = { - 0xc8, 0xac, 0x48, 0x88, 0xa6, 0x1b, 0x3d, 0x9b, 0x56, 0xa9, 0x75, 0xe7, -}; - -const mcuxClEls_KeyProp_t wrap_out_key_prop = { - .bits = - { - .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, - .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, - .ukwk = MCUXCLELS_KEYPROPERTY_KWK_TRUE, - .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, - .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, - - - }, -}; - -const uint8_t ckdf_derivation_data_wrap_out[12] = { - 0x4e, 0x5f, 0x0a, 0x1c, 0x43, 0x37, 0x2c, 0xd0, 0x54, 0x8e, 0x46, 0xc9, -}; - -const mcuxClEls_KeyProp_t mac_key_prop = { - .bits = - { - .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, - .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, - .ucmac = MCUXCLELS_KEYPROPERTY_CMAC_TRUE, - .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, - .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, - }, -}; - -const uint8_t ckdf_derivation_data_mac[12] = { - 0xea, 0x93, 0x05, 0x7a, 0x50, 0xb6, 0x4d, 0x58, 0x0a, 0xe6, 0x6b, 0x57, -}; - -const uint8_t import_die_int_ecdh_sk[32] = { - 0x82, 0x9b, 0xb4, 0x4a, 0x3b, 0x6d, 0x73, 0x35, 0x09, 0x5e, 0xd9, 0x8d, 0xf6, 0x09, 0x89, 0x98, - 0xac, 0x63, 0xab, 0x4e, 0x4e, 0x78, 0xf6, 0x0a, 0x70, 0xea, 0x64, 0x92, 0xd4, 0xfc, 0xe4, 0x92, -}; - -const uint8_t import_die_int_ecdh_pk[64] = { - 0x8c, 0xe2, 0x3a, 0x89, 0xe7, 0xc5, 0xe9, 0xb1, 0x3e, 0x89, 0xed, 0xdb, 0x69, 0xb9, 0x22, 0xf8, - 0xc2, 0x8f, 0x5d, 0xcc, 0x59, 0x3e, 0x5f, 0x7b, 0x6e, 0x5a, 0x6c, 0xb3, 0x62, 0xc0, 0x17, 0x8a, - 0x2f, 0xda, 0xe8, 0x72, 0x67, 0x7b, 0xdf, 0xfe, 0xdb, 0x4a, 0x6e, 0x39, 0x2a, 0x1b, 0xae, 0xf8, - 0x88, 0x8f, 0xc5, 0x11, 0xc3, 0x67, 0x85, 0x5a, 0xc5, 0x54, 0xbb, 0xeb, 0x19, 0xf6, 0x52, 0x66, -}; - -const uint8_t key_blob_magic[7] = { 'k', 'e', 'y', 'b', 'l', 'o', 'b' }; - -const size_t s50_blob_size = 100; - -const char nibble_to_char[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', -}; - -uint8_t * append_u32(uint8_t * pos, uint32_t val); -uint8_t * append_u16(uint8_t * pos, uint32_t val); -void write_uint32_msb_first(uint8_t * pos, uint32_t data); -void printf_buffer(const char * name, const unsigned char * buffer, size_t size); -uint32_t get_required_keyslots(mcuxClEls_KeyProp_t prop); -bool els_is_active_keyslot(mcuxClEls_KeyIndex_t keyIdx); -status_t els_enable(); -status_t els_get_key_properties(mcuxClEls_KeyIndex_t key_index, mcuxClEls_KeyProp_t * key_properties); -mcuxClEls_KeyIndex_t els_get_free_keyslot(uint32_t required_keyslots); -status_t els_derive_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyProp_t key_prop, const uint8_t * dd, - mcuxClEls_KeyIndex_t * dst_key_index); -status_t els_delete_key(mcuxClEls_KeyIndex_t key_index); -status_t els_import_key(const uint8_t * wrapped_key, size_t wrapped_key_size, mcuxClEls_KeyProp_t key_prop, - mcuxClEls_KeyIndex_t unwrap_key_index, mcuxClEls_KeyIndex_t * dst_key_index); -status_t els_keygen(mcuxClEls_KeyIndex_t key_index, uint8_t * public_key, size_t * public_key_size); -status_t calculate_psa_import_blob_cmac(uint8_t * psa_import_blob, size_t psa_import_blob_length_before_mac, - size_t psa_import_blob_size); -status_t create_psa_import_blob(const uint8_t * els_key_blob, size_t els_key_blob_size, const psa_key_attributes_t * attributes, - uint8_t * output, size_t * output_size); -status_t import_die_int_wrapped_key_into_els(const uint8_t * wrapped_key, size_t wrapped_key_size, - mcuxClEls_KeyProp_t key_properties, mcuxClEls_KeyIndex_t * index_output); -status_t ELS_sign_hash(uint8_t * digest, mcuxClEls_EccByte_t * ecc_signature, mcuxClEls_EccSignOption_t * sign_options, - mcuxClEls_KeyIndex_t key_index); - -#endif diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp b/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp new file mode 100644 index 00000000000000..b57a48883bbb41 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp @@ -0,0 +1,481 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright 2023 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FactoryDataProviderEncImpl.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +#include "ELSFactoryData.h" +#include "mflash_drv.h" + +#include "fsl_adapter_flash.h" + +/* mbedtls */ +#include "mbedtls/aes.h" +#include "mbedtls/sha256.h" + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#ifndef FACTORY_DATA_PROVIDER_LOG +#define FACTORY_DATA_PROVIDER_LOG 0 +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#include "fsl_debug_console.h" +#define FACTORY_DATA_PROVIDER_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define FACTORY_DATA_PROVIDER_PRINTF(...) +#endif + +/* Grab symbol for the base address from the linker file. */ +extern uint32_t __FACTORY_DATA_START_OFFSET[]; +extern uint32_t __FACTORY_DATA_SIZE[]; +extern uint32_t __FACTORY_DATA_END[]; + +using namespace ::chip::Credentials; +using namespace ::chip::Crypto; + +namespace chip { +namespace DeviceLayer { + +FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; + +static constexpr size_t kAesKeyBlobLength = Crypto::kP256_PrivateKey_Length + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; + +#define TAG_ID_FOR_AES_KEY_BOLB 0xFE +#define MEM_ALIGN_4(size) ((size + 4) / 4 * 4) + +CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint8_t type = 0; + uint32_t index = 0; + uint8_t * addrContent = NULL; + uint8_t * factoryDataAddress = &factoryDataRamBuffer[0]; + uint32_t factoryDataSize = sizeof(factoryDataRamBuffer); + uint16_t currentLen = 0; + + while (index < factoryDataSize) + { + /* Read the type */ + memcpy((uint8_t *) &type, factoryDataAddress + index, sizeof(type)); + index += sizeof(type); + + /* Read the len */ + memcpy((uint8_t *) ¤tLen, factoryDataAddress + index, sizeof(currentLen)); + index += sizeof(currentLen); + + /* Check if the type gotten is the expected one */ + if (searchedType == type) + { + FACTORY_DATA_PROVIDER_PRINTF("type = %d, currentLen = %d, bufLength =%d", type, currentLen, bufLength); + /* If pBuf is null it means that we only want to know if the Type has been found */ + if (pBuf != NULL) + { + /* If the buffer given is too small, fill only the available space */ + if (bufLength < currentLen) + { + currentLen = bufLength; + } + memcpy((uint8_t *) pBuf, factoryDataAddress + index, currentLen); + } + length = currentLen; + if (contentAddr != NULL) + { + *contentAddr = (uint32_t) factoryDataAddress + index; + } + err = CHIP_NO_ERROR; + break; + } + else if (type == 0) + { + /* No more type available , break the loop */ + break; + } + else + { + /* Jump to next data */ + index += currentLen; + } + } + + return err; +} + +CHIP_ERROR FactoryDataProviderImpl::ELS_ImportWrappedKeyAndDecrypt(MutableByteSpan & key, uint8_t * encrypt, uint16_t size, + uint8_t * decrypt) +{ + uint8_t els_key_blob[kAesKeyBlobLength]; + size_t els_key_blob_size = sizeof(els_key_blob); + status_t status = STATUS_SUCCESS; + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + uint8_t public_key[64] = { 0 }; + size_t public_key_size = sizeof(public_key); + + mcuxClEls_KeyProp_t plain_key_properties = { + .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | + MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_AES } + }; + + if (key.data() == NULL) + return CHIP_ERROR_INTERNAL; + + memcpy(els_key_blob, key.data(), key.size()); + + PLOG_DEBUG_BUFFER("els key blob", els_key_blob, els_key_blob_size); + + /* Import blob DAC key into SE50 (reserved key slot) */ + status = import_die_int_wrapped_key_into_els(els_key_blob, els_key_blob_size, plain_key_properties, &key_index); + STATUS_SUCCESS_OR_EXIT_MSG("import_die_int_wrapped_key_into_els failed: 0x%08x", status); + + ELS_Cipher_Aes_Ecb_Decrypt(key_index, encrypt, size, decrypt); + + els_delete_key(key_index); + + return CHIP_NO_ERROR; +exit: + els_delete_key(key_index); + return CHIP_ERROR_INVALID_SIGNATURE; +} + +CHIP_ERROR FactoryDataProviderImpl::LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serialized_keypair; + ReturnErrorOnFailure(serialized_keypair.SetLength(privateKey.size() + publicKey.size())); + memcpy(serialized_keypair.Bytes(), publicKey.data(), publicKey.size()); + memcpy(serialized_keypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size()); + return keypair.Deserialize(serialized_keypair); +} + +CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + + VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(digestToSign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + + // In a non-exemplary implementation, the public key is not needed here. It is used here merely because + // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. + Crypto::P256PublicKey dacPublicKey; + uint16_t certificateSize = 0; + uint32_t certificateAddr; + ReturnLogErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, certificateSize, &certificateAddr)); + MutableByteSpan dacCertSpan((uint8_t *) certificateAddr, certificateSize); + + /* Extract Public Key of DAC certificate from itself */ + ReturnLogErrorOnFailure(Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey)); + + /* Get private key of DAC certificate from reserved section */ + uint16_t keySize = 0; + uint32_t keyAddr; + ReturnLogErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize, &keyAddr)); + MutableByteSpan dacPrivateKeySpan((uint8_t *) keyAddr, keySize); + + ReturnLogErrorOnFailure(LoadKeypairFromRaw(ByteSpan(dacPrivateKeySpan.data(), dacPrivateKeySpan.size()), + ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); + + ReturnLogErrorOnFailure(keypair.ECDSA_sign_msg(digestToSign.data(), digestToSign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); +} + +CHIP_ERROR FactoryDataProviderImpl::ReadAndCheckFactoryDataInFlash(void) +{ + status_t status; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + uint32_t hashId; + + uint16_t i; + + /* Init mflash */ + status = mflash_drv_init(); + + if (status != kStatus_Success || factoryDataSize > sizeof(factoryDataRamBuffer)) + return CHIP_ERROR_INTERNAL; + + /* Load the factory data into RAM buffer */ + if (mflash_drv_read(factoryDataAddress, (uint32_t *) &factoryDataRamBuffer[0], factoryDataSize) != kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + + memcpy(&mHeader, factoryDataRamBuffer, sizeof(mHeader)); + + if (mHeader.hashId != HASH_ID) + { + return CHIP_ERROR_NOT_FOUND; + } + + /* remove the header section */ + memmove(&factoryDataRamBuffer[0], &factoryDataRamBuffer[sizeof(mHeader)], mHeader.size); + + return CHIP_NO_ERROR; +} + +/* the factory data must be sencrypted by AES-256 */ +CHIP_ERROR FactoryDataProviderImpl::DecryptAndCheckFactoryData(void) +{ + status_t status; + bool encrypted = false; + uint16_t i = 0; + uint32_t factoryDataSize = mHeader.size; + uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; + uint8_t currentBlock[BLOCK_SIZE_16_BYTES]; + CHIP_ERROR res; + uint8_t type; + uint16_t len; + + while (i < factoryDataSize) + { + type = factoryDataRamBuffer[i]; + len = factoryDataRamBuffer[i + 1] + (factoryDataRamBuffer[i + 2] << 8); + i += len; + if ((type > kMaxId) || (i > factoryDataSize)) + { + ChipLogProgress(DeviceLayer, "factory data is encrypted\n"); + encrypted = true; + break; + } + } + + if (encrypted) + { + mbedtls_aes_context aesCtx; + int status = 0; + do + { + mbedtls_aes_init(&aesCtx); + if (mbedtls_aes_setkey_dec(&aesCtx, pAesKey, 256U) != 0) + { + status = -1; + break; + } + for (i = 0; i < factoryDataSize / BLOCK_SIZE_16_BYTES; i++) + { + if (mbedtls_aes_crypt_ecb(&aesCtx, MBEDTLS_AES_DECRYPT, &factoryDataRamBuffer[i * 16], ¤tBlock[0]) != 0) + { + status = -2; + break; + } + memcpy(&factoryDataRamBuffer[i * 16], ¤tBlock[0], sizeof(currentBlock)); + } + mbedtls_aes_free(&aesCtx); + } while (false); + + if (status < 0) + { + ChipLogError(DeviceLayer, "factory data decryption Failure, status:%d", status); + return CHIP_ERROR_WRONG_ENCRYPTION_TYPE; + } + ChipLogProgress(DeviceLayer, "factory data decryption is successful!"); + } + else + { + ChipLogError(DeviceLayer, "factory data is in plain text!"); + } + + /* Calculate SHA256 value over the factory data and compare with stored value */ + res = Hash_SHA256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); + + if (res != CHIP_NO_ERROR) + return res; + + if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) + { + return CHIP_ERROR_NOT_FOUND; + } + + ChipLogProgress(DeviceLayer, "factory data hash check is successful!"); + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kVerifierId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kSaltId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kIcId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacPrivateKeyId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kPaiCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, NULL, 0, len)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::Init(void) +{ + uint8_t type; + ReturnLogErrorOnFailure(ReadAndCheckFactoryDataInFlash()); + + els_enable(); + + ChipLogProgress(DeviceLayer, "init: protect whole factory data\n"); + + /* check if AES Key blob attached in the tail of factory data*/ + uint16_t size = MEM_ALIGN_4(sizeof(uint8_t) + sizeof(uint16_t) + kAesKeyBlobLength); + uint16_t len; + type = factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE - size]; + len = factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE - size + kLengthOffset] + + (factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE - size + kLengthOffset + 1] << 8); + ChipLogProgress(DeviceLayer, "aes key blob type:%x, len:%d", type, len); + if ((type == TAG_ID_FOR_AES_KEY_BOLB) && (len == kAesKeyBlobLength)) + { + MutableByteSpan key(&factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE - size + kValueOffset], len); + mcuxClEls_KeyIndex_t index; + + uint8_t * data = static_cast(chip::Platform::MemoryAlloc(mHeader.size)); + memset(data, 0, mHeader.size); + + /* will provision the wrapping key to edgelock and decrypt the factory data */ + ReturnLogErrorOnFailure(ELS_ImportWrappedKeyAndDecrypt(key, &factoryDataRamBuffer[0], mHeader.size, data)); + + memcpy(factoryDataRamBuffer, data, FACTORY_DATA_MAX_SIZE); + chip::Platform::MemoryFree(data); + } + else + { + /* This situation is usually in production mode, the AES key is passed through Uart and only runs once. + The AES Key is provisioined into Edge Lock, and the returned wrapped key is store in the end the factory data in TLV mode. + Here we take the precondition that we already got the AES Key, and check whether the decrypted factory data is right and + provision it into Edge Lock if right. */ + /* pAesKey should be pointed to a real key in advance on app layer, so should not be NULL. + Currently the fwk_factory_data_provider module supports only ecb mode. Therefore return an error if encrypt mode is not ecb + */ + if (pAesKey == NULL || encryptMode != encrypt_ecb) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + ReturnLogErrorOnFailure(DecryptAndCheckFactoryData()); + ReturnLogErrorOnFailure(ELS_SaveAesKeyBlob()); + + ChipLogProgress(DeviceLayer, "System restarting"); + // Restart the system. + NVIC_SystemReset(); + while (1) + { + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::ELS_SaveAesKeyBlob() +{ + size_t blobSize = kAesKeyBlobLength; + uint8_t blob[kAesKeyBlobLength] = { 0 }; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + + VerifyOrReturnError(factoryDataRamBuffer != nullptr, CHIP_ERROR_INTERNAL); + + uint8_t type = TAG_ID_FOR_AES_KEY_BOLB; + ReturnErrorOnFailure(ELS_ExportBlob(blob, &blobSize)); + PLOG_DEBUG_BUFFER("els key blob", blob, blobSize); + ChipLogProgress(DeviceLayer, "SSS: extracted blob from factory data AES key"); + + /* Read all factory data */ + hal_flash_status_t status = + HAL_FlashRead(factoryDataAddress + MFLASH_BASE_ADDRESS, FACTORY_DATA_MAX_SIZE, &factoryDataRamBuffer[0]); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: cached factory data in RAM"); + + /* save the Aes Key Blob in the end of factory data region */ + uint16_t size = MEM_ALIGN_4(sizeof(uint8_t) + sizeof(uint16_t) + kAesKeyBlobLength); + memcpy(&factoryDataRamBuffer[factoryDataSize - size], &type, sizeof(uint8_t)); + memcpy(&factoryDataRamBuffer[factoryDataSize - size + kLengthOffset], &blobSize, sizeof(uint16_t)); + memcpy(&factoryDataRamBuffer[factoryDataSize - size + kValueOffset], blob, blobSize); + ChipLogError(DeviceLayer, "SSS: attach wrapped key in the end of factory data in tlv format"); + + /* Erase flash factory data sectors */ + status = HAL_FlashEraseSector(factoryDataAddress + MFLASH_BASE_ADDRESS, FACTORY_DATA_MAX_SIZE); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + /* Write new factory data into flash */ + status = HAL_FlashProgramUnaligned(factoryDataAddress + MFLASH_BASE_ADDRESS, FACTORY_DATA_MAX_SIZE, factoryDataRamBuffer); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: updated factory data"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::ELS_ExportBlob(uint8_t * data, size_t * dataLen) +{ + status_t status = STATUS_SUCCESS; + mcuxClEls_KeyProp_t plain_key_properties = { + .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | + MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_AES } + }; + + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + /* Import plain DAC key into S50 */ + status = import_plain_key_into_els(pAesKey, Crypto::kP256_PrivateKey_Length, plain_key_properties, &key_index); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + /* ELS generate key blob. The blob created here is one that can be directly imported into ELS again. */ + status = export_key_from_els(key_index, data, dataLen); + STATUS_SUCCESS_OR_EXIT_MSG("export_key_from_els failed: 0x%08x", status); + + status = els_delete_key(key_index); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SetAes256Key(const uint8_t * keyAes256) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (keyAes256 != nullptr) + { + pAesKey = keyAes256; + error = CHIP_NO_ERROR; + } + + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::SetEncryptionMode(EncryptionMode mode) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + + /* + * Currently the fwk_factory_data_provider module supports only ecb mode. + * Therefore return an error if encrypt mode is not ecb + */ + if (mode == encrypt_ecb) + { + encryptMode = mode; + error = CHIP_NO_ERROR; + } + return error; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h b/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h new file mode 100644 index 00000000000000..7a41eb6fbfd752 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright 2023 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#define FACTORY_DATA_MAX_SIZE 4096 + +namespace chip { +namespace DeviceLayer { + +/** + * @brief This class provides Commissionable data and Device Attestation Credentials. + * + * This implementation allows to use the ELS hardware module to load the Matter factory + * dataset in RAM at the boot. + * + * + */ + +class FactoryDataProviderImpl : public FactoryDataProvider +{ +public: + static FactoryDataProviderImpl sInstance; + + CHIP_ERROR Init(void); + CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr = NULL); + CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair); + CHIP_ERROR SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer); + + CHIP_ERROR SetAes256Key(const uint8_t * keyAes256); + CHIP_ERROR SetEncryptionMode(EncryptionMode mode); + +private: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + uint8_t factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE]; + Header mHeader; + + /* TLV offset */ + static constexpr uint32_t kLengthOffset = 1; + static constexpr uint32_t kValueOffset = 3; + + CHIP_ERROR ELS_ExportBlob(uint8_t * data, size_t * dataLen); + CHIP_ERROR ELS_SaveAesKeyBlob(); + + CHIP_ERROR ReadAndCheckFactoryDataInFlash(void); + CHIP_ERROR DecryptAndCheckFactoryData(void); + CHIP_ERROR ELS_ImportWrappedKeyAndDecrypt(MutableByteSpan & key, uint8_t * encrypt, uint16_t size, uint8_t * decrypt); + + const uint8_t * pAesKey = nullptr; + EncryptionMode encryptMode = encrypt_ecb; +}; + +inline FactoryDataProvider & FactoryDataPrvd() +{ + return FactoryDataProviderImpl::sInstance; +} + +inline FactoryDataProviderImpl & FactoryDataPrvdImpl() +{ + return FactoryDataProviderImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp index 299a018fabd092..73155af65eb48c 100644 --- a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp @@ -25,13 +25,11 @@ extern "C" { #include "ELSFactoryData.h" #include "mflash_drv.h" -#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY #include "fsl_adapter_flash.h" -#endif -#ifndef FACTORY_DATA_PROVIDER_RUN_TESTS -#define FACTORY_DATA_PROVIDER_RUN_TESTS 0 -#endif +/* mbedtls */ +#include "mbedtls/aes.h" +#include "mbedtls/sha256.h" #if defined(__cplusplus) } @@ -63,6 +61,8 @@ namespace DeviceLayer { FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; +static constexpr size_t kPrivateKeyBlobLength = Crypto::kP256_PrivateKey_Length + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; + CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * contentAddr) { @@ -123,16 +123,13 @@ CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) { - uint8_t els_key_blob[MAX_ELS_KEY_SIZE + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD]; - uint16_t keySize = 0; - uint32_t keyAddr; - status_t status = STATUS_SUCCESS; + uint8_t els_key_blob[kPrivateKeyBlobLength]; size_t els_key_blob_size = sizeof(els_key_blob); + uint16_t keySize = 0; + status_t status = STATUS_SUCCESS; uint8_t digest[kSHA256_Hash_Length]; - uint8_t public_key[64] = { 0 }; - size_t public_key_size = sizeof(public_key); - mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; mcuxClEls_KeyProp_t plain_key_properties = { .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_KGSRC } @@ -140,39 +137,15 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign mcuxClEls_EccSignOption_t sign_options = { 0 }; mcuxClEls_EccByte_t ecc_signature[MCUXCLELS_ECC_SIGNATURE_SIZE]; - uint8_t psa_import_blob[256]; - size_t psa_import_blob_size = sizeof(psa_import_blob); + + uint8_t public_key[64] = { 0 }; + size_t public_key_size = sizeof(public_key); /* Search key ID FactoryDataId::kDacPrivateKeyId */ - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize, &keyAddr)); - memcpy(els_key_blob, (uint8_t *) keyAddr, keySize); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, els_key_blob, els_key_blob_size, keySize)); PLOG_DEBUG_BUFFER("els_key_blob", els_key_blob, els_key_blob_size); - /* Calculate message HASH to sign */ - memset(&digest[0], 0, sizeof(digest)); - ReturnErrorOnFailure(Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0])); - - PLOG_DEBUG_BUFFER("digestToSign", digestToSign.data(), digestToSign.size()); - - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&attributes, 256); - psa_set_key_lifetime( - &attributes, - PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT, PSA_KEY_LOCATION_S50_BLOB_STORAGE)); - psa_set_key_id(&attributes, 0x3E000021); - - /*To satisfy PSA APIs and to bind key attributes on PSA level to the key, a TLV structure is created - containing the els_key_blob and metadata. That TLV structure gets a CMAC. This structure is quasi - identical to what EdgeLock 2GO is creating. Note that the TLV structure is not used below but - required in case a blob shall be imported into TF-M for RW61x. */ - status = create_psa_import_blob(els_key_blob, els_key_blob_size, &attributes, psa_import_blob, &psa_import_blob_size); - STATUS_SUCCESS_OR_EXIT_MSG("export_key_from_els failed: 0x%08x", status); - PLOG_DEBUG_BUFFER("psa_import_blob", psa_import_blob, psa_import_blob_size); - /* Import blob DAC key into SE50 (reserved key slot) */ status = import_die_int_wrapped_key_into_els(els_key_blob, els_key_blob_size, plain_key_properties, &key_index); STATUS_SUCCESS_OR_EXIT_MSG("import_die_int_wrapped_key_into_els failed: 0x%08x", status); @@ -187,6 +160,12 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign /* The key is usable for signing. */ PLOG_DEBUG_BUFFER("public_key", public_key, public_key_size); + /* Calculate message HASH to sign */ + memset(&digest[0], 0, sizeof(digest)); + ReturnErrorOnFailure(Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0])); + + PLOG_DEBUG_BUFFER("digestToSign", digestToSign.data(), digestToSign.size()); + /* ECC sign message hash with the key index slot reserved during the blob importation */ ELS_sign_hash(digest, ecc_signature, &sign_options, key_index); @@ -195,26 +174,19 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign /* Generate MutableByteSpan with ECC signature and ECC signature size */ return CopySpanToMutableSpan(ByteSpan{ ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE }, outSignBuffer); + exit: els_delete_key(key_index); return CHIP_ERROR_INVALID_SIGNATURE; } -CHIP_ERROR FactoryDataProviderImpl::Init(void) +CHIP_ERROR FactoryDataProviderImpl::ReadAndCheckFactoryDataInFlash(void) { -#if FACTORY_DATA_PROVIDER_RUN_TESTS - unittest(); -#else - els_enable(); - - uint16_t len; status_t status; uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; uint32_t hashId; - uint8_t currentBlock[BLOCK_SIZE_16_BYTES]; uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; - uint16_t i; CHIP_ERROR res; /* Init mflash */ @@ -223,35 +195,21 @@ CHIP_ERROR FactoryDataProviderImpl::Init(void) if (status != kStatus_Success || factoryDataSize > sizeof(factoryDataRamBuffer)) return CHIP_ERROR_INTERNAL; - /* Read hash id saved in flash */ - if (mflash_drv_read(factoryDataAddress, (uint32_t *) &mHeader, sizeof(mHeader)) != kStatus_Success) + /* Load the factory data into RAM buffer */ + if (mflash_drv_read(factoryDataAddress, (uint32_t *) &factoryDataRamBuffer[0], factoryDataSize) != kStatus_Success) { return CHIP_ERROR_INTERNAL; } - + memcpy(&mHeader, factoryDataRamBuffer, sizeof(mHeader)); if (mHeader.hashId != HASH_ID) { return CHIP_ERROR_NOT_FOUND; } - - /* Update address to start after hash id to read size of factory data */ - factoryDataAddress += sizeof(mHeader); - - /* Load the buffer into RAM by reading each 16 bytes blocks */ - for (i = 0; i < (factoryDataSize / BLOCK_SIZE_16_BYTES); i++) - { - if (mflash_drv_read(factoryDataAddress + i * BLOCK_SIZE_16_BYTES, (uint32_t *) ¤tBlock[0], sizeof(currentBlock)) != - kStatus_Success) - { - return CHIP_ERROR_INTERNAL; - } - - /* Store the block unencrypted */ - memcpy(&factoryDataRamBuffer[i * BLOCK_SIZE_16_BYTES], ¤tBlock[0], sizeof(currentBlock)); - } + /* remove the header section */ + memmove(&factoryDataRamBuffer[0], &factoryDataRamBuffer[sizeof(mHeader)], mHeader.size); /* Calculate SHA256 value over the factory data and compare with stored value */ - res = Hash256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); + res = Hash_SHA256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); if (res != CHIP_NO_ERROR) return res; @@ -261,107 +219,63 @@ CHIP_ERROR FactoryDataProviderImpl::Init(void) return CHIP_ERROR_NOT_FOUND; } - ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kVerifierId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kSaltId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kIcId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacPrivateKeyId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacCertificateId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, NULL, 0, len)); - FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kPaiCertificateId, len); - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, NULL, 0, len)); - -#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY - ReturnErrorOnFailure(ELS_ConvertDacKey()); -#endif -#endif + ChipLogProgress(DeviceLayer, "factory data hash check is successful!"); return CHIP_NO_ERROR; } -CHIP_ERROR FactoryDataProviderImpl::Hash256(const uint8_t * input, size_t inputSize, uint8_t * output) -{ - CHIP_ERROR res; - res = Hash_SHA256(input, inputSize, output); - - return res; -} - -#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY -static inline uint32_t els_get_key_size(mcuxClEls_KeyIndex_t keyIdx) +CHIP_ERROR FactoryDataProviderImpl::Init(void) { - mcuxClEls_KeyProp_t key_properties; - key_properties.word.value = ((const volatile uint32_t *) (&ELS->ELS_KS0))[keyIdx]; - return (key_properties.bits.ksize == MCUXCLELS_KEYPROPERTY_KEY_SIZE_256) ? (256U / 8U) : (128U / 8U); -} + uint16_t len; + uint8_t type; + uint16_t keySize = 0; -static status_t els_export_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyIndex_t wrap_key_index, uint8_t * els_key_out_blob, - size_t * els_key_out_blob_size) + ReturnLogErrorOnFailure(ReadAndCheckFactoryDataInFlash()); -{ - uint32_t key_size = els_get_key_size(src_key_index); - uint32_t required_blob_size = ELS_BLOB_METADATA_SIZE + key_size + ELS_WRAP_OVERHEAD; - assert(required_blob_size <= *els_key_out_blob_size); + els_enable(); - *els_key_out_blob_size = required_blob_size; + ChipLogProgress(DeviceLayer, "init: only protect DAC private key\n"); - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_KeyExport_Async(wrap_key_index, src_key_index, els_key_out_blob)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyExport_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + /* check whether the kDacPrivateKeyId data is converted or not*/ + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize)); + if (keySize == kPrivateKeyBlobLength) { - PLOG_ERROR("mcuxClEls_KeyExport_Async failed: 0x%08lx", result); - return STATUS_ERROR_GENERIC; + /* the kDacPrivateKeyId data is converted already, do nothing */ + ChipLogProgress(DeviceLayer, "SSS: DAC private key already converted to blob"); + return CHIP_NO_ERROR; } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + else { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08lx", result); - return STATUS_ERROR_GENERIC; + /* provison the dac private key into Edge Lock and the returned wrapped key is stored the previous area of factory data, + update the hash and re-write the factory data in Flash */ + ChipLogProgress(DeviceLayer, "SSS: convert DAC private key to blob"); + ReturnLogErrorOnFailure(ELS_ConvertDacKey()); + ChipLogProgress(DeviceLayer, "System restarting"); + // Restart the system. + NVIC_SystemReset(); + while (1) + { + } } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} -static status_t export_key_from_els(mcuxClEls_KeyIndex_t key_index, uint8_t * output, size_t * output_size) -{ - assert(output != NULL); - status_t status = STATUS_SUCCESS; - - mcuxClEls_KeyIndex_t key_wrap_out_index = MCUXCLELS_KEY_SLOTS; - PLOG_INFO("Deriving wrapping key for export on ELS..."); - status = els_derive_key(DIE_INT_MK_SK_INDEX, wrap_out_key_prop, ckdf_derivation_data_wrap_out, &key_wrap_out_index); - STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); - - PLOG_INFO("Exporting/wrapping key..."); - status = els_export_key(key_index, key_wrap_out_index, output, output_size); - STATUS_SUCCESS_OR_EXIT_MSG("export_key failed: 0x%08x", status); - - status = els_delete_key(key_wrap_out_index); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - key_wrap_out_index = MCUXCLELS_KEY_SLOTS; -exit: - return status; + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() { - size_t blobSize = MAX_ELS_KEY_SIZE + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; - size_t newSize = sizeof(Header) + mHeader.size + (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD); - uint8_t blob[Crypto::kP256_PrivateKey_Length + (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD)] = { 0 }; + size_t blobSize = kPrivateKeyBlobLength; + size_t newSize = sizeof(Header) + mHeader.size + (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD); + uint8_t blob[kPrivateKeyBlobLength] = { 0 }; uint32_t KeyAddr; uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; - uint8_t * data = static_cast(chip::Platform::MemoryAlloc(newSize)); VerifyOrReturnError(factoryDataRamBuffer != nullptr, CHIP_ERROR_INTERNAL); + uint8_t * data = static_cast(chip::Platform::MemoryAlloc(newSize)); /* Import pain DAC key and generate the blob */ ReturnErrorOnFailure(ELS_ExportBlob(blob, &blobSize, KeyAddr)); - ChipLogError(DeviceLayer, "SSS: extracted blob from DAC private key"); + ChipLogProgress(DeviceLayer, "SSS: extracted blob from DAC private key"); + PLOG_DEBUG_BUFFER("blob", blob, blobSize); /* Read all factory data */ hal_flash_status_t status = @@ -373,7 +287,6 @@ CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() */ ReturnErrorOnFailure(ReplaceWithBlob(data, blob, blobSize, KeyAddr)); ChipLogError(DeviceLayer, "SSS: replaced DAC private key with secured blob"); - PLOG_DEBUG_BUFFER("ReplaceWithBlob", data, newSize); /* Erase flash factory data sectors */ status = HAL_FlashEraseSector(factoryDataAddress + MFLASH_BASE_ADDRESS, factoryDataSize); @@ -383,387 +296,21 @@ CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); ChipLogError(DeviceLayer, "SSS: updated factory data"); + chip::Platform::MemoryFree(data); return CHIP_NO_ERROR; } -static status_t els_generate_keypair(mcuxClEls_KeyIndex_t * dst_key_index, uint8_t * public_key, size_t * public_key_size) -{ - if (*public_key_size < 64) - { - PLOG_ERROR("insufficient space for public key"); - return STATUS_ERROR_GENERIC; - } - - mcuxClEls_EccKeyGenOption_t options = { 0 }; - options.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_RANDOM; - options.bits.kgtypedh = MCUXCLELS_ECC_OUTPUTKEY_KEYEXCHANGE; - - uint32_t keypair_required_keyslots = get_required_keyslots(keypair_prop); - *dst_key_index = (mcuxClEls_KeyIndex_t) els_get_free_keyslot(keypair_required_keyslots); - - if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) - { - PLOG_ERROR("no free keyslot found"); - return STATUS_ERROR_GENERIC; - } - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( - result, token, - mcuxClEls_EccKeyGen_Async(options, (mcuxClEls_KeyIndex_t) 0U, *dst_key_index, keypair_prop, NULL, public_key)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyGen_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_EccKeyGen_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - *public_key_size = 64; - return STATUS_SUCCESS; -} - -static status_t els_get_random(unsigned char * out, size_t out_size) -{ - /* Get random IV for sector metadata encryption. */ - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClCss_Rng_DrbgRequest_Async(out, out_size)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_Rng_DrbgRequest_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PRINTF("mcuxClCss_Rng_DrbgRequest_Async failed: 0x%08lx\r\n", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClCss_WaitForOperation(MCUXCLCSS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PRINTF("Css_EccKeyGen_Async WaitForOperation failed: 0x%08lx\r\n", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - return STATUS_SUCCESS; -} - -static int get_random_mbedtls_callback(void * ctx, unsigned char * out, size_t out_size) -{ - status_t status = els_get_random(out, out_size); - if (status != STATUS_SUCCESS) - { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - return 0; -} - -static status_t host_perform_key_agreement(const uint8_t * public_key, size_t public_key_size, uint8_t * shared_secret, - size_t * shared_secret_size) -{ - assert(public_key != NULL); - assert(public_key_size == 64); - assert(shared_secret != NULL); - assert(*shared_secret_size >= 32); - - status_t status = STATUS_SUCCESS; - - int ret = 0; - mbedtls_ecp_group grp; - mbedtls_ecp_point qB; - mbedtls_mpi dA, zA; - mbedtls_ecp_group_init(&grp); - mbedtls_ecp_point_init(&qB); - mbedtls_mpi_init(&dA); - mbedtls_mpi_init(&zA); - - unsigned char strbuf[128] = { 0 }; - size_t strlen = sizeof(strbuf); - - uint8_t public_key_compressed[65] = { 0 }; - public_key_compressed[0] = 0x04; - - *shared_secret_size = 32; - ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecp_group_load failed: 0x%08x", ret); - - ret = mbedtls_mpi_read_binary(&dA, import_die_int_ecdh_sk, sizeof(import_die_int_ecdh_sk)); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_mpi_read_binary failed: 0x%08x", ret); - - memcpy(&public_key_compressed[1], public_key, public_key_size); - - ret = mbedtls_ecp_point_read_binary(&grp, &qB, public_key_compressed, sizeof(public_key_compressed)); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecp_point_read_binary failed: 0x%08x", ret); - - ret = mbedtls_ecdh_compute_shared(&grp, &zA, &qB, &dA, &get_random_mbedtls_callback, NULL); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecdh_compute_shared failed: 0x%08x", ret); - - mbedtls_ecp_point_write_binary(&grp, &qB, MBEDTLS_ECP_PF_UNCOMPRESSED, &strlen, &strbuf[0], sizeof(strbuf)); - printf_buffer("public_key", strbuf, strlen); - - mbedtls_mpi_write_binary(&zA, shared_secret, *shared_secret_size); - PLOG_DEBUG_BUFFER("shared_secret", shared_secret, *shared_secret_size); -exit: - return status; -} - -static status_t host_derive_key(const uint8_t * input_key, size_t input_key_size, const uint8_t * derivation_data, - size_t derivation_data_size, uint32_t key_properties, uint8_t * output, size_t * output_size) -{ - status_t status = STATUS_SUCCESS; - - int ret = 0; - uint32_t counter = 1; - mbedtls_cipher_context_t ctx; - memset(&ctx, 0, sizeof(ctx)); - bool ctx_valid = false; - - assert(input_key != NULL); - assert(input_key_size == 32); - assert(derivation_data != NULL); - assert(derivation_data_size == 12); - assert(output != NULL); - assert(*output_size == 32); - - uint32_t lsbit = key_properties & 0x01; - uint32_t length_blocks = 1 + lsbit; - uint32_t length_bytes = length_blocks * AES_BLOCK_SIZE; - assert(*output_size >= length_bytes); - *output_size = length_bytes; - - // KDF in counter mode implementation as described in Section 5.1 - // of NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions - // Derivation data[191:0](sic!) = software_derivation_data[95:0] || 64'h0 || requested_ - // properties[31:0 || length[31:0] || counter[31:0] - - uint8_t dd[32] = { 0 }; - memcpy(&dd[0], derivation_data, derivation_data_size); - memset(&dd[12], 0, 8); - write_uint32_msb_first(&dd[20], key_properties); - write_uint32_msb_first(&dd[24], length_bytes * 8); // expected in bits! - write_uint32_msb_first(&dd[28], counter); - - mbedtls_cipher_type_t mbedtls_cipher_type = MBEDTLS_CIPHER_AES_256_ECB; - const mbedtls_cipher_info_t * cipher_info = mbedtls_cipher_info_from_type(mbedtls_cipher_type); - - PLOG_DEBUG_BUFFER("input_key", input_key, input_key_size); - PLOG_DEBUG_BUFFER("dd", dd, sizeof(dd)); - - uint8_t * pos = output; - do - { - mbedtls_cipher_init(&ctx); - ctx_valid = true; - - ret = mbedtls_cipher_setup(&ctx, cipher_info); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_setup failed: 0x%08x", ret); - - ret = mbedtls_cipher_cmac_starts(&ctx, input_key, input_key_size * 8); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_starts failed: 0x%08x", ret); - - ret = mbedtls_cipher_cmac_update(&ctx, dd, sizeof(dd)); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_update failed: 0x%08x", ret); - - ret = mbedtls_cipher_cmac_finish(&ctx, pos); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_finish failed: 0x%08x", ret); - - mbedtls_cipher_free(&ctx); - ctx_valid = false; - - write_uint32_msb_first(&dd[28], ++counter); - pos += AES_BLOCK_SIZE; - } while (counter * AES_BLOCK_SIZE <= length_bytes); - - PLOG_DEBUG_BUFFER("output", output, length_bytes); - -exit: - if (ctx_valid) - { - mbedtls_cipher_free(&ctx); - ctx_valid = false; - } - - return status; -} - -static status_t host_wrap_key(const uint8_t * data, size_t data_size, const uint8_t * key, size_t key_size, uint8_t * output, - size_t * output_size) -{ - status_t status = STATUS_SUCCESS; - int ret = 0; - mbedtls_nist_kw_context ctx; - mbedtls_nist_kw_init(&ctx); - ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8, true); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_nist_kw_setkey failed: 0x%08x", ret); - ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, data, data_size, output, output_size, *output_size); - RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_nist_kw_wrap failed: 0x%08x", ret); - PLOG_DEBUG_BUFFER("wrapped buffer", output, *output_size); -exit: - mbedtls_nist_kw_free(&ctx); - return status; -} - -static status_t create_els_import_keyblob(const uint8_t * plain_key, size_t plain_key_size, mcuxClEls_KeyProp_t plain_key_prop, - const uint8_t * key_wrap_in, size_t key_wrap_in_size, uint8_t * blob, size_t * blob_size) -{ - assert(plain_key_size == 16 || plain_key_size == 32); - assert(key_wrap_in_size == 16); - - uint8_t buffer[ELS_BLOB_METADATA_SIZE + MAX_ELS_KEY_SIZE] = { 0 }; - size_t buffer_size = ELS_BLOB_METADATA_SIZE + plain_key_size; - - // Enforce the wrpok bit - the key needs to be re-wrappable! - plain_key_prop.bits.wrpok = MCUXCLELS_KEYPROPERTY_WRAP_TRUE; - - // This is what ELS documentation says. It does not work though?? - // memset(&buffer[0], 0xA6, 8); - // write_uint32_msb_first(&buffer[8], plain_key_prop.word.value); - // memset(&buffer[12], 0, 4); - // memcpy(&buffer[16], plain_key, plain_key_size); - - write_uint32_msb_first(&buffer[0], plain_key_prop.word.value); - memset(&buffer[4], 0, 4); - memcpy(&buffer[8], plain_key, plain_key_size); - PLOG_DEBUG_BUFFER("plain buffer before wrapping for import", buffer, buffer_size); - - status_t status = host_wrap_key(buffer, buffer_size, key_wrap_in, key_wrap_in_size, blob, blob_size); - return status; -} - -static status_t els_perform_key_agreement(mcuxClEls_KeyIndex_t keypair_index, mcuxClEls_KeyProp_t shared_secret_prop, - mcuxClEls_KeyIndex_t * dst_key_index, const uint8_t * public_key, size_t public_key_size) -{ - uint32_t shared_secret_required_keyslots = get_required_keyslots(shared_secret_prop); - *dst_key_index = els_get_free_keyslot(shared_secret_required_keyslots); - - if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) - { - PLOG_ERROR("no free keyslot found"); - return STATUS_ERROR_GENERIC; - } - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, - mcuxClEls_EccKeyExchange_Async(keypair_index, public_key, *dst_key_index, shared_secret_prop)); - - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyExchange_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) - { - PLOG_ERROR("mcuxClEls_EccKeyExchange_Async failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); - if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) - { - PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); - return STATUS_ERROR_GENERIC; - } - MCUX_CSSL_FP_FUNCTION_CALL_END(); - - return STATUS_SUCCESS; -} - -static status_t import_plain_key_into_els(const uint8_t * plain_key, size_t plain_key_size, mcuxClEls_KeyProp_t key_properties, - mcuxClEls_KeyIndex_t * index_output) -{ - status_t status = STATUS_SUCCESS; - mcuxClEls_KeyIndex_t index_plain = MCUXCLELS_KEY_SLOTS; - mcuxClEls_KeyIndex_t index_shared_secret = MCUXCLELS_KEY_SLOTS; - mcuxClEls_KeyIndex_t index_unwrap = MCUXCLELS_KEY_SLOTS; - mcuxClEls_KeyIndex_t * potentially_used_key_indices[] = { &index_plain, &index_shared_secret, &index_unwrap }; - - uint8_t els_key_in_blob[ELS_BLOB_METADATA_SIZE + MAX_ELS_KEY_SIZE + ELS_WRAP_OVERHEAD]; - size_t els_key_in_blob_size = sizeof(els_key_in_blob); - - uint8_t shared_secret[32] = { 0 }; - size_t shared_secret_len = sizeof(shared_secret); - - uint8_t key_wrap_in[32]; - size_t key_wrap_in_size = sizeof(key_wrap_in); - - PLOG_INFO("Generating random ECC keypair..."); - uint8_t public_key[64] = { 0u }; - size_t public_key_size = sizeof(public_key); - status = els_generate_keypair(&index_plain, &public_key[0], &public_key_size); - STATUS_SUCCESS_OR_EXIT_MSG("generate_keypair failed: 0x%08x", status); - - PLOG_INFO("Calculating shared secret on host..."); - status = host_perform_key_agreement(public_key, public_key_size, &shared_secret[0], &shared_secret_len); - STATUS_SUCCESS_OR_EXIT_MSG("perform_key_agreement_host failed: 0x%08x", status); - - PLOG_INFO("Deriving wrapping key for import on host..."); - status = host_derive_key(shared_secret, shared_secret_len, ckdf_derivation_data_wrap_in, sizeof(ckdf_derivation_data_wrap_in), - wrap_in_key_prop.word.value, &key_wrap_in[0], &key_wrap_in_size); - STATUS_SUCCESS_OR_EXIT_MSG("ckdf_host failed: 0x%08x", status); - - PLOG_INFO("Creating ELS keyblob for import..."); - - status = create_els_import_keyblob(plain_key, plain_key_size, key_properties, key_wrap_in, key_wrap_in_size, - &els_key_in_blob[0], &els_key_in_blob_size); - STATUS_SUCCESS_OR_EXIT_MSG("create_els_import_keyblob failed: 0x%08x", status); - - PLOG_INFO("Calculating shared secret on ELS..."); - status = els_perform_key_agreement(index_plain, shared_secret_prop, &index_shared_secret, import_die_int_ecdh_pk, - sizeof(import_die_int_ecdh_pk)); - STATUS_SUCCESS_OR_EXIT_MSG("perform_key_agreement failed: 0x%08x", status); - - status = els_delete_key(index_plain); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - index_plain = MCUXCLELS_KEY_SLOTS; - - PLOG_INFO("Deriving wrapping key for import on ELS..."); - status = els_derive_key(index_shared_secret, wrap_in_key_prop, ckdf_derivation_data_wrap_in, &index_unwrap); - STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); - - status = els_delete_key(index_shared_secret); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - index_shared_secret = MCUXCLELS_KEY_SLOTS; - - PLOG_INFO("Importing wrapped key..."); - status = els_import_key(els_key_in_blob, els_key_in_blob_size, key_properties, index_unwrap, index_output); - STATUS_SUCCESS_OR_EXIT_MSG("import_wrapped_key failed: 0x%08x", status); - - status = els_delete_key(index_unwrap); - STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); - index_unwrap = MCUXCLELS_KEY_SLOTS; - -exit: - for (size_t i = 0; i < ARRAY_SIZE(potentially_used_key_indices); i++) - { - mcuxClEls_KeyIndex_t key_index = *(potentially_used_key_indices[i]); - if (key_index < MCUXCLELS_KEY_SLOTS) - { - (void) els_delete_key(key_index); - } - } - return status; -} - CHIP_ERROR FactoryDataProviderImpl::ELS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & addr) { + status_t status = STATUS_SUCCESS; uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; - MutableByteSpan dacPrivateKeySpan(keyBuf); uint16_t keySize = 0; - - status_t status = STATUS_SUCCESS; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&attributes, 256); - psa_set_key_lifetime( - &attributes, - PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT, PSA_KEY_LOCATION_S50_BLOB_STORAGE)); - psa_set_key_id(&attributes, 0x3E000021); + MutableByteSpan keySpan(keyBuf); /* Search key ID FactoryDataId::kDacPrivateKeyId */ - ReturnErrorOnFailure( - SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize, &addr)); - dacPrivateKeySpan.reduce_size(keySize); - PLOG_DEBUG_BUFFER("Private DAC key plain", dacPrivateKeySpan.data(), dacPrivateKeySpan.size()); - + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, keySpan.data(), keySpan.size(), keySize, &addr)); + keySpan.reduce_size(keySize); + PLOG_DEBUG_BUFFER("Private DAC key plain", keySpan.data(), keySpan.size()); mcuxClEls_KeyProp_t plain_key_properties = { .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_KGSRC } @@ -771,7 +318,7 @@ CHIP_ERROR FactoryDataProviderImpl::ELS_ExportBlob(uint8_t * data, size_t * data mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; /* Import plain DAC key into S50 */ - status = import_plain_key_into_els(dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), plain_key_properties, &key_index); + status = import_plain_key_into_els(keySpan.data(), keySpan.size(), plain_key_properties, &key_index); STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); /* ELS generate key blob. The blob created here is one that can be directly imported into ELS again. */ @@ -807,94 +354,5 @@ CHIP_ERROR FactoryDataProviderImpl::ReplaceWithBlob(uint8_t * data, uint8_t * bl return CHIP_NO_ERROR; } -#endif // CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY - -CHIP_ERROR FactoryDataProviderImpl::unittest(void) -{ -#if FACTORY_DATA_PROVIDER_RUN_TESTS - CHIP_ERROR res; - - uint8_t ecc_message[295] = { - 0x15, 0x30, 0x01, 0xec, 0x30, 0x81, 0xe9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, - 0xdb, 0x30, 0x81, 0xd8, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x02, 0x01, 0x30, 0x45, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x38, 0x04, 0x36, 0x15, - 0x24, 0x00, 0x01, 0x25, 0x01, 0x37, 0x10, 0x36, 0x02, 0x05, 0x26, 0xa2, 0x18, 0x25, 0x03, 0x01, 0x03, 0x2c, 0x04, 0x13, - 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, 0x24, - 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x01, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, - 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, 0xf3, - 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x21, 0x00, 0xc3, 0xbf, 0xd1, 0xcb, 0xed, 0x21, - 0x1e, 0x54, 0x76, 0x81, 0xa6, 0xfa, 0x08, 0x8f, 0x26, 0xce, 0x14, 0x8c, 0x72, 0xae, 0x1b, 0x6f, 0x61, 0x18, 0x0f, 0x6f, - 0x01, 0xc2, 0x75, 0xad, 0x6e, 0x5e, 0x02, 0x20, 0x31, 0x11, 0x00, 0x88, 0xcc, 0xc9, 0x98, 0x55, 0x0e, 0xf1, 0xd2, 0x42, - 0x07, 0x7a, 0xaa, 0x41, 0x0c, 0xd2, 0xd3, 0xd4, 0x76, 0xab, 0xd5, 0xaf, 0x32, 0x2c, 0x45, 0x75, 0xfa, 0xcc, 0x51, 0x5b, - 0x30, 0x02, 0x20, 0x73, 0x09, 0xbb, 0x01, 0xa5, 0xae, 0x2f, 0xfc, 0x0b, 0x7f, 0xee, 0xcb, 0xa0, 0xc4, 0x94, 0xf1, 0xd3, - 0x61, 0xce, 0x4a, 0x83, 0x21, 0x5e, 0x84, 0x07, 0xcf, 0x42, 0xc5, 0xee, 0xea, 0x1a, 0x2e, 0x24, 0x03, 0x00, 0x18, 0x90, - 0x75, 0x48, 0x87, 0x85, 0x5f, 0x73, 0xb0, 0xcb, 0x3e, 0x38, 0xa7, 0xbd, 0xad, 0x22, 0xf4 - }; - - const uint8_t kDevelopmentDAC_Cert_FFF1_8002[492] = { - 0x30, 0x82, 0x01, 0xe8, 0x30, 0x82, 0x01, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x52, 0x72, 0x4d, 0x21, 0xe2, - 0xc1, 0x74, 0xaf, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3d, 0x31, 0x25, 0x30, - 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x50, - 0x41, 0x49, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x20, 0x6e, 0x6f, 0x20, 0x50, 0x49, 0x44, 0x31, 0x14, 0x30, 0x12, - 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, - 0x17, 0x0d, 0x32, 0x32, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, - 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x44, 0x41, 0x43, 0x20, - 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x2f, 0x30, 0x78, 0x38, 0x30, 0x30, 0x32, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x31, 0x14, 0x30, 0x12, 0x06, - 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, 0x32, 0x30, 0x59, 0x30, - 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, - 0x03, 0x42, 0x00, 0x04, 0xda, 0x93, 0xf1, 0x67, 0x36, 0x25, 0x67, 0x50, 0xd9, 0x03, 0xb0, 0x34, 0xba, 0x45, 0x88, 0xab, - 0xaf, 0x58, 0x95, 0x4f, 0x77, 0xaa, 0x9f, 0xd9, 0x98, 0x9d, 0xfd, 0x40, 0x0d, 0x7a, 0xb3, 0xfd, 0xc9, 0x75, 0x3b, 0x3b, - 0x92, 0x1b, 0x29, 0x4c, 0x95, 0x0f, 0xd9, 0xd2, 0x80, 0xd1, 0x4c, 0x43, 0x86, 0x2f, 0x16, 0xdc, 0x85, 0x4b, 0x00, 0xed, - 0x39, 0xe7, 0x50, 0xba, 0xbf, 0x1d, 0xc4, 0xca, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, - 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xef, 0x06, 0x56, 0x11, 0x9c, 0x1c, 0x91, - 0xa7, 0x9a, 0x94, 0xe6, 0xdc, 0xf3, 0x79, 0x79, 0xdb, 0xd0, 0x7f, 0xf8, 0xa3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, - 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x63, 0x54, 0x0e, 0x47, 0xf6, 0x4b, 0x1c, 0x38, 0xd1, 0x38, 0x84, 0xa4, 0x62, 0xd1, - 0x6c, 0x19, 0x5d, 0x8f, 0xfb, 0x3c, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, - 0x00, 0x30, 0x45, 0x02, 0x20, 0x46, 0x86, 0x81, 0x07, 0x33, 0xbf, 0x0d, 0xc8, 0xff, 0x4c, 0xb5, 0x14, 0x5a, 0x6b, 0xfa, - 0x1a, 0xec, 0xff, 0xa8, 0xb6, 0xda, 0xb6, 0xc3, 0x51, 0xaa, 0xee, 0xcd, 0xaf, 0xb8, 0xbe, 0x95, 0x7d, 0x02, 0x21, 0x00, - 0xe8, 0xc2, 0x8d, 0x6b, 0xfc, 0xc8, 0x7a, 0x7d, 0x54, 0x2e, 0xad, 0x6e, 0xda, 0xca, 0x14, 0x8d, 0x5f, 0xa5, 0x06, 0x1e, - 0x51, 0x7c, 0xbe, 0x4f, 0x24, 0xa7, 0x20, 0xe1, 0xc0, 0x59, 0xde, 0x1a, - }; - const uint8_t kDevelopmentDAC_PublicKey_FFF1_8002[65] = { - 0x04, 0xda, 0x93, 0xf1, 0x67, 0x36, 0x25, 0x67, 0x50, 0xd9, 0x03, 0xb0, 0x34, 0xba, 0x45, 0x88, 0xab, - 0xaf, 0x58, 0x95, 0x4f, 0x77, 0xaa, 0x9f, 0xd9, 0x98, 0x9d, 0xfd, 0x40, 0x0d, 0x7a, 0xb3, 0xfd, 0xc9, - 0x75, 0x3b, 0x3b, 0x92, 0x1b, 0x29, 0x4c, 0x95, 0x0f, 0xd9, 0xd2, 0x80, 0xd1, 0x4c, 0x43, 0x86, 0x2f, - 0x16, 0xdc, 0x85, 0x4b, 0x00, 0xed, 0x39, 0xe7, 0x50, 0xba, 0xbf, 0x1d, 0xc4, 0xca, - }; - - /* Sign using the example attestation private key */ - P256ECDSASignature da_signature; - MutableByteSpan out_sig_span(da_signature.Bytes(), da_signature.Capacity()); - CHIP_ERROR err = SignWithDacKey(ByteSpan{ ecc_message, sizeof(ecc_message) }, out_sig_span); - assert(err == CHIP_NO_ERROR); - - assert(out_sig_span.size() == kP256_ECDSA_Signature_Length_Raw); - da_signature.SetLength(out_sig_span.size()); - - /* Get DAC from the provider */ - uint8_t dac_cert_buf[kMaxDERCertLength]; - MutableByteSpan dac_cert_span(dac_cert_buf); - - memcpy(dac_cert_span.data(), kDevelopmentDAC_Cert_FFF1_8002, 492); - - /* Extract public key from DAC, prior to signature verification */ - P256PublicKey dac_public_key; - err = ExtractPubkeyFromX509Cert(dac_cert_span, dac_public_key); - assert(err == CHIP_NO_ERROR); - assert(dac_public_key.Length() == 65); - assert(0 == memcmp(dac_public_key.ConstBytes(), kDevelopmentDAC_PublicKey_FFF1_8002, 65)); - - /* Verify round trip signature */ - err = dac_public_key.ECDSA_validate_msg_signature(&ecc_message[0], sizeof(ecc_message), da_signature); - assert(err == CHIP_NO_ERROR); - PRINTF("ECDSA signature validated with SUCCESS \n"); -#endif - return CHIP_NO_ERROR; -} - } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h index 43a759fa8ee15c..4fc4785328aaf4 100644 --- a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h @@ -57,12 +57,12 @@ class FactoryDataProviderImpl : public FactoryDataProvider /* TLV offset */ static constexpr uint32_t kLengthOffset = 1; static constexpr uint32_t kValueOffset = 3; - CHIP_ERROR Hash256(const uint8_t * input, size_t inputSize, uint8_t * output); - CHIP_ERROR unittest(void); CHIP_ERROR ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset); CHIP_ERROR ELS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset); CHIP_ERROR ELS_ConvertDacKey(); + + CHIP_ERROR ReadAndCheckFactoryDataInFlash(void); }; inline FactoryDataProvider & FactoryDataPrvd() diff --git a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp index 085a10ea5f5fa3..c17e7df36c616c 100644 --- a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp +++ b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp @@ -112,7 +112,6 @@ void PlatformManagerImpl::HardwareInit(void) CHIP_ERROR PlatformManagerImpl::ServiceInit(void) { status_t status; - hal_rng_status_t rngStatus; CHIP_ERROR chipRes = CHIP_NO_ERROR; status = CRYPTO_InitHardware(); @@ -196,9 +195,6 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) err = ServiceInit(); SuccessOrExit(err); -#ifdef SPINEL_INTERFACE_RPMSG - otPlatRadioInitSpinelInterface(); -#endif /* SPINEL_INTERFACE_RPMSG */ PLATFORM_InitOt(); /* * Initialize the RCP here: the WiFi initialization requires to enable/disable @@ -211,7 +207,7 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) #endif #if CHIP_DEVICE_CONFIG_ENABLE_WPA - osError = os_setup_idle_function(chip::DeviceLayer::PlatformManagerImpl::IdleHook); + osError = OSA_SetupIdleFunction(chip::DeviceLayer::PlatformManagerImpl::IdleHook); if (osError != WM_SUCCESS) { ChipLogError(DeviceLayer, "Failed to setup idle function"); diff --git a/src/platform/nxp/rt/rw61x/args.gni b/src/platform/nxp/rt/rw61x/args.gni index 0c2d183aca8646..5561196ea3a323 100644 --- a/src/platform/nxp/rt/rw61x/args.gni +++ b/src/platform/nxp/rt/rw61x/args.gni @@ -42,12 +42,6 @@ declare_args() { # if rw610_mbedtls_port_els_pkc is set to false software mbedtls is used instead rw610_mbedtls_port_els_pkc = true - - # Enable DAC private key secure usage, chip_with_factory_data must be set to 1 - chip_enable_secure_dac_private_key_storage = 0 - - # Generate DAC private key blob for factory data, chip_enable_secure_dac_private_key_storage must be set to 1 - chip_convert_dac_private_key = 0 } # TODO : Enable the OTA Requestor by default. @@ -60,6 +54,10 @@ declare_args() { no_mcuboot = true } +# By default nxp_nvm_component is set to "littlefs" in nxp_sdk.gni, +# here we override it to set it to "nvs" for RW61x platform +nxp_nvm_component = "nvs" + mbedtls_target = "${nxp_sdk_build_root}:nxp_mbedtls" openthread_external_mbedtls = mbedtls_target diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index 2aad9239944047..f6329bb2280c8b 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit 2aad9239944047012e525caf52119a5c84b704d3 +Subproject commit f6329bb2280c8bc3f50f6d39e79191499e67cffa diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index f45fe4dd8687f0..0a3248f5c8ec5a 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit f45fe4dd8687f0feddf063a33214c2196b463d3e +Subproject commit 0a3248f5c8ec5a9fd05541974872323f26d5182f diff --git a/third_party/openthread/platforms/nxp/k32w1/BUILD.gn b/third_party/openthread/platforms/nxp/mcxw71_k32w1/BUILD.gn similarity index 93% rename from third_party/openthread/platforms/nxp/k32w1/BUILD.gn rename to third_party/openthread/platforms/nxp/mcxw71_k32w1/BUILD.gn index 38a2f231cb811c..b7dc6d35983c40 100644 --- a/third_party/openthread/platforms/nxp/k32w1/BUILD.gn +++ b/third_party/openthread/platforms/nxp/mcxw71_k32w1/BUILD.gn @@ -80,14 +80,14 @@ source_set("libopenthread-k32w1") { ] if (chip_crypto == "platform") { - sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/ecdsa_sss.cpp" ] + sources += [ "${openthread_nxp_root}/src/common/crypto/ecdsa_sss.cpp" ] if (use_hw_sha256) { - sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/sha256_sss.cpp" ] + sources += [ "${openthread_nxp_root}/src/common/crypto/sha256_sss.cpp" ] } if (use_hw_aes) { - sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/aes_sss.cpp" ] + sources += [ "${openthread_nxp_root}/src/common/crypto/aes_sss.cpp" ] } if (chip_key_storage == "fwk_nvm") { diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index c8054103122357..6d4854f53a9160 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -43,21 +43,24 @@ config("openthread_rw61x_config") { "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1", "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1", "OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE=1", - "OPENTHREAD_CONFIG_MDNS_SERVER_ENABLE=1", "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1", "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1", "OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS=3", "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1", "OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE=1", "OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE=1", - "OT_APP_BR_LWIP_HOOKS_EN=1", "OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE=1", + "OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF=0", + "OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1", + "OT_APP_BR_LWIP_HOOKS_EN=1", ] } + # ot cli configs - defines += [ - "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1" - ] + defines += [ "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1" ] } #Config used by the openthread stack to get the path to OpenthreadConfig.h @@ -70,9 +73,9 @@ source_set("libopenthread-rw61x") { deps = [] sources = [ "${openthread_nxp_root}/src/common/alarm_freertos.c", + "${openthread_nxp_root}/src/common/diag.c", + "${openthread_nxp_root}/src/common/entropy.c", "${openthread_nxp_root}/src/common/logging.c", - "${openthread_nxp_root}/src/rw/rw612/platform/diag.c", - "${openthread_nxp_root}/src/rw/rw612/platform/entropy.c", ] if (chip_enable_wifi && chip_enable_openthread) { @@ -82,7 +85,9 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/common/br/infra_if.c", "${openthread_nxp_root}/src/common/br/lwip_hooks.c", "${openthread_nxp_root}/src/common/br/lwip_mcast.c", + "${openthread_nxp_root}/src/common/br/mdns_socket.c", "${openthread_nxp_root}/src/common/br/udp_plat.c", + "${openthread_nxp_root}/src/common/br/utils.c", ] deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] } @@ -93,6 +98,7 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/common/spinel/spinel_hdlc.cpp", "${openthread_nxp_root}/src/common/spinel/system.c", "${openthread_root}/src/lib/hdlc/hdlc.cpp", + "${openthread_root}/src/lib/url/url.cpp", ] } else { sources += [ @@ -102,12 +108,14 @@ source_set("libopenthread-rw61x") { ] } - if (rt_nvm_component == "nvm_fwk") { + if (nxp_nvm_component == "nvm_fwk") { sources += [ "${openthread_nxp_root}/src/common/flash_nvm.c" ] - } else if (rt_nvm_component == "littlefs") { + } else if (nxp_nvm_component == "littlefs") { sources += [ "${openthread_nxp_root}/src/common/flash_littlefs.c" ] - } else if (rt_nvm_component == "key_storage") { + } else if (nxp_nvm_component == "key_storage") { sources += [ "${openthread_nxp_root}/src/common/flash_fsa.c" ] + } else if (nxp_nvm_component == "nvs") { + sources += [ "${openthread_nxp_root}/src/common/flash_nvs.c" ] } defines = [ From ee6a1e2475f797579397c2ff39dac3f331f2f453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 3 Sep 2024 17:03:19 +0200 Subject: [PATCH 14/70] [Chef] Add Water Leak Detector (#35217) * [Chef] Add Water Leak Detector * Update rootnode_waterleakdetector_0b067acfa3.matter --- ...otnode_waterleakdetector_0b067acfa3.matter | 1857 ++++++++++ .../rootnode_waterleakdetector_0b067acfa3.zap | 3137 +++++++++++++++++ .../sample_app_util/matter_device_types.json | 3 +- 3 files changed, 4996 insertions(+), 1 deletion(-) create mode 100644 examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter create mode 100644 examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter new file mode 100644 index 00000000000000..a75da3800cd9de --- /dev/null +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter @@ -0,0 +1,1857 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRestroom = 73; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; +} + +enum AtomicRequestTypeEnum : enum8 { + kBeginWrite = 0; + kCommitWrite = 1; + kRollbackWrite = 2; +} + +enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; +} + +enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; +} + +enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; +} + +enum RelativePositionTag : enum8 { + kUnder = 0; + kNextTo = 1; + kAround = 2; + kOn = 3; + kAbove = 4; + kFrontOf = 5; + kBehind = 6; +} + +enum TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + +struct AtomicAttributeStatusStruct { + attrib_id attributeID = 0; + status statusCode = 1; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** Attributes and commands for group configuration and manipulation. */ +cluster Groups = 4 { + revision 4; + + bitmap Feature : bitmap32 { + kGroupNames = 0x1; + } + + bitmap NameSupportBitmap : bitmap8 { + kGroupNames = 0x80; + } + + readonly attribute NameSupportBitmap nameSupport = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddGroupRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + response struct AddGroupResponse = 0 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct ViewGroupRequest { + group_id groupID = 0; + } + + response struct ViewGroupResponse = 1 { + enum8 status = 0; + group_id groupID = 1; + char_string<16> groupName = 2; + } + + request struct GetGroupMembershipRequest { + group_id groupList[] = 0; + } + + response struct GetGroupMembershipResponse = 2 { + nullable int8u capacity = 0; + group_id groupList[] = 1; + } + + request struct RemoveGroupRequest { + group_id groupID = 0; + } + + response struct RemoveGroupResponse = 3 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct AddGroupIfIdentifyingRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + /** Command description for AddGroup */ + fabric command access(invoke: manage) AddGroup(AddGroupRequest): AddGroupResponse = 0; + /** Command description for ViewGroup */ + fabric command ViewGroup(ViewGroupRequest): ViewGroupResponse = 1; + /** Command description for GetGroupMembership */ + fabric command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; + /** Command description for RemoveGroup */ + fabric command access(invoke: manage) RemoveGroup(RemoveGroupRequest): RemoveGroupResponse = 3; + /** Command description for RemoveAllGroups */ + fabric command access(invoke: manage) RemoveAllGroups(): DefaultSuccess = 4; + /** Command description for AddGroupIfIdentifying */ + fabric command access(invoke: manage) AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 2; + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing common languages, units of measurements, and numerical formatting + standards. As such, Nodes that visually or audibly convey information need a mechanism by which + they can be configured to use a user’s preferred language, units, etc */ +cluster LocalizationConfiguration = 43 { + revision 1; // NOTE: Default/not specifically set + + attribute access(write: manage) char_string<35> activeLocale = 0; + readonly attribute char_string supportedLocales[] = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + provisional readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + provisional readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + provisional readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 1; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** This cluster provides an interface to a boolean state called StateValue. */ +cluster BooleanState = 69 { + revision 1; + + info event StateChange = 0 { + boolean stateValue = 0; + } + + readonly attribute boolean stateValue = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Attributes and commands for scene configuration and manipulation. */ +provisional cluster ScenesManagement = 98 { + revision 1; + + bitmap CopyModeBitmap : bitmap8 { + kCopyAllScenes = 0x1; + } + + bitmap Feature : bitmap32 { + kSceneNames = 0x1; + } + + struct AttributeValuePairStruct { + attrib_id attributeID = 0; + optional int8u valueUnsigned8 = 1; + optional int8s valueSigned8 = 2; + optional int16u valueUnsigned16 = 3; + optional int16s valueSigned16 = 4; + optional int32u valueUnsigned32 = 5; + optional int32s valueSigned32 = 6; + optional int64u valueUnsigned64 = 7; + optional int64s valueSigned64 = 8; + } + + struct ExtensionFieldSet { + cluster_id clusterID = 0; + AttributeValuePairStruct attributeValueList[] = 1; + } + + fabric_scoped struct SceneInfoStruct { + int8u sceneCount = 0; + fabric_sensitive int8u currentScene = 1; + fabric_sensitive group_id currentGroup = 2; + fabric_sensitive boolean sceneValid = 3; + int8u remainingCapacity = 4; + fabric_idx fabricIndex = 254; + } + + readonly attribute optional nullable node_id lastConfiguredBy = 0; + readonly attribute int16u sceneTableSize = 1; + readonly attribute SceneInfoStruct fabricSceneInfo[] = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + int32u transitionTime = 2; + char_string sceneName = 3; + ExtensionFieldSet extensionFieldSets[] = 4; + } + + response struct AddSceneResponse = 0 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct ViewSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct ViewSceneResponse = 1 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + optional int32u transitionTime = 3; + optional char_string sceneName = 4; + optional ExtensionFieldSet extensionFieldSets[] = 5; + } + + request struct RemoveSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct RemoveSceneResponse = 2 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct RemoveAllScenesRequest { + group_id groupID = 0; + } + + response struct RemoveAllScenesResponse = 3 { + status status = 0; + group_id groupID = 1; + } + + request struct StoreSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct StoreSceneResponse = 4 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct RecallSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + optional nullable int32u transitionTime = 2; + } + + request struct GetSceneMembershipRequest { + group_id groupID = 0; + } + + response struct GetSceneMembershipResponse = 6 { + status status = 0; + nullable int8u capacity = 1; + group_id groupID = 2; + optional int8u sceneList[] = 3; + } + + request struct CopySceneRequest { + CopyModeBitmap mode = 0; + group_id groupIdentifierFrom = 1; + int8u sceneIdentifierFrom = 2; + group_id groupIdentifierTo = 3; + int8u sceneIdentifierTo = 4; + } + + response struct CopySceneResponse = 64 { + status status = 0; + group_id groupIdentifierFrom = 1; + int8u sceneIdentifierFrom = 2; + } + + /** Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' */ + fabric command access(invoke: manage) AddScene(AddSceneRequest): AddSceneResponse = 0; + /** Retrieves the requested scene entry from its Scene table. */ + fabric command ViewScene(ViewSceneRequest): ViewSceneResponse = 1; + /** Removes the requested scene entry, corresponding to the value of the GroupID field, from its Scene Table */ + fabric command access(invoke: manage) RemoveScene(RemoveSceneRequest): RemoveSceneResponse = 2; + /** Remove all scenes, corresponding to the value of the GroupID field, from its Scene Table */ + fabric command access(invoke: manage) RemoveAllScenes(RemoveAllScenesRequest): RemoveAllScenesResponse = 3; + /** Adds the scene entry into its Scene Table along with all extension field sets corresponding to the current state of other clusters on the same endpoint */ + fabric command access(invoke: manage) StoreScene(StoreSceneRequest): StoreSceneResponse = 4; + /** Set the attributes and corresponding state for each other cluster implemented on the endpoint accordingly to the resquested scene entry in the Scene Table */ + fabric command RecallScene(RecallSceneRequest): DefaultSuccess = 5; + /** Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group */ + fabric command GetSceneMembership(GetSceneMembershipRequest): GetSceneMembershipResponse = 6; + /** Allows a client to efficiently copy scenes from one group/scene identifier pair to another group/scene identifier pair. */ + fabric command CopyScene(CopySceneRequest): CopySceneResponse = 64; +} + +/** This cluster is used to configure a boolean sensor. */ +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; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + } + + server cluster LocalizationConfiguration { + ram attribute activeLocale; + callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 0x0001; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + handle command RetrieveLogsResponse; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command OpenCommissioningWindow; + handle command OpenBasicCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } +} +endpoint 1 { + device type ma_water_leak_detector = 67, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Groups { + ram attribute nameSupport; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + + handle command AddGroup; + handle command AddGroupResponse; + handle command ViewGroup; + handle command ViewGroupResponse; + handle command GetGroupMembership; + handle command GetGroupMembershipResponse; + handle command RemoveGroup; + handle command RemoveGroupResponse; + handle command RemoveAllGroups; + handle command AddGroupIfIdentifying; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster BooleanState { + ram attribute stateValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster ScenesManagement { + ram attribute lastConfiguredBy; + ram attribute sceneTableSize; + callback attribute fabricSceneInfo; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 6; + + handle command AddScene; + handle command AddSceneResponse; + handle command ViewScene; + handle command ViewSceneResponse; + handle command RemoveScene; + handle command RemoveSceneResponse; + handle command RemoveAllScenes; + handle command RemoveAllScenesResponse; + handle command StoreScene; + handle command StoreSceneResponse; + handle command RecallScene; + handle command GetSceneMembership; + handle command GetSceneMembershipResponse; + } + + server cluster BooleanStateConfiguration { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } +} + + diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap new file mode 100644 index 00000000000000..dad5608b6c6384 --- /dev/null +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap @@ -0,0 +1,3137 @@ +{ + "fileFormat": 2, + "featureLevel": 103, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "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": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OpenBasicCommissioningWindow", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 67, + "profileId": 259, + "label": "MA-water-leak-detector", + "name": "MA-water-leak-detector" + }, + "deviceTypes": [ + { + "code": 67, + "profileId": 259, + "label": "MA-water-leak-detector", + "name": "MA-water-leak-detector" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 67 + ], + "deviceTypeName": "MA-water-leak-detector", + "deviceTypeCode": 67, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NameSupport", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "NameSupportBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State", + "code": 69, + "mfgCode": null, + "define": "BOOLEAN_STATE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "StateValue", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes Management", + "code": 98, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "AddScene", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddSceneResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewScene", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewSceneResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveScene", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveSceneResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllScenes", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveAllScenesResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StoreScene", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StoreSceneResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RecallScene", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetSceneMembership", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetSceneMembershipResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "LastConfiguredBy", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "node_id", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SceneTableSize", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FabricSceneInfo", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "6", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State Configuration", + "code": 128, + "mfgCode": null, + "define": "BOOLEAN_STATE_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": 0 + } + ] +} \ No newline at end of file diff --git a/examples/chef/sample_app_util/matter_device_types.json b/examples/chef/sample_app_util/matter_device_types.json index d1c61db86ffc40..e8ed949033d41f 100644 --- a/examples/chef/sample_app_util/matter_device_types.json +++ b/examples/chef/sample_app_util/matter_device_types.json @@ -48,5 +48,6 @@ "Laundry Washer": 115, "Robotic Vacuum Cleaner": 116, "Dishwasher": 117, - "Smoke CO Alarm": 118 + "Smoke CO Alarm": 118, + "Water Leak Detector": 67 } From e79c277158a48fee0c7e0bb0203df6a602f5840c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 3 Sep 2024 17:04:31 +0200 Subject: [PATCH 15/70] Update template.zap (#35219) Fix warnings --- examples/chef/devices/template.zap | 180 ++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 1 deletion(-) diff --git a/examples/chef/devices/template.zap b/examples/chef/devices/template.zap index c722acbb13e59e..c0bc9ae53991a6 100644 --- a/examples/chef/devices/template.zap +++ b/examples/chef/devices/template.zap @@ -633,6 +633,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -690,6 +722,144 @@ } ] }, + { + "name": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "General Commissioning", "code": 48, @@ -1121,6 +1291,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ @@ -2728,4 +2906,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} From 5ffb598a9cb73b1a662e646d394e599dea320332 Mon Sep 17 00:00:00 2001 From: William Date: Tue, 3 Sep 2024 16:04:57 +0100 Subject: [PATCH 16/70] Create memory delegate (#35176) * Created a memory delegate in service area cluster server. * Added supported areas and supported maps Remove methods to the MemoryDelegate and the Instance. * Added selected areas and progress Remove methods to the MemoryDelegate and the Instance. * Moved the `HandleSupportedAreasUpdated` into the server. * Updated the RVC example app according to the latest changes. * Added the suffix Raw to unsanitary methods in the MemoryDelegate. * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Removed unused variables * Restyled by clang-format * Added a readme for the service area cluster. * Restyled by prettier-markdown * Renamed MemoryDelegate to StorageDelegate. * Added documentation noting how to handle MutableCharSpan out params to avoid memory leaks * Restyled by clang-format * Restyled by prettier-markdown * restarting restyler. * Added missed untraced files. * Restyled by clang-format * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Restyled by clang-format --------- Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- examples/rvc-app/linux/BUILD.gn | 1 + .../rvc-app/rvc-common/include/rvc-device.h | 4 +- .../include/rvc-service-area-delegate.h | 78 --- .../rvc-service-area-storage-delegate.h | 113 +++++ .../rvc-app/rvc-common/src/rvc-device.cpp | 6 +- .../src/rvc-service-area-delegate.cpp | 459 +----------------- .../src/rvc-service-area-storage-delegate.cpp | 393 +++++++++++++++ src/app/chip_data_model.gni | 3 +- .../clusters/service-area-server/README.md | 35 ++ .../service-area-cluster-objects.h | 9 +- .../service-area-delegate.h | 243 +--------- .../service-area-server.cpp | 355 +++++++++++--- .../service-area-server/service-area-server.h | 135 +++++- ....cpp => service-area-storage-delegate.cpp} | 43 +- .../service-area-storage-delegate.h | 280 +++++++++++ 15 files changed, 1291 insertions(+), 866 deletions(-) create mode 100644 examples/rvc-app/rvc-common/include/rvc-service-area-storage-delegate.h create mode 100644 examples/rvc-app/rvc-common/src/rvc-service-area-storage-delegate.cpp create mode 100644 src/app/clusters/service-area-server/README.md rename src/app/clusters/service-area-server/{service-area-delegate.cpp => service-area-storage-delegate.cpp} (56%) create mode 100644 src/app/clusters/service-area-server/service-area-storage-delegate.h diff --git a/examples/rvc-app/linux/BUILD.gn b/examples/rvc-app/linux/BUILD.gn index 0adb4e9c9ae8e9..797e219abe3470 100644 --- a/examples/rvc-app/linux/BUILD.gn +++ b/examples/rvc-app/linux/BUILD.gn @@ -28,6 +28,7 @@ executable("chip-rvc-app") { "${chip_root}/examples/rvc-app/rvc-common/src/rvc-mode-delegates.cpp", "${chip_root}/examples/rvc-app/rvc-common/src/rvc-operational-state-delegate.cpp", "${chip_root}/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp", + "${chip_root}/examples/rvc-app/rvc-common/src/rvc-service-area-storage-delegate.cpp", "RvcAppCommandDelegate.cpp", "include/CHIPProjectAppConfig.h", "main.cpp", diff --git a/examples/rvc-app/rvc-common/include/rvc-device.h b/examples/rvc-app/rvc-common/include/rvc-device.h index e2011f6c83e196..fd9ecf25e76376 100644 --- a/examples/rvc-app/rvc-common/include/rvc-device.h +++ b/examples/rvc-app/rvc-common/include/rvc-device.h @@ -3,6 +3,7 @@ #include "rvc-mode-delegates.h" #include "rvc-operational-state-delegate.h" #include "rvc-service-area-delegate.h" +#include "rvc-service-area-storage-delegate.h" #include #include #include @@ -27,6 +28,7 @@ class RvcDevice RvcOperationalState::Instance mOperationalStateInstance; ServiceArea::RvcServiceAreaDelegate mServiceAreaDelegate; + ServiceArea::RvcServiceAreaStorageDelegate mStorageDelegate; ServiceArea::Instance mServiceAreaInstance; bool mDocked = false; @@ -44,7 +46,7 @@ class RvcDevice mRunModeDelegate(), mRunModeInstance(&mRunModeDelegate, aRvcClustersEndpoint, RvcRunMode::Id, 0), mCleanModeDelegate(), mCleanModeInstance(&mCleanModeDelegate, aRvcClustersEndpoint, RvcCleanMode::Id, 0), mOperationalStateDelegate(), mOperationalStateInstance(&mOperationalStateDelegate, aRvcClustersEndpoint), mServiceAreaDelegate(), - mServiceAreaInstance(&mServiceAreaDelegate, aRvcClustersEndpoint, + mServiceAreaInstance(&mStorageDelegate, &mServiceAreaDelegate, aRvcClustersEndpoint, BitMask(ServiceArea::Feature::kMaps, ServiceArea::Feature::kProgressReporting)) { // set the current-mode at start-up diff --git a/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h b/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h index a87d345cb506ba..12c86bb9d6e077 100644 --- a/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h +++ b/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h @@ -38,12 +38,6 @@ namespace ServiceArea { class RvcServiceAreaDelegate : public Delegate { private: - // containers for array attributes. - std::vector mSupportedAreas; - std::vector mSupportedMaps; - std::vector mSelectedAreas; - std::vector mProgressList; - RvcDevice * mIsSetSelectedAreasAllowedDeviceInstance; IsSetSelectedAreasAllowedCallback mIsSetSelectedAreasAllowedCallback; RvcDevice * mHandleSkipAreaDeviceInstance; @@ -84,82 +78,10 @@ class RvcServiceAreaDelegate : public Delegate bool HandleSkipArea(uint32_t skippedArea, MutableCharSpan & skipStatusText) override; - //************************************************************************* - // Supported Areas accessors - bool IsSupportedAreasChangeAllowed() override; - uint32_t GetNumberOfSupportedAreas() override; - - bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & supportedArea) override; - - bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & supportedArea) override; - - bool AddSupportedArea(const AreaStructureWrapper & newArea, uint32_t & listIndex) override; - - bool ModifySupportedArea(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) override; - - bool ClearSupportedAreas() override; - - /** - * This is a more sophisticated way of ensuring that we all attributes are still valid when a supported area is removed. - * Rather than clearing all the attributes that depend on the supported aeras, we only remove the elements that point to - * the removed supported areas. - */ - void HandleSupportedAreasUpdated() override; - - /** - * Note: Call the HandleSupportedAreasUpdated() method when finished removing supported areas. - */ - bool RemoveSupportedArea(uint32_t areaId); - - //************************************************************************* - // Supported Maps accessors - bool IsSupportedMapChangeAllowed() override; - uint32_t GetNumberOfSupportedMaps() override; - - bool GetSupportedMapByIndex(uint32_t listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; - - bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; - - bool AddSupportedMap(const ServiceArea::MapStructureWrapper & newMap, uint32_t & listIndex) override; - - bool ModifySupportedMap(uint32_t listIndex, const ServiceArea::MapStructureWrapper & newMap) override; - - bool ClearSupportedMaps() override; - - bool RemoveSupportedMap(uint32_t mapId); - - //************************************************************************* - // Selected Areas accessors - - uint32_t GetNumberOfSelectedAreas() override; - - bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) override; - - bool AddSelectedArea(uint32_t aAreaId, uint32_t & listIndex) override; - - bool ClearSelectedAreas() override; - - //************************************************************************* - // Progress accessors - - uint32_t GetNumberOfProgressElements() override; - - bool GetProgressElementByIndex(uint32_t listIndex, ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; - - bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, - ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; - - bool AddProgressElement(const ServiceArea::Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) override; - - bool ModifyProgressElement(uint32_t listIndex, - const ServiceArea::Structs::ProgressStruct::Type & modifiedProgressElement) override; - - bool ClearProgress() override; - //************************************************************************* // RVC device callback setters diff --git a/examples/rvc-app/rvc-common/include/rvc-service-area-storage-delegate.h b/examples/rvc-app/rvc-common/include/rvc-service-area-storage-delegate.h new file mode 100644 index 00000000000000..b1502581edf03a --- /dev/null +++ b/examples/rvc-app/rvc-common/include/rvc-service-area-storage-delegate.h @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +class RvcDevice; + +namespace ServiceArea { + +class RvcServiceAreaStorageDelegate : public StorageDelegate +{ +private: + // containers for array attributes. + std::vector mSupportedAreas; + std::vector mSupportedMaps; + std::vector mSelectedAreas; + std::vector mProgressList; + +public: + //************************************************************************* + // Supported Areas accessors + + uint32_t GetNumberOfSupportedAreas() override; + + bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & supportedArea) override; + + bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & supportedArea) override; + + bool AddSupportedAreaRaw(const AreaStructureWrapper & newArea, uint32_t & listIndex) override; + + bool ModifySupportedAreaRaw(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) override; + + bool ClearSupportedAreasRaw() override; + + bool RemoveSupportedAreaRaw(uint32_t areaId) override; + + //************************************************************************* + // Supported Maps accessors + + uint32_t GetNumberOfSupportedMaps() override; + + bool GetSupportedMapByIndex(uint32_t listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; + + bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; + + bool AddSupportedMapRaw(const MapStructureWrapper & newMap, uint32_t & listIndex) override; + + bool ModifySupportedMapRaw(uint32_t listIndex, const MapStructureWrapper & newMap) override; + + bool ClearSupportedMapsRaw() override; + + bool RemoveSupportedMapRaw(uint32_t mapId) override; + + //************************************************************************* + // Selected Areas accessors + + uint32_t GetNumberOfSelectedAreas() override; + + bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) override; + + bool AddSelectedAreaRaw(uint32_t aAreaId, uint32_t & listIndex) override; + + bool ClearSelectedAreasRaw() override; + + bool RemoveSelectedAreasRaw(uint32_t areaId) override; + + //************************************************************************* + // Progress accessors + + uint32_t GetNumberOfProgressElements() override; + + bool GetProgressElementByIndex(uint32_t listIndex, ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; + + bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, + ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; + + bool AddProgressElementRaw(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) override; + + bool ModifyProgressElementRaw(uint32_t listIndex, const Structs::ProgressStruct::Type & modifiedProgressElement) override; + + bool ClearProgressRaw() override; + + bool RemoveProgressElementRaw(uint32_t areaId) override; +}; + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/rvc-app/rvc-common/src/rvc-device.cpp b/examples/rvc-app/rvc-common/src/rvc-device.cpp index dac7db9e43708e..88b8095ddf8bdd 100644 --- a/examples/rvc-app/rvc-common/src/rvc-device.cpp +++ b/examples/rvc-app/rvc-common/src/rvc-device.cpp @@ -339,12 +339,12 @@ void RvcDevice::HandleAddServiceAreaArea(ServiceArea::AreaStructureWrapper & are void RvcDevice::HandleRemoveServiceAreaMap(uint32_t mapId) { - mServiceAreaDelegate.RemoveSupportedMap(mapId); + mServiceAreaInstance.RemoveSupportedMap(mapId); } void RvcDevice::HandleRemoveServiceAreaArea(uint32_t areaId) { - mServiceAreaDelegate.RemoveSupportedArea(areaId); + mServiceAreaInstance.RemoveSupportedArea(areaId); } void RvcDevice::HandleErrorEvent(const std::string & error) @@ -439,7 +439,7 @@ void RvcDevice::UpdateServiceAreaProgressOnExit() uint32_t i = 0; ServiceArea::Structs::ProgressStruct::Type progressElement; - while (mServiceAreaDelegate.GetProgressElementByIndex(i, progressElement)) + while (mServiceAreaInstance.GetProgressElementByIndex(i, progressElement)) { if (progressElement.status == ServiceArea::OperationalStatusEnum::kOperating || progressElement.status == ServiceArea::OperationalStatusEnum::kPending) diff --git a/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp b/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp index 2f2594e17d7686..b46206ec50ee75 100644 --- a/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp +++ b/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp @@ -122,7 +122,7 @@ bool RvcServiceAreaDelegate::IsValidSelectAreasSet(const Span & } // If there is 1 or 0 supported maps, any combination of areas is valid. - if (!GetInstance()->HasFeature(Feature::kMaps) || GetNumberOfSupportedMaps() <= 1) + if (!GetInstance()->HasFeature(Feature::kMaps) || GetInstance()->GetNumberOfSupportedMaps() <= 1) { return true; } @@ -131,7 +131,7 @@ bool RvcServiceAreaDelegate::IsValidSelectAreasSet(const Span & { AreaStructureWrapper tempArea; uint32_t ignoredIndex; - if (!GetSupportedAreaById(selectedAreas[0], ignoredIndex, tempArea)) + if (!GetInstance()->GetSupportedAreaById(selectedAreas[0], ignoredIndex, tempArea)) { areaStatus = SelectAreasStatus::kUnsupportedArea; CopyCharSpanToMutableCharSpan("unable to find selected area in supported areas"_span, statusText); @@ -142,7 +142,7 @@ bool RvcServiceAreaDelegate::IsValidSelectAreasSet(const Span & for (const auto & areaId : selectedAreas.SubSpan(1)) { - if (!GetSupportedAreaById(areaId, ignoredIndex, tempArea)) + if (!GetInstance()->GetSupportedAreaById(areaId, ignoredIndex, tempArea)) { areaStatus = SelectAreasStatus::kUnsupportedArea; CopyCharSpanToMutableCharSpan("unable to find selected area in supported areas"_span, statusText); @@ -166,460 +166,27 @@ bool RvcServiceAreaDelegate::HandleSkipArea(uint32_t skippedArea, MutableCharSpa return (mHandleSkipAreaDeviceInstance->*mHandleSkipAreaCallback)(skippedArea, skipStatusText); }; -//************************************************************************* -// Supported Areas accessors - bool RvcServiceAreaDelegate::IsSupportedAreasChangeAllowed() { return (mIsSupportedAreasChangeAllowedDeviceInstance->*mIsSupportedAreasChangeAllowedCallback)(); } -uint32_t RvcServiceAreaDelegate::GetNumberOfSupportedAreas() -{ - return static_cast(mSupportedAreas.size()); -} - -bool RvcServiceAreaDelegate::GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & supportedArea) -{ - if (listIndex < mSupportedAreas.size()) - { - supportedArea = mSupportedAreas[listIndex]; - return true; - } - - return false; -}; - -bool RvcServiceAreaDelegate::GetSupportedAreaById(uint32_t aAreaID, uint32_t & listIndex, AreaStructureWrapper & supportedArea) -{ - // We do not need to reimplement this method as it's already done by the SDK. - // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation - // since we have direct access to the list. - listIndex = 0; - - while (listIndex < mSupportedAreas.size()) - { - if (mSupportedAreas[listIndex].areaID == aAreaID) - { - supportedArea = mSupportedAreas[listIndex]; - return true; - } - - ++listIndex; - } - - return false; -}; - -bool RvcServiceAreaDelegate::AddSupportedArea(const AreaStructureWrapper & newArea, uint32_t & listIndex) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check list size to ensure there no memory issues. - if (mSupportedAreas.size() < kMaxNumSupportedAreas) - { - // not sorting list, number of areas normally expected to be small, max 255 - mSupportedAreas.push_back(newArea); - listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list - return true; - } - - ChipLogError(Zcl, "AddSupportedArea %u - supported areas list is already at maximum size %u", newArea.areaID, - static_cast(kMaxNumSupportedAreas)); - - return false; -} - -bool RvcServiceAreaDelegate::ModifySupportedArea(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check that areaID's match. - if (modifiedArea.areaID != mSupportedAreas[listIndex].areaID) - { - ChipLogError(Zcl, "ModifySupportedArea - areaID's do not match, new areaID %u, existing areaID %u", modifiedArea.areaID, - mSupportedAreas[listIndex].areaID); - return false; - } - - // checks passed, update the attribute - mSupportedAreas[listIndex] = modifiedArea; - return true; -} - -bool RvcServiceAreaDelegate::ClearSupportedAreas() -{ - if (!mSupportedAreas.empty()) - { - mSupportedAreas.clear(); - return true; - } - - return false; -} - -bool RvcServiceAreaDelegate::RemoveSupportedArea(uint32_t areaId) -{ - for (auto it = mSupportedAreas.begin(); it != mSupportedAreas.end(); ++it) - { - if (it->areaID == areaId) - { - mSupportedAreas.erase(it); - return true; - } - } - - return false; -} - -//************************************************************************* -// Supported Maps accessors - bool RvcServiceAreaDelegate::IsSupportedMapChangeAllowed() { return (mIsSupportedMapChangeAllowedDeviceInstance->*mIsSupportedMapChangeAllowedCallback)(); } -uint32_t RvcServiceAreaDelegate::GetNumberOfSupportedMaps() -{ - return static_cast(mSupportedMaps.size()); -} - -bool RvcServiceAreaDelegate::GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) -{ - if (listIndex < mSupportedMaps.size()) - { - aSupportedMap = mSupportedMaps[listIndex]; - return true; - } - - return false; -}; - -bool RvcServiceAreaDelegate::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) -{ - // We do not need to reimplement this method as it's already done by the SDK. - // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation - // since we have direct access to the list. - listIndex = 0; - - while (listIndex < mSupportedMaps.size()) - { - if (mSupportedMaps[listIndex].mapID == aMapId) - { - aSupportedMap = mSupportedMaps[listIndex]; - return true; - } - - ++listIndex; - } - - return false; -}; - -bool RvcServiceAreaDelegate::AddSupportedMap(const MapStructureWrapper & newMap, uint32_t & listIndex) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check list size to ensure there no memory issues. - if (mSupportedMaps.size() < kMaxNumSupportedMaps) - { - // not sorting list, number of areas normally expected to be small, max 255 - mSupportedMaps.push_back(newMap); - listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list - return true; - } - ChipLogError(Zcl, "AddSupportedMap %u - supported maps list is already at maximum size %u", newMap.mapID, - static_cast(kMaxNumSupportedMaps)); - - return false; -} - -bool RvcServiceAreaDelegate::ModifySupportedMap(uint32_t listIndex, const MapStructureWrapper & modifiedMap) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check that mapID's match. - if (modifiedMap.mapID != mSupportedMaps[listIndex].mapID) - { - ChipLogError(Zcl, "ModifySupportedMap - mapID's do not match, new mapID %u, existing mapID %u", modifiedMap.mapID, - mSupportedMaps[listIndex].mapID); - return false; - } - - // save modified map - mSupportedMaps[listIndex] = modifiedMap; - return true; -} - -bool RvcServiceAreaDelegate::ClearSupportedMaps() -{ - if (!mSupportedMaps.empty()) - { - mSupportedMaps.clear(); - return true; - } - - return false; -} - -void RvcServiceAreaDelegate::HandleSupportedAreasUpdated() -{ - // Get a list of supported area IDs as `supportedAreaIDs` - std::vector supportedAreaIDs; - for (const auto & supportedArea : mSupportedAreas) - { - supportedAreaIDs.push_back(supportedArea.areaID); - } - - if (supportedAreaIDs.empty()) - { - // Clear all selected areas, current area, and progress if there are no supported areas. - GetInstance()->ClearSelectedAreas(); - GetInstance()->SetCurrentArea(DataModel::NullNullable); - GetInstance()->ClearProgress(); - return; - } - - // Remove mSelectedArea elements that do not exist is `supportedAreaIDs` - { - for (auto it = mSelectedAreas.begin(); it != mSelectedAreas.end();) - { - if (std::find(supportedAreaIDs.begin(), supportedAreaIDs.end(), *it) == supportedAreaIDs.end()) - { - it = mSelectedAreas.erase(it); - } - else - { - ++it; - } - } - } - - // Set current Area to null if current area is not in `supportedAreaIDs` - { - auto currentAreaId = GetInstance()->GetCurrentArea(); - if (!currentAreaId.IsNull() && - std::find(supportedAreaIDs.begin(), supportedAreaIDs.end(), currentAreaId.Value()) == supportedAreaIDs.end()) - { - GetInstance()->SetCurrentArea(DataModel::NullNullable); - } - } - - // Remove mProgress elements that do not exist is `supportedAreaIDs` - { - for (auto it = mProgressList.begin(); it != mProgressList.end();) - { - if (std::find(supportedAreaIDs.begin(), supportedAreaIDs.end(), it->areaID) == supportedAreaIDs.end()) - { - it = mProgressList.erase(it); - } - else - { - ++it; - } - } - } -} - -bool RvcServiceAreaDelegate::RemoveSupportedMap(uint32_t mapId) -{ - bool removedEntry = false; - for (auto it = mSupportedMaps.begin(); it != mSupportedMaps.end(); ++it) - { - if (it->mapID == mapId) - { - mSupportedMaps.erase(it); - removedEntry = true; - } - } - - if (!removedEntry) - { - return false; - } - - // If there are no supported maps left, none of the supported areas are vaild and their MapID needs to be null. - if (GetNumberOfSupportedMaps() == 0) - { - ClearSupportedAreas(); - return true; - } - - // Get the supported area IDs where the map ID matches the removed map ID - std::vector supportedAreaIds; - { - for (const auto & supportedArea : mSupportedAreas) - { - if (supportedArea.mapID == mapId) - { - supportedAreaIds.push_back(supportedArea.areaID); - } - } - } - - // Remove the supported areas with the matching map ID - if (!supportedAreaIds.empty()) - { - for (const auto & supportedAreaId : supportedAreaIds) - { - RemoveSupportedArea(supportedAreaId); - } - HandleSupportedAreasUpdated(); - } - - return true; -} - -//************************************************************************* -// Selected areas accessors - -uint32_t RvcServiceAreaDelegate::GetNumberOfSelectedAreas() -{ - return static_cast(mSelectedAreas.size()); -} - -bool RvcServiceAreaDelegate::GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) -{ - if (listIndex < mSelectedAreas.size()) - { - selectedArea = mSelectedAreas[listIndex]; - return true; - } - - return false; -}; - -bool RvcServiceAreaDelegate::AddSelectedArea(uint32_t aAreaID, uint32_t & listIndex) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check list size to ensure there no memory issues. - if (mSelectedAreas.size() < kMaxNumSelectedAreas) - { - // not sorting list, number of areas normally expected to be small, max 255 - mSelectedAreas.push_back(aAreaID); - listIndex = static_cast(mSelectedAreas.size()) - 1; // new element is last in list - return true; - } - ChipLogError(Zcl, "AddSelectedArea %u - selected areas list is already at maximum size %u", aAreaID, - static_cast(kMaxNumSelectedAreas)); - - return false; -} - -bool RvcServiceAreaDelegate::ClearSelectedAreas() -{ - if (!mSelectedAreas.empty()) - { - mSelectedAreas.clear(); - return true; - } - - return false; -} - -//************************************************************************* -// Progress List accessors - -uint32_t RvcServiceAreaDelegate::GetNumberOfProgressElements() -{ - return static_cast(mProgressList.size()); -} - -bool RvcServiceAreaDelegate::GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) -{ - if (listIndex < mProgressList.size()) - { - aProgressElement = mProgressList[listIndex]; - return true; - } - - return false; -}; - -bool RvcServiceAreaDelegate::GetProgressElementById(uint32_t aAreaID, uint32_t & listIndex, - Structs::ProgressStruct::Type & aProgressElement) -{ - // We do not need to reimplement this method as it's already done by the SDK. - // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation - // since we have direct access to the list. - listIndex = 0; - - while (listIndex < mProgressList.size()) - { - if (mProgressList[listIndex].areaID == aAreaID) - { - aProgressElement = mProgressList[listIndex]; - return true; - } - - ++listIndex; - } - - return false; -}; - -bool RvcServiceAreaDelegate::AddProgressElement(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) -{ - // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, - // etc. - - // Double-check list size to ensure there no memory issues. - if (mProgressList.size() < kMaxNumProgressElements) - { - // not sorting list, number of areas normally expected to be small, max 255 - mProgressList.push_back(newProgressElement); - listIndex = static_cast(mProgressList.size()) - 1; // new element is last in list - return true; - } - ChipLogError(Zcl, "AddProgressElement %u -progress list is already at maximum size %u", newProgressElement.areaID, - static_cast(kMaxNumProgressElements)); - - return false; -} - -bool RvcServiceAreaDelegate::ModifyProgressElement(uint32_t listIndex, - const Structs::ProgressStruct::Type & modifiedProgressElement) -{ - if (modifiedProgressElement.areaID != mProgressList[listIndex].areaID) - { - ChipLogError(Zcl, "ModifyProgressElement - areaID's do not match, new areaID %u, existing areaID %u", - modifiedProgressElement.areaID, mProgressList[listIndex].areaID); - return false; - } - - mProgressList[listIndex] = modifiedProgressElement; - return true; -} - -bool RvcServiceAreaDelegate::ClearProgress() -{ - if (!mProgressList.empty()) - { - mProgressList.clear(); - return true; - } - - return false; -} - void RvcServiceAreaDelegate::SetAttributesAtCleanStart() { - if (GetNumberOfSupportedAreas() == 0) + if (GetInstance()->GetNumberOfSupportedAreas() == 0) { return; } - if (GetNumberOfSelectedAreas() == 0) + if (GetInstance()->GetNumberOfSelectedAreas() == 0) { AreaStructureWrapper firstArea; - GetSupportedAreaByIndex(0, firstArea); + GetInstance()->GetSupportedAreaByIndex(0, firstArea); GetInstance()->SetCurrentArea(firstArea.areaID); @@ -632,7 +199,7 @@ void RvcServiceAreaDelegate::SetAttributesAtCleanStart() else { uint32_t areaId; - GetSelectedAreaByIndex(0, areaId); + GetInstance()->GetSelectedAreaByIndex(0, areaId); GetInstance()->SetCurrentArea(areaId); @@ -642,7 +209,7 @@ void RvcServiceAreaDelegate::SetAttributesAtCleanStart() GetInstance()->SetProgressStatus(areaId, OperationalStatusEnum::kOperating); uint32_t i = 1; - while (GetSelectedAreaByIndex(i, areaId)) + while (GetInstance()->GetSelectedAreaByIndex(i, areaId)) { GetInstance()->AddPendingProgressElement(areaId); i++; @@ -670,7 +237,7 @@ void RvcServiceAreaDelegate::GoToNextArea(OperationalStatusEnum currentAreaOpSta auto currentAreaId = currentAreaIdN.Value(); uint32_t currentAreaIndex; - GetSupportedAreaById(currentAreaId, currentAreaIndex, currentArea); + GetInstance()->GetSupportedAreaById(currentAreaId, currentAreaIndex, currentArea); auto currentAreaMapId = currentArea.mapID; finished = true; @@ -679,11 +246,11 @@ void RvcServiceAreaDelegate::GoToNextArea(OperationalStatusEnum currentAreaOpSta GetInstance()->SetProgressStatus(currentAreaId, currentAreaOpState); } - if (GetNumberOfSelectedAreas() == 0) + if (GetInstance()->GetNumberOfSelectedAreas() == 0) { AreaStructureWrapper nextArea; uint32_t nextIndex = currentAreaIndex + 1; - while (GetSupportedAreaByIndex(nextIndex, nextArea)) + while (GetInstance()->GetSupportedAreaByIndex(nextIndex, nextArea)) { if (!currentAreaMapId.IsNull() && nextArea.mapID == currentAreaMapId.Value()) { @@ -705,7 +272,7 @@ void RvcServiceAreaDelegate::GoToNextArea(OperationalStatusEnum currentAreaOpSta { uint32_t selectedAreaId; uint32_t selectedAreaIndex = 0; - while (GetSelectedAreaByIndex(selectedAreaIndex, selectedAreaId)) + while (GetInstance()->GetSelectedAreaByIndex(selectedAreaIndex, selectedAreaId)) { if (selectedAreaId == currentAreaId) { @@ -716,7 +283,7 @@ void RvcServiceAreaDelegate::GoToNextArea(OperationalStatusEnum currentAreaOpSta uint32_t nextSelectedAreaId; uint32_t nextSelectedAreaIndex = selectedAreaIndex + 1; - if (GetSelectedAreaByIndex(nextSelectedAreaIndex, nextSelectedAreaId)) + if (GetInstance()->GetSelectedAreaByIndex(nextSelectedAreaIndex, nextSelectedAreaId)) { GetInstance()->SetCurrentArea(nextSelectedAreaId); diff --git a/examples/rvc-app/rvc-common/src/rvc-service-area-storage-delegate.cpp b/examples/rvc-app/rvc-common/src/rvc-service-area-storage-delegate.cpp new file mode 100644 index 00000000000000..1fb753550129c7 --- /dev/null +++ b/examples/rvc-app/rvc-common/src/rvc-service-area-storage-delegate.cpp @@ -0,0 +1,393 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ServiceArea; + +//************************************************************************* +// Supported Areas accessors + +uint32_t RvcServiceAreaStorageDelegate::GetNumberOfSupportedAreas() +{ + return static_cast(mSupportedAreas.size()); +} + +bool RvcServiceAreaStorageDelegate::GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & supportedArea) +{ + if (listIndex < mSupportedAreas.size()) + { + supportedArea = mSupportedAreas[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::GetSupportedAreaById(uint32_t aAreaID, uint32_t & listIndex, + AreaStructureWrapper & supportedArea) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mSupportedAreas.size()) + { + if (mSupportedAreas[listIndex].areaID == aAreaID) + { + supportedArea = mSupportedAreas[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::AddSupportedAreaRaw(const AreaStructureWrapper & newArea, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSupportedAreas.size() < kMaxNumSupportedAreas) + { + // not sorting list, number of areas normally expected to be small, max 255 + mSupportedAreas.push_back(newArea); + listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list + return true; + } + + ChipLogError(Zcl, "AddSupportedAreaRaw %u - supported areas list is already at maximum size %u", newArea.areaID, + static_cast(kMaxNumSupportedAreas)); + + return false; +} + +bool RvcServiceAreaStorageDelegate::ModifySupportedAreaRaw(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check that areaID's match. + if (modifiedArea.areaID != mSupportedAreas[listIndex].areaID) + { + ChipLogError(Zcl, "ModifySupportedAreaRaw - areaID's do not match, new areaID %u, existing areaID %u", modifiedArea.areaID, + mSupportedAreas[listIndex].areaID); + return false; + } + + // checks passed, update the attribute + mSupportedAreas[listIndex] = modifiedArea; + return true; +} + +bool RvcServiceAreaStorageDelegate::ClearSupportedAreasRaw() +{ + if (!mSupportedAreas.empty()) + { + mSupportedAreas.clear(); + return true; + } + + return false; +} + +bool RvcServiceAreaStorageDelegate::RemoveSupportedAreaRaw(uint32_t areaId) +{ + for (auto it = mSupportedAreas.begin(); it != mSupportedAreas.end(); ++it) + { + if (it->areaID == areaId) + { + mSupportedAreas.erase(it); + return true; + } + } + + return false; +} + +//************************************************************************* +// Supported Maps accessors + +uint32_t RvcServiceAreaStorageDelegate::GetNumberOfSupportedMaps() +{ + return static_cast(mSupportedMaps.size()); +} + +bool RvcServiceAreaStorageDelegate::GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) +{ + if (listIndex < mSupportedMaps.size()) + { + aSupportedMap = mSupportedMaps[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mSupportedMaps.size()) + { + if (mSupportedMaps[listIndex].mapID == aMapId) + { + aSupportedMap = mSupportedMaps[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::AddSupportedMapRaw(const MapStructureWrapper & newMap, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSupportedMaps.size() < kMaxNumSupportedMaps) + { + // not sorting list, number of areas normally expected to be small, max 255 + mSupportedMaps.push_back(newMap); + listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddSupportedMapRaw %u - supported maps list is already at maximum size %u", newMap.mapID, + static_cast(kMaxNumSupportedMaps)); + + return false; +} + +bool RvcServiceAreaStorageDelegate::ModifySupportedMapRaw(uint32_t listIndex, const MapStructureWrapper & modifiedMap) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check that mapID's match. + if (modifiedMap.mapID != mSupportedMaps[listIndex].mapID) + { + ChipLogError(Zcl, "ModifySupportedMapRaw - mapID's do not match, new mapID %u, existing mapID %u", modifiedMap.mapID, + mSupportedMaps[listIndex].mapID); + return false; + } + + // save modified map + mSupportedMaps[listIndex] = modifiedMap; + return true; +} + +bool RvcServiceAreaStorageDelegate::ClearSupportedMapsRaw() +{ + if (!mSupportedMaps.empty()) + { + mSupportedMaps.clear(); + return true; + } + + return false; +} + +bool RvcServiceAreaStorageDelegate::RemoveSupportedMapRaw(uint32_t mapId) +{ + for (auto it = mSupportedMaps.begin(); it != mSupportedMaps.end(); ++it) + { + if (it->mapID == mapId) + { + mSupportedMaps.erase(it); + return true; + } + } + + return false; +} + +//************************************************************************* +// Selected areas accessors + +uint32_t RvcServiceAreaStorageDelegate::GetNumberOfSelectedAreas() +{ + return static_cast(mSelectedAreas.size()); +} + +bool RvcServiceAreaStorageDelegate::GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) +{ + if (listIndex < mSelectedAreas.size()) + { + selectedArea = mSelectedAreas[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::AddSelectedAreaRaw(uint32_t aAreaID, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSelectedAreas.size() < kMaxNumSelectedAreas) + { + // not sorting list, number of areas normally expected to be small, max 255 + mSelectedAreas.push_back(aAreaID); + listIndex = static_cast(mSelectedAreas.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddSelectedAreaRaw %u - selected areas list is already at maximum size %u", aAreaID, + static_cast(kMaxNumSelectedAreas)); + + return false; +} + +bool RvcServiceAreaStorageDelegate::ClearSelectedAreasRaw() +{ + if (!mSelectedAreas.empty()) + { + mSelectedAreas.clear(); + return true; + } + + return false; +} + +bool RvcServiceAreaStorageDelegate::RemoveSelectedAreasRaw(uint32_t areaId) +{ + for (auto it = mSelectedAreas.begin(); it != mSelectedAreas.end(); ++it) + { + if (*it == areaId) + { + mSelectedAreas.erase(it); + return true; + } + } + + return false; +} + +//************************************************************************* +// Progress List accessors + +uint32_t RvcServiceAreaStorageDelegate::GetNumberOfProgressElements() +{ + return static_cast(mProgressList.size()); +} + +bool RvcServiceAreaStorageDelegate::GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + if (listIndex < mProgressList.size()) + { + aProgressElement = mProgressList[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::GetProgressElementById(uint32_t aAreaID, uint32_t & listIndex, + Structs::ProgressStruct::Type & aProgressElement) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mProgressList.size()) + { + if (mProgressList[listIndex].areaID == aAreaID) + { + aProgressElement = mProgressList[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaStorageDelegate::AddProgressElementRaw(const Structs::ProgressStruct::Type & newProgressElement, + uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mProgressList.size() < kMaxNumProgressElements) + { + // not sorting list, number of areas normally expected to be small, max 255 + mProgressList.push_back(newProgressElement); + listIndex = static_cast(mProgressList.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddProgressElementRaw %u -progress list is already at maximum size %u", newProgressElement.areaID, + static_cast(kMaxNumProgressElements)); + + return false; +} + +bool RvcServiceAreaStorageDelegate::ModifyProgressElementRaw(uint32_t listIndex, + const Structs::ProgressStruct::Type & modifiedProgressElement) +{ + if (modifiedProgressElement.areaID != mProgressList[listIndex].areaID) + { + ChipLogError(Zcl, "ModifyProgressElementRaw - areaID's do not match, new areaID %u, existing areaID %u", + modifiedProgressElement.areaID, mProgressList[listIndex].areaID); + return false; + } + + mProgressList[listIndex] = modifiedProgressElement; + return true; +} + +bool RvcServiceAreaStorageDelegate::ClearProgressRaw() +{ + if (!mProgressList.empty()) + { + mProgressList.clear(); + return true; + } + + return false; +} + +bool RvcServiceAreaStorageDelegate::RemoveProgressElementRaw(uint32_t areaId) +{ + for (auto it = mProgressList.begin(); it != mProgressList.end(); ++it) + { + if (it->areaID == areaId) + { + mProgressList.erase(it); + return true; + } + } + + return false; +} diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index a1d9a811a1b1e7..c8907ac98b3d79 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -403,8 +403,9 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/${cluster}.cpp", "${_app_root}/clusters/${cluster}/${cluster}.h", "${_app_root}/clusters/${cluster}/service-area-cluster-objects.h", - "${_app_root}/clusters/${cluster}/service-area-delegate.cpp", "${_app_root}/clusters/${cluster}/service-area-delegate.h", + "${_app_root}/clusters/${cluster}/service-area-storage-delegate.cpp", + "${_app_root}/clusters/${cluster}/service-area-storage-delegate.h", ] } else if (cluster == "thread-border-router-management-server") { sources += [ diff --git a/src/app/clusters/service-area-server/README.md b/src/app/clusters/service-area-server/README.md new file mode 100644 index 00000000000000..7f0cf642947565 --- /dev/null +++ b/src/app/clusters/service-area-server/README.md @@ -0,0 +1,35 @@ +# The Service Area Cluster + +## Cluster design + +The service area cluster is designed around three core classes: `Instance`, +`StorageDelegate`, and a second `Delegate` class. + +The `Instance` class serves as the primary interface for safely accessing and +modifying cluster attributes, adhering to the constraints outlined in the +specification document. However, it does not handle the storage of list +attributes. + +Storage management is delegated to the `StorageDelegate` class, which provides a +list of virtual methods for the user to implement. These methods are +straightforward and do not require input validation, but they should not be used +directly. + +The business logic specific to the device is encapsulated in a second `Delegate` +class. This class can access the `Instance` through the `GetInstance()` method, +enabling it to utilize all the attribute access methods provided by the +`Instance` class. This design allows for a clear separation of concerns, with +each class handling a specific aspect of the cluster's functionality. + +## How to use + +- Create a class that inherits the `ServiceArea::StorageDelegate` class. +- For this class, implement the necessary virtual methods. +- Create a class that inherits the `ServiceArea::Delegate` class. +- For this class, implement the necessary virtual methods. +- In some translation unit (.c or .cpp file), instantiate the delegate + classes. +- Instantiate the `Instance` class using the delegate instances. +- Call the `Instance`'s `Init()` method after the root `Server::Init()`. +- Alternatively, the last two steps can be done in the + `emberAfServiceAreaClusterInitCallback` function. diff --git a/src/app/clusters/service-area-server/service-area-cluster-objects.h b/src/app/clusters/service-area-server/service-area-cluster-objects.h index 470cd09c02b67d..876d628060be6f 100644 --- a/src/app/clusters/service-area-server/service-area-cluster-objects.h +++ b/src/app/clusters/service-area-server/service-area-cluster-objects.h @@ -27,8 +27,13 @@ namespace Clusters { namespace ServiceArea { // These limits are defined in the spec. -inline constexpr size_t kAreaNameMaxSize = 128u; -inline constexpr size_t kMapNameMaxSize = 64u; +inline constexpr size_t kMaxNumSupportedAreas = 255; +inline constexpr size_t kMaxNumSupportedMaps = 255; +inline constexpr size_t kMaxNumSelectedAreas = 255; +inline constexpr size_t kMaxNumProgressElements = 255; +inline constexpr size_t kMaxSizeStatusText = 256; +inline constexpr size_t kAreaNameMaxSize = 128u; +inline constexpr size_t kMapNameMaxSize = 64u; /** * This class is used to wrap the AreaStruct object and provide a more user-friendly interface for the data. diff --git a/src/app/clusters/service-area-server/service-area-delegate.h b/src/app/clusters/service-area-server/service-area-delegate.h index 7fe40bb8fe16f4..3983e8d6ed7c25 100644 --- a/src/app/clusters/service-area-server/service-area-delegate.h +++ b/src/app/clusters/service-area-server/service-area-delegate.h @@ -28,16 +28,6 @@ namespace ServiceArea { class Instance; -// ***************************************************************************** -// cluster constraints - -constexpr size_t kMaxNumSupportedAreas = 255; -constexpr size_t kMaxNumSupportedMaps = 255; -constexpr size_t kMaxNumSelectedAreas = 255; -constexpr size_t kMaxNumProgressElements = 255; - -constexpr size_t kMaxSizeStatusText = 256; - /** * ServiceArea::Delegate Defines methods for implementing application-specific * logic for the Service Area Cluster. @@ -61,12 +51,13 @@ class Delegate */ virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; }; - //************************************************************************* - // Command handling support - /** * @brief Can the selected locations be set by the client in the current operating mode? - * @param[out] statusText text describing why selected locations cannot be set (if return is false). + * @param[out] statusText text describing why the selected locations cannot be set (if return is false). + * Max size kMaxSizeStatusText. + * Note: If the return is false and statusText is not successfully set, for example due to a string that can be longer than + * kMaxSizeStatusText, the size of this value should be set to 0 with .reduce_size(0) to avoid callers using un-initialized + * memory. * @return true if the current device state allows selected locations to be set by user. * * @note The statusText field SHOULD indicate why the request is not allowed, given the current mode @@ -85,7 +76,10 @@ class Delegate * * @param[in] selectedAreas List of new selected locations. * @param[out] locationStatus Success if all checks pass, error code if failure. - * @param[out] statusText text describing failure (see description above), size kMaxSizeStatusText. + * @param[out] statusText text describing failure (see description above). Max size kMaxSizeStatusText. + * Note: If the return is false and statusText is not successfully set, for example due to a string that can be longer than + * kMaxSizeStatusText, the size of this value should be set to 0 with .reduce_size(0) to avoid callers using un-initialized + * memory. * @return true if success. * * @note If the SelectAreas command is allowed when the device is operating and the selected locations change to none, the @@ -98,7 +92,10 @@ class Delegate * @brief The server instance ensures that the SelectedAreas and CurrentArea attributes are not null before * calling this method. * @param[in] skippedArea the area ID to skip. - * @param[out] skipStatusText text describing why current location cannot be skipped. + * @param[out] skipStatusText text describing why the current location cannot be skipped. Max size kMaxSizeStatusText. + * Note: If the return is false and skipStatusText is not successfully set, for example due to a string that can be longer than + * kMaxSizeStatusText, the size of this value should be set to 0 with .reduce_size(0) to avoid callers using un-initialized + * memory. * @return true if command is successful, false if the received skip request cannot be handled due to the current mode of the * device. * @@ -127,9 +124,6 @@ class Delegate return false; } - //************************************************************************* - // Supported Areas accessors - /** * @return true if the current device state allows the SupportedAreas attribute to be updated. * @@ -144,74 +138,6 @@ class Delegate */ virtual bool IsSupportedAreasChangeAllowed() = 0; - virtual uint32_t GetNumberOfSupportedAreas() = 0; - - /** - * @brief Get a supported area using the position in the list. - * @param[in] listIndex the position in the list. - * @param[out] aSupportedArea a copy of the area contents, if found. - * @return true if an area is found, false otherwise. - */ - virtual bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea) = 0; - - /** - * @brief Get a supported area that matches a areaID. - * @param[in] aAreaId the areaID to search for. - * @param[out] listIndex the area's index in the list, if found. - * @param[out] aSupportedArea a copy of the area contents, if found. - * @return true if an area is found, false otherwise. - * - * @note may be overloaded in device implementation for optimization, if desired. - */ - virtual bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea); - - /** - * This method is called by the server instance to add a new area to the list. - * The server instance will ensure that the newArea is a valid, unique area. - * @param [in] newArea new area to add. - * @param [out] listIndex filled with the list index for the new area, if successful. - * @return true if successful, false otherwise. - - * @note this method SHOULD double check that the added area won't exceed the maximum list size. - */ - virtual bool AddSupportedArea(const AreaStructureWrapper & newArea, uint32_t & listIndex) = 0; - - /** - * This method is called by the server instance to modify an existing area in the list. - * The server instance will ensure that the modifiedArea is a valid, unique area. - * @param[in] listIndex The index of the area being modified. - * @param[in] modifiedArea An area with the modified contents. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that newArea's areaID matches the object at listIndex. - */ - virtual bool ModifySupportedArea(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) = 0; - - /** - * @return true if supported locations was not already null, false otherwise. - */ - virtual bool ClearSupportedAreas() = 0; - - /** - * @brief Ensure that when the Supported locations is modified, the required restrictions for the SelectedAreas, - * CurrentArea, and Progress attributes are maintained. - * - * This method will be called by the SDK whenever the adherence to the restrictions for these attributes cannot be guaranteed. - * For example, if there are deletions in the SupportedMops or SupportedAreas attributes, or if there are changes to their - * IDs. This method will no be called if the changes made to the SupportedMops or SupportedAreas attributes, ensure that the - * restrictions are adhered. For example, if there are additions or the modifications do not involve changing IDs in the - * SupportedMops or SupportedAreas attributes. - * - * The default implementation will set the SelectedAreas, CurrentArea, and Progress attributes to null. - * - * The user is free the redefine this method as their device may have more information on what has changed and may be able to - * maintain the restrictions on these attributes by selectively editing them. - */ - virtual void HandleSupportedAreasUpdated(); - - //************************************************************************* - // Supported Maps accessors - /** * @return true if the current device state allows the SupportedMaps attribute to be updated. * @@ -226,149 +152,6 @@ class Delegate */ virtual bool IsSupportedMapChangeAllowed() = 0; - virtual uint32_t GetNumberOfSupportedMaps() = 0; - - /** - * @brief Get a supported map using the position in the list. - * @param[in] listIndex the position in the list. - * @param[out] aSupportedMap copy of the map contents, if found. - * @return true if a supported map is found, false otherwise. - */ - virtual bool GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) = 0; - - /** - * @brief Get a supported map that matches a mapID. - * @param[in] aMapId the mapID to search for. - * @param[out] listIndex the map's index in the list, if found. - * @param[out] aSupportedMap copy of the location contents, if found. - * @return true if a supported map is found, false otherwise. - * - * @note may be overloaded in device implementation for optimization, if desired. - */ - virtual bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap); - - /** - * This method is called by the server instance to add a new map to the list. - * The server instance will ensure that the newMap is a valid, unique map. - * @param[in] newMap The new map to add. - * @param[out] listIndex filled with the list index of the new map, if successful. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that the added map won't exceed the maximum list size - */ - virtual bool AddSupportedMap(const MapStructureWrapper & newMap, uint32_t & listIndex) = 0; - - /** - * This method is called by the server instance to modify an existing map in the list. - * The server instance will ensure that the modifiedMap is a valid, unique map. - * @param[in] listIndex The index of the map being modified. - * @param[in] modifiedMapA map with the modified contents. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that modifiedMap's mapID matches the object at listIndex. - */ - virtual bool ModifySupportedMap(uint32_t listIndex, const MapStructureWrapper & modifiedMap) = 0; - - /** - * @return true if supported maps was not already null, false otherwise. - */ - virtual bool ClearSupportedMaps() = 0; - - //************************************************************************* - // Selected Areas accessors - - virtual uint32_t GetNumberOfSelectedAreas() = 0; - - /** - * @brief Get a selected area using the position in the list. - * @param[in] listIndex the position in the list. - * @param[out] selectedArea the selected area value, if found. - * @return true if a selected area is found, false otherwise. - */ - virtual bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) = 0; - - /** - * @return true if the aAreaId areaID is found in the SelectedAreas list, false otherwise. - * - * @note may be overloaded in device implementation for optimization, if desired. - */ - virtual bool IsSelectedArea(uint32_t aAreaId); - - /** - * This method is called by the server instance to add a new selected area to the list. - * The server instance will ensure that the aAreaId references a SUPPORTED area, and is unique within selected - * areas. - * @param[in] aAreaId The new areaID to add. - * @param[out] listIndex filled with the list index of the new area, if successful. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that the added area won't exceed the maximum list size. - */ - virtual bool AddSelectedArea(uint32_t aAreaId, uint32_t & listIndex) = 0; - - /** - * @return true if selected locations was not already null, false otherwise. - */ - virtual bool ClearSelectedAreas() = 0; - - //************************************************************************* - // Progress accessors - - virtual uint32_t GetNumberOfProgressElements() = 0; - - /** - * @brief Get a progress element using the position in the list. - * @param[in] listIndex the position in the list. - * @param[out] aProgressElement copy of the progress element contents, if found. - * @return true if a progress element is found, false otherwise. - */ - virtual bool GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) = 0; - - /** - * @brief Get a progress element that matches a areaID. - * @param[in] aAreaId the areaID to search for. - * @param[out] listIndex the location's index in the list, if found. - * @param[out] aProgressElement copy of the progress element contents, if found. - * @return true if a progress element is found, false otherwise. - * - * @note may be overloaded in device implementation for optimization, if desired. - */ - virtual bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement); - - /** - * @brief Is the progress element in the progress list? - * @param[in] aAreaId location id of the progress element. - * @return true if the progress element identified by Id is in the progress list. - */ - virtual bool IsProgressElement(uint32_t aAreaId); - - /** - * This method is called by the server instance to add a new progress element to the list. - * The server instance will ensure that the newProgressElement is a valid, unique progress element. - * @param[in] newProgressElement The new element to add. - * @param[out] listIndex is filled with the list index for the new element, if successful. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that the added element won't exceed the maximum list size. - */ - virtual bool AddProgressElement(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) = 0; - - /** - * This method is called by the server instance to modify an existing progress element in the list. - * The server instance will ensure that the modifiedProgressElement is a valid and unique progress element. - * @param[in] listIndex The list index of the progress element being modified. - * @param[in] modifiedProgressElement modified element's contents. - * @return true if successful, false otherwise. - * - * @note this function SHOULD double check that modifiedProgressElement's areaID matches the object at listIndex - */ - virtual bool ModifyProgressElement(uint32_t listIndex, const Structs::ProgressStruct::Type & modifiedProgressElement) = 0; - - /** - * @return true if progress list was not already null, false otherwise. - */ - virtual bool ClearProgress() = 0; - Instance * GetInstance() { return mInstance; } void SetInstance(Instance * aInstance) { mInstance = aInstance; } diff --git a/src/app/clusters/service-area-server/service-area-server.cpp b/src/app/clusters/service-area-server/service-area-server.cpp index 4de8f942e0251d..55ee2ab27c9943 100644 --- a/src/app/clusters/service-area-server/service-area-server.cpp +++ b/src/app/clusters/service-area-server/service-area-server.cpp @@ -46,9 +46,9 @@ namespace ServiceArea { // **************************************************************************** // Service Area Server Instance -Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, BitMask aFeature) : +Instance::Instance(StorageDelegate * storageDelegate, Delegate * aDelegate, EndpointId aEndpointId, BitMask aFeature) : AttributeAccessInterface(MakeOptional(aEndpointId), Id), CommandHandlerInterface(MakeOptional(aEndpointId), Id), - mDelegate(aDelegate), mEndpointId(aEndpointId), mClusterId(Id), mFeature(aFeature) + mStorageDelegate(storageDelegate), mDelegate(aDelegate), mEndpointId(aEndpointId), mClusterId(Id), mFeature(aFeature) { ChipLogProgress(Zcl, "Service Area: Instance constructor"); mDelegate->SetInstance(this); @@ -72,6 +72,8 @@ CHIP_ERROR Instance::Init() VerifyOrReturnError(AttributeAccessInterfaceRegistry::Instance().Register(this), CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(mStorageDelegate->Init()); + return mDelegate->Init(); } @@ -132,7 +134,7 @@ void Instance::InvokeCommand(HandlerContext & handlerContext) CHIP_ERROR Instance::ReadSupportedAreas(AttributeValueEncoder & aEncoder) { - if (mDelegate->GetNumberOfSupportedAreas() == 0) + if (GetNumberOfSupportedAreas() == 0) { return aEncoder.EncodeEmptyList(); } @@ -141,7 +143,7 @@ CHIP_ERROR Instance::ReadSupportedAreas(AttributeValueEncoder & aEncoder) uint8_t locationIndex = 0; AreaStructureWrapper supportedArea; - while (mDelegate->GetSupportedAreaByIndex(locationIndex++, supportedArea)) + while (GetSupportedAreaByIndex(locationIndex++, supportedArea)) { ReturnErrorOnFailure(encoder.Encode(supportedArea)); } @@ -151,7 +153,7 @@ CHIP_ERROR Instance::ReadSupportedAreas(AttributeValueEncoder & aEncoder) CHIP_ERROR Instance::ReadSupportedMaps(AttributeValueEncoder & aEncoder) { - if (mDelegate->GetNumberOfSupportedMaps() == 0) + if (GetNumberOfSupportedMaps() == 0) { return aEncoder.EncodeEmptyList(); } @@ -160,7 +162,7 @@ CHIP_ERROR Instance::ReadSupportedMaps(AttributeValueEncoder & aEncoder) uint32_t mapIndex = 0; MapStructureWrapper supportedMap; - while (mDelegate->GetSupportedMapByIndex(mapIndex++, supportedMap)) + while (GetSupportedMapByIndex(mapIndex++, supportedMap)) { ReturnErrorOnFailure(encoder.Encode(supportedMap)); } @@ -170,7 +172,7 @@ CHIP_ERROR Instance::ReadSupportedMaps(AttributeValueEncoder & aEncoder) CHIP_ERROR Instance::ReadSelectedAreas(AttributeValueEncoder & aEncoder) { - if (mDelegate->GetNumberOfSelectedAreas() == 0) + if (GetNumberOfSelectedAreas() == 0) { return aEncoder.EncodeEmptyList(); } @@ -179,7 +181,7 @@ CHIP_ERROR Instance::ReadSelectedAreas(AttributeValueEncoder & aEncoder) uint32_t locationIndex = 0; uint32_t selectedArea; - while (mDelegate->GetSelectedAreaByIndex(locationIndex++, selectedArea)) + while (GetSelectedAreaByIndex(locationIndex++, selectedArea)) { ReturnErrorOnFailure(encoder.Encode(selectedArea)); } @@ -189,7 +191,7 @@ CHIP_ERROR Instance::ReadSelectedAreas(AttributeValueEncoder & aEncoder) CHIP_ERROR Instance::ReadProgress(AttributeValueEncoder & aEncoder) { - if (mDelegate->GetNumberOfProgressElements() == 0) + if (GetNumberOfProgressElements() == 0) { return aEncoder.EncodeEmptyList(); } @@ -198,7 +200,7 @@ CHIP_ERROR Instance::ReadProgress(AttributeValueEncoder & aEncoder) uint32_t locationIndex = 0; Structs::ProgressStruct::Type progressElement; - while (mDelegate->GetProgressElementByIndex(locationIndex++, progressElement)) + while (GetProgressElementByIndex(locationIndex++, progressElement)) { ReturnErrorOnFailure(encoder.Encode(progressElement)); } @@ -257,7 +259,7 @@ void Instance::HandleSelectAreasCmd(HandlerContext & ctx, const Commands::Select }; // if number of selected locations in parameter matches number in attribute - the locations *might* be the same - bool matchesCurrentSelectedAreas = (numberOfAreas == mDelegate->GetNumberOfSelectedAreas()); + bool matchesCurrentSelectedAreas = (numberOfAreas == GetNumberOfSelectedAreas()); // do as much parameter validation as we can if (numberOfAreas != 0) @@ -277,7 +279,7 @@ void Instance::HandleSelectAreasCmd(HandlerContext & ctx, const Commands::Select // each item in this list SHALL match the AreaID field of an entry on the SupportedAreas attribute's list // If the Status field is set to UnsupportedArea, the StatusText field SHALL be an empty string. - if (!IsSupportedArea(selectedArea)) + if (!mStorageDelegate->IsSupportedArea(selectedArea)) { exitResponse(SelectAreasStatus::kUnsupportedArea, ""_span); return; @@ -286,7 +288,7 @@ void Instance::HandleSelectAreasCmd(HandlerContext & ctx, const Commands::Select // check to see if parameter list and attribute still match if (matchesCurrentSelectedAreas) { - if (!mDelegate->GetSelectedAreaByIndex(ignoredIndex, oldSelectedArea) || (selectedArea != oldSelectedArea)) + if (!GetSelectedAreaByIndex(ignoredIndex, oldSelectedArea) || (selectedArea != oldSelectedArea)) { matchesCurrentSelectedAreas = false; } @@ -346,14 +348,14 @@ void Instance::HandleSelectAreasCmd(HandlerContext & ctx, const Commands::Select // indicated by the entries of the newArea field, when requested to operate, // the SelectAreasResponse command SHALL have the Status field set to Success, // and the SelectedAreas attribute SHALL be set to the value of the newAreas field. - mDelegate->ClearSelectedAreas(); + mStorageDelegate->ClearSelectedAreasRaw(); if (numberOfAreas != 0) { uint32_t ignored; for (uint32_t areaId : selectedAreasSpan) { - mDelegate->AddSelectedArea(areaId, ignored); + mStorageDelegate->AddSelectedAreaRaw(areaId, ignored); } } @@ -378,7 +380,7 @@ void Instance::HandleSkipAreaCmd(HandlerContext & ctx, const Commands::SkipArea: // The SkippedArea field SHALL match an entry in the SupportedAreas list. // If the Status field is set to InvalidAreaList, the StatusText field SHALL be an empty string. - if (!IsSupportedArea(req.skippedArea)) + if (!mStorageDelegate->IsSupportedArea(req.skippedArea)) { ChipLogError(Zcl, "SkippedArea (%" PRIu32 ") is not in the SupportedAreas attribute.", req.skippedArea); exitResponse(SkipAreaStatus::kInvalidAreaList, ""_span); @@ -437,14 +439,6 @@ void Instance::NotifyProgressChanged() // **************************************************************************** // Supported Areas manipulators -bool Instance::IsSupportedArea(uint32_t aAreaId) -{ - uint32_t ignoredIndex; - AreaStructureWrapper ignoredArea; - - return mDelegate->GetSupportedAreaById(aAreaId, ignoredIndex, ignoredArea); -} - bool Instance::IsValidSupportedArea(const AreaStructureWrapper & aArea) { // If the LocationInfo field is null, the LandmarkInfo field SHALL NOT be null. @@ -470,7 +464,7 @@ bool Instance::IsValidSupportedArea(const AreaStructureWrapper & aArea) } // The mapID field SHALL be null if SupportedMaps is not supported or SupportedMaps is an empty list. - if (mFeature.Has(Feature::kMaps) && (mDelegate->GetNumberOfSupportedMaps() > 0)) + if (mFeature.Has(Feature::kMaps) && (GetNumberOfSupportedMaps() > 0)) { if (aArea.mapID.IsNull()) { @@ -480,7 +474,7 @@ bool Instance::IsValidSupportedArea(const AreaStructureWrapper & aArea) } // If the SupportedMaps attribute is not null, mapID SHALL be the ID of an entry from the SupportedMaps attribute. - if (!IsSupportedMap(aArea.mapID.Value())) + if (!mStorageDelegate->IsSupportedMap(aArea.mapID.Value())) { ChipLogError(Zcl, "IsValidSupportedArea %" PRIu32 " - map Id %" PRIu32 " is not in supported map list", aArea.areaID, aArea.mapID.Value()); @@ -512,14 +506,14 @@ bool Instance::IsUniqueSupportedArea(const AreaStructureWrapper & aArea, bool ig // If the SupportedMaps attribute is not null, each entry in this list SHALL have a unique value for the combination of the // MapID and LocationInfo fields. If the SupportedMaps attribute is null, each entry in this list SHALL have a unique value for // the LocationInfo field. - if (mDelegate->GetNumberOfSupportedMaps() == 0) + if (GetNumberOfSupportedMaps() == 0) { config.Set(AreaStructureWrapper::IsEqualConfig::kIgnoreMapId); } uint8_t locationIndex = 0; AreaStructureWrapper entry; - while (mDelegate->GetSupportedAreaByIndex(locationIndex++, entry)) + while (GetSupportedAreaByIndex(locationIndex++, entry)) { if (aArea.IsEqual(entry, config)) { @@ -567,6 +561,99 @@ bool Instance::ReportEstimatedEndTimeChange(const DataModel::Nullable return (aEstimatedEndTime.Value() < mEstimatedEndTime.Value()); } +void Instance::HandleSupportedAreasUpdated() +{ + // If there are no more Supported Areas, clear all selected areas, current area, and progress. + if (GetNumberOfSupportedAreas() == 0) + { + ClearSelectedAreas(); + SetCurrentArea(DataModel::NullNullable); + ClearProgress(); + return; + } + + // Remove Selected Areas elements that do not exist is the Supported Areas attribute. + { + uint32_t i = 0; + uint32_t areaId = 0; + uint32_t areasToRemoveIndex = 0; + uint32_t areasToRemoveBuffer[kMaxNumSelectedAreas]; + Span areasToRemoveSpan(areasToRemoveBuffer); + + while (GetSelectedAreaByIndex(i, areaId)) + { + if (!mStorageDelegate->IsSupportedArea(areaId)) + { + areasToRemoveSpan[areasToRemoveIndex] = areaId; + areasToRemoveIndex++; + } + i++; + } + areasToRemoveSpan.reduce_size(areasToRemoveIndex); + + for (auto id : areasToRemoveSpan) + { + if (!RemoveSelectedAreas(id)) + { + ChipLogError(Zcl, "HandleSupportedAreasUpdated: Failed to remove area %" PRIu32 " from selected areas", id); + } + } + } + + // Set current Area to null if current area is not in the supported areas attribute. + { + auto currentAreaId = GetCurrentArea(); + if (!currentAreaId.IsNull() && !mStorageDelegate->IsSupportedArea(currentAreaId.Value())) + { + SetCurrentArea(DataModel::NullNullable); + } + } + + // Remove Progress elements associated with areas that do not exist is the Supported Areas attribute. + { + uint32_t i = 0; + Structs::ProgressStruct::Type tempProgressElement; + uint32_t progressToRemoveIndex = 0; + uint32_t progressToRemoveBuffer[kMaxNumProgressElements]; + Span progressToRemoveSpan(progressToRemoveBuffer); + + while (mStorageDelegate->GetProgressElementByIndex(i, tempProgressElement)) + { + if (mStorageDelegate->IsSupportedArea(tempProgressElement.areaID)) + { + progressToRemoveSpan[progressToRemoveIndex] = tempProgressElement.areaID; + progressToRemoveIndex++; + } + i++; + } + progressToRemoveSpan.reduce_size(progressToRemoveIndex); + + for (auto areaId : progressToRemoveSpan) + { + if (!mStorageDelegate->RemoveProgressElementRaw(areaId)) + { + ChipLogError(Zcl, "HandleSupportedAreasUpdated: Failed to remove progress element with area ID %" PRIu32 "", + areaId); + } + } + } +} + +uint32_t Instance::GetNumberOfSupportedAreas() +{ + return mStorageDelegate->GetNumberOfSupportedAreas(); +} + +bool Instance::GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea) +{ + return mStorageDelegate->GetSupportedAreaByIndex(listIndex, aSupportedArea); +} + +bool Instance::GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea) +{ + return mStorageDelegate->GetSupportedAreaById(aAreaId, listIndex, aSupportedArea); +} + bool Instance::AddSupportedArea(AreaStructureWrapper & aNewArea) { // Does device mode allow this attribute to be updated? @@ -576,16 +663,16 @@ bool Instance::AddSupportedArea(AreaStructureWrapper & aNewArea) } // Check there is space for the entry. - if (mDelegate->GetNumberOfSupportedAreas() >= kMaxNumSupportedAreas) + if (GetNumberOfSupportedAreas() >= kMaxNumSupportedAreas) { - ChipLogError(Zcl, "AddSupportedArea %" PRIu32 " - too many entries", aNewArea.areaID); + ChipLogError(Zcl, "AddSupportedAreaRaw %" PRIu32 " - too many entries", aNewArea.areaID); return false; } // Verify cluster requirements concerning valid fields and field relationships. if (!IsValidSupportedArea(aNewArea)) { - ChipLogError(Zcl, "AddSupportedArea %" PRIu32 " - not a valid location object", aNewArea.areaID); + ChipLogError(Zcl, "AddSupportedAreaRaw %" PRIu32 " - not a valid location object", aNewArea.areaID); return false; } @@ -595,13 +682,13 @@ bool Instance::AddSupportedArea(AreaStructureWrapper & aNewArea) // the AreaInfo field. if (!IsUniqueSupportedArea(aNewArea, false)) { - ChipLogError(Zcl, "AddSupportedArea %" PRIu32 " - not a unique location object", aNewArea.areaID); + ChipLogError(Zcl, "AddSupportedAreaRaw %" PRIu32 " - not a unique location object", aNewArea.areaID); return false; } // Add the SupportedArea to the SupportedAreas attribute. uint32_t ignoredIndex; - if (!mDelegate->AddSupportedArea(aNewArea, ignoredIndex)) + if (!mStorageDelegate->AddSupportedAreaRaw(aNewArea, ignoredIndex)) { return false; } @@ -617,9 +704,9 @@ bool Instance::ModifySupportedArea(AreaStructureWrapper & aNewArea) // get existing supported location to modify AreaStructureWrapper supportedArea; - if (!mDelegate->GetSupportedAreaById(aNewArea.areaID, listIndex, supportedArea)) + if (!GetSupportedAreaById(aNewArea.areaID, listIndex, supportedArea)) { - ChipLogError(Zcl, "ModifySupportedArea %" PRIu32 " - not a supported areaID", aNewArea.areaID); + ChipLogError(Zcl, "ModifySupportedAreaRaw %" PRIu32 " - not a supported areaID", aNewArea.areaID); return false; } @@ -639,7 +726,7 @@ bool Instance::ModifySupportedArea(AreaStructureWrapper & aNewArea) // verify cluster requirements concerning valid fields and field relationships if (!IsValidSupportedArea(aNewArea)) { - ChipLogError(Zcl, "ModifySupportedArea %" PRIu32 " - not a valid location object", aNewArea.areaID); + ChipLogError(Zcl, "ModifySupportedAreaRaw %" PRIu32 " - not a valid location object", aNewArea.areaID); return false; } @@ -647,12 +734,12 @@ bool Instance::ModifySupportedArea(AreaStructureWrapper & aNewArea) // We ignore comparing the area ID as one of the locations will match this one. if (!IsUniqueSupportedArea(aNewArea, true)) { - ChipLogError(Zcl, "ModifySupportedArea %" PRIu32 " - not a unique location object", aNewArea.areaID); + ChipLogError(Zcl, "ModifySupportedAreaRaw %" PRIu32 " - not a unique location object", aNewArea.areaID); return false; } // Replace the supported location with the modified location. - if (!mDelegate->ModifySupportedArea(listIndex, aNewArea)) + if (!mStorageDelegate->ModifySupportedAreaRaw(listIndex, aNewArea)) { return false; } @@ -660,7 +747,7 @@ bool Instance::ModifySupportedArea(AreaStructureWrapper & aNewArea) if (mapIDChanged) { - mDelegate->HandleSupportedAreasUpdated(); + HandleSupportedAreasUpdated(); } NotifySupportedAreasChanged(); @@ -675,9 +762,9 @@ bool Instance::ClearSupportedAreas() return false; } - if (mDelegate->ClearSupportedAreas()) + if (mStorageDelegate->ClearSupportedAreasRaw()) { - mDelegate->HandleSupportedAreasUpdated(); + HandleSupportedAreasUpdated(); NotifySupportedAreasChanged(); return true; } @@ -685,30 +772,48 @@ bool Instance::ClearSupportedAreas() return false; } +bool Instance::RemoveSupportedArea(uint32_t areaId) +{ + if (mStorageDelegate->RemoveSupportedAreaRaw(areaId)) + { + HandleSupportedAreasUpdated(); + NotifySupportedAreasChanged(); + return true; + } + return false; +} + //************************************************************************* // Supported Maps manipulators -bool Instance::IsSupportedMap(uint32_t aMapId) +uint32_t Instance::GetNumberOfSupportedMaps() { - uint32_t ignoredIndex; - MapStructureWrapper ignoredMap; + return mStorageDelegate->GetNumberOfSupportedMaps(); +} + +bool Instance::GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) +{ + return mStorageDelegate->GetSupportedMapByIndex(listIndex, aSupportedMap); +} - return mDelegate->GetSupportedMapById(aMapId, ignoredIndex, ignoredMap); +bool Instance::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) +{ + return mStorageDelegate->GetSupportedMapById(aMapId, listIndex, aSupportedMap); } bool Instance::AddSupportedMap(uint32_t aMapId, const CharSpan & aMapName) { // check max# of list entries - if (mDelegate->GetNumberOfSupportedMaps() >= kMaxNumSupportedMaps) + if (GetNumberOfSupportedMaps() >= kMaxNumSupportedMaps) { - ChipLogError(Zcl, "AddSupportedMap %" PRIu32 " - maximum number of entries", aMapId); + ChipLogError(Zcl, "AddSupportedMapRaw %" PRIu32 " - maximum number of entries", aMapId); return false; } // Map name SHALL include readable text that describes the map name (cannot be empty string). if (aMapName.empty()) { - ChipLogError(Zcl, "AddSupportedMap %" PRIu32 " - Name must not be empty string", aMapId); + ChipLogError(Zcl, "AddSupportedMapRaw %" PRIu32 " - Name must not be empty string", aMapId); return false; } @@ -716,12 +821,12 @@ bool Instance::AddSupportedMap(uint32_t aMapId, const CharSpan & aMapName) uint8_t mapIndex = 0; MapStructureWrapper entry; - while (mDelegate->GetSupportedMapByIndex(mapIndex++, entry)) + while (GetSupportedMapByIndex(mapIndex++, entry)) { // the name cannot be the same as an existing map if (entry.IsNameEqual(aMapName)) { - ChipLogError(Zcl, "AddSupportedMap %" PRIu32 " - A map already exists with same name '%.*s'", aMapId, + ChipLogError(Zcl, "AddSupportedMapRaw %" PRIu32 " - A map already exists with same name '%.*s'", aMapId, static_cast(entry.GetName().size()), entry.GetName().data()); return false; } @@ -729,7 +834,7 @@ bool Instance::AddSupportedMap(uint32_t aMapId, const CharSpan & aMapName) // Each entry in this list SHALL have a unique value for the MapID field. if (aMapId == entry.mapID) { - ChipLogError(Zcl, "AddSupportedMap - non-unique Id %" PRIu32 "", aMapId); + ChipLogError(Zcl, "AddSupportedMapRaw - non-unique Id %" PRIu32 "", aMapId); return false; } } @@ -738,7 +843,7 @@ bool Instance::AddSupportedMap(uint32_t aMapId, const CharSpan & aMapName) // add to supported maps attribute MapStructureWrapper newMap(aMapId, aMapName); uint32_t ignoredIndex; - if (!mDelegate->AddSupportedMap(newMap, ignoredIndex)) + if (!mStorageDelegate->AddSupportedMapRaw(newMap, ignoredIndex)) { return false; } @@ -755,7 +860,7 @@ bool Instance::RenameSupportedMap(uint32_t aMapId, const CharSpan & newMapName) MapStructureWrapper modifiedMap; // get existing entry - if (!mDelegate->GetSupportedMapById(aMapId, modifiedIndex, modifiedMap)) + if (!GetSupportedMapById(aMapId, modifiedIndex, modifiedMap)) { ChipLogError(Zcl, "RenameSupportedMap Id %" PRIu32 " - map does not exist", aMapId); return false; @@ -775,7 +880,7 @@ bool Instance::RenameSupportedMap(uint32_t aMapId, const CharSpan & newMapName) uint32_t loopIndex = 0; MapStructureWrapper entry; - while (mDelegate->GetSupportedMapByIndex(loopIndex, entry)) + while (GetSupportedMapByIndex(loopIndex, entry)) { if (modifiedIndex == loopIndex) { @@ -792,7 +897,7 @@ bool Instance::RenameSupportedMap(uint32_t aMapId, const CharSpan & newMapName) ++loopIndex; } - if (!mDelegate->ModifySupportedMap(modifiedIndex, modifiedMap)) + if (!mStorageDelegate->ModifySupportedMapRaw(modifiedIndex, modifiedMap)) { return false; } @@ -810,7 +915,7 @@ bool Instance::ClearSupportedMaps() return false; } - if (mDelegate->ClearSupportedMaps()) + if (mStorageDelegate->ClearSupportedMapsRaw()) { ClearSupportedAreas(); NotifySupportedMapsChanged(); @@ -820,29 +925,88 @@ bool Instance::ClearSupportedMaps() return false; } +bool Instance::RemoveSupportedMap(uint32_t mapId) +{ + if (!mStorageDelegate->RemoveSupportedMapRaw(mapId)) + { + return false; + } + + NotifySupportedMapsChanged(); + + // If there are no supported maps left, none of the supported areas are vaild and their MapID needs to be null. + if (GetNumberOfSupportedMaps() == 0) + { + ClearSupportedAreas(); + return true; + } + + // Get the supported area IDs where the map ID matches the removed map ID. + uint32_t supportedAreaIdsBuffer[kMaxNumSupportedAreas]; + Span supportedAreaIdsSpan(supportedAreaIdsBuffer); + { + uint32_t supportedAreaIdsSize = 0; + uint32_t supportedAreasIndex = 0; + AreaStructureWrapper tempSupportedArea; + while (mStorageDelegate->GetSupportedAreaByIndex(supportedAreasIndex, tempSupportedArea)) + { + if (tempSupportedArea.mapID == mapId) + { + supportedAreaIdsSpan[supportedAreasIndex] = tempSupportedArea.areaID; + supportedAreaIdsSize++; + } + supportedAreasIndex++; + } + + supportedAreaIdsSpan.reduce_size(supportedAreaIdsSize); + } + + if (!supportedAreaIdsSpan.empty()) + { + for (uint32_t supportedAreaId : supportedAreaIdsSpan) + { + mStorageDelegate->RemoveSupportedAreaRaw(supportedAreaId); + } + HandleSupportedAreasUpdated(); + NotifySupportedAreasChanged(); + } + + return true; +} + //************************************************************************* // Selected Areas manipulators +uint32_t Instance::GetNumberOfSelectedAreas() +{ + return mStorageDelegate->GetNumberOfSelectedAreas(); +} + +bool Instance::GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) +{ + return mStorageDelegate->GetSelectedAreaByIndex(listIndex, selectedArea); +} + bool Instance::AddSelectedArea(uint32_t & aSelectedArea) { // check max# of list entries - if (mDelegate->GetNumberOfSelectedAreas() >= kMaxNumSelectedAreas) + if (GetNumberOfSelectedAreas() >= kMaxNumSelectedAreas) { - ChipLogError(Zcl, "AddSelectedArea %" PRIu32 " - maximum number of entries", aSelectedArea); + ChipLogError(Zcl, "AddSelectedAreaRaw %" PRIu32 " - maximum number of entries", aSelectedArea); return false; } // each item in this list SHALL match the AreaID field of an entry on the SupportedAreas attribute's list - if (!IsSupportedArea(aSelectedArea)) + if (!mStorageDelegate->IsSupportedArea(aSelectedArea)) { - ChipLogError(Zcl, "AddSelectedArea %" PRIu32 " - not a supported location", aSelectedArea); + ChipLogError(Zcl, "AddSelectedAreaRaw %" PRIu32 " - not a supported location", aSelectedArea); return false; } // each entry in this list SHALL have a unique value - if (mDelegate->IsSelectedArea(aSelectedArea)) + if (mStorageDelegate->IsSelectedArea(aSelectedArea)) { - ChipLogError(Zcl, "AddSelectedArea %" PRIu32 " - duplicated location", aSelectedArea); + ChipLogError(Zcl, "AddSelectedAreaRaw %" PRIu32 " - duplicated location", aSelectedArea); return false; } @@ -852,18 +1016,29 @@ bool Instance::AddSelectedArea(uint32_t & aSelectedArea) if (!mDelegate->IsSetSelectedAreasAllowed(locationStatusText)) { - ChipLogError(Zcl, "AddSelectedArea %" PRIu32 " - %.*s", aSelectedArea, static_cast(locationStatusText.size()), + ChipLogError(Zcl, "AddSelectedAreaRaw %" PRIu32 " - %.*s", aSelectedArea, static_cast(locationStatusText.size()), locationStatusText.data()); return false; } uint32_t ignoredIndex; - return mDelegate->AddSelectedArea(aSelectedArea, ignoredIndex); + return mStorageDelegate->AddSelectedAreaRaw(aSelectedArea, ignoredIndex); } bool Instance::ClearSelectedAreas() { - if (mDelegate->ClearSelectedAreas()) + if (mStorageDelegate->ClearSelectedAreasRaw()) + { + NotifySelectedAreasChanged(); + return true; + } + + return false; +} + +bool Instance::RemoveSelectedAreas(uint32_t areaId) +{ + if (mStorageDelegate->RemoveSelectedAreasRaw(areaId)) { NotifySelectedAreasChanged(); return true; @@ -884,7 +1059,7 @@ bool Instance::SetCurrentArea(const DataModel::Nullable & aCurrentArea { // If not null, the value of this attribute SHALL match the AreaID field of an entry on the SupportedAreas attribute's // list. - if ((!aCurrentArea.IsNull()) && (!IsSupportedArea(aCurrentArea.Value()))) + if ((!aCurrentArea.IsNull()) && (!mStorageDelegate->IsSupportedArea(aCurrentArea.Value()))) { ChipLogError(Zcl, "SetCurrentArea %" PRIu32 " - location is not supported", aCurrentArea.Value()); return false; @@ -940,27 +1115,42 @@ bool Instance::SetEstimatedEndTime(const DataModel::Nullable & aEstima //************************************************************************* // Progress list manipulators +uint32_t Instance::GetNumberOfProgressElements() +{ + return mStorageDelegate->GetNumberOfProgressElements(); +} + +bool Instance::GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + return mStorageDelegate->GetProgressElementByIndex(listIndex, aProgressElement); +} + +bool Instance::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + return mStorageDelegate->GetProgressElementById(aAreaId, listIndex, aProgressElement); +} + bool Instance::AddPendingProgressElement(uint32_t aAreaId) { // create progress element Structs::ProgressStruct::Type inactiveProgress = { aAreaId, OperationalStatusEnum::kPending }; // check max# of list entries - if (mDelegate->GetNumberOfProgressElements() >= kMaxNumProgressElements) + if (GetNumberOfProgressElements() >= kMaxNumProgressElements) { ChipLogError(Zcl, "AddPendingProgressElement - maximum number of entries"); return false; } // For each entry in this list, the AreaID field SHALL match an entry on the SupportedAreas attribute's list. - if (!IsSupportedArea(aAreaId)) + if (!mStorageDelegate->IsSupportedArea(aAreaId)) { ChipLogError(Zcl, "AddPendingProgressElement - not a supported location %" PRIu32 "", aAreaId); return false; } // Each entry in this list SHALL have a unique value for the AreaID field. - if (mDelegate->IsProgressElement(aAreaId)) + if (mStorageDelegate->IsProgressElement(aAreaId)) { ChipLogError(Zcl, "AddPendingProgressElement - progress element already exists for location %" PRIu32 "", aAreaId); return false; @@ -968,7 +1158,7 @@ bool Instance::AddPendingProgressElement(uint32_t aAreaId) uint32_t ignoredIndex; - if (!mDelegate->AddProgressElement(inactiveProgress, ignoredIndex)) + if (!mStorageDelegate->AddProgressElementRaw(inactiveProgress, ignoredIndex)) { return false; } @@ -982,7 +1172,7 @@ bool Instance::SetProgressStatus(uint32_t aAreaId, OperationalStatusEnum opStatu uint32_t listIndex; Structs::ProgressStruct::Type progressElement; - if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + if (!GetProgressElementById(aAreaId, listIndex, progressElement)) { ChipLogError(Zcl, "SetProgressStatus - progress element does not exist for location %" PRIu32 "", aAreaId); return false; @@ -1004,7 +1194,7 @@ bool Instance::SetProgressStatus(uint32_t aAreaId, OperationalStatusEnum opStatu } // add the updated element to the progress attribute - if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + if (!mStorageDelegate->ModifyProgressElementRaw(listIndex, progressElement)) { return false; } @@ -1018,7 +1208,7 @@ bool Instance::SetProgressTotalOperationalTime(uint32_t aAreaId, const DataModel uint32_t listIndex; Structs::ProgressStruct::Type progressElement; - if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + if (!GetProgressElementById(aAreaId, listIndex, progressElement)) { ChipLogError(Zcl, "SetProgressTotalOperationalTime - progress element does not exist for location %" PRIu32 "", aAreaId); return false; @@ -1047,7 +1237,7 @@ bool Instance::SetProgressTotalOperationalTime(uint32_t aAreaId, const DataModel progressElement.totalOperationalTime.Emplace(aTotalOperationalTime); // add the updated element to the progress attribute - if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + if (!mStorageDelegate->ModifyProgressElementRaw(listIndex, progressElement)) { return false; } @@ -1061,7 +1251,7 @@ bool Instance::SetProgressEstimatedTime(uint32_t aAreaId, const DataModel::Nulla uint32_t listIndex; Structs::ProgressStruct::Type progressElement; - if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + if (!GetProgressElementById(aAreaId, listIndex, progressElement)) { ChipLogError(Zcl, "SetProgressEstimatedTime - progress element does not exist for location %" PRIu32 "", aAreaId); return false; @@ -1077,7 +1267,7 @@ bool Instance::SetProgressEstimatedTime(uint32_t aAreaId, const DataModel::Nulla progressElement.estimatedTime.Emplace(aEstimatedTime); // add the updated element to the progress attribute - if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + if (!mStorageDelegate->ModifyProgressElementRaw(listIndex, progressElement)) { return false; } @@ -1088,7 +1278,18 @@ bool Instance::SetProgressEstimatedTime(uint32_t aAreaId, const DataModel::Nulla bool Instance::ClearProgress() { - if (mDelegate->ClearProgress()) + if (mStorageDelegate->ClearProgressRaw()) + { + NotifyProgressChanged(); + return true; + } + + return false; +} + +bool Instance::RemoveProgressElement(uint32_t areaId) +{ + if (mStorageDelegate->RemoveProgressElementRaw(areaId)) { NotifyProgressChanged(); return true; diff --git a/src/app/clusters/service-area-server/service-area-server.h b/src/app/clusters/service-area-server/service-area-server.h index e023f24d129261..1b2f72730402b9 100644 --- a/src/app/clusters/service-area-server/service-area-server.h +++ b/src/app/clusters/service-area-server/service-area-server.h @@ -20,6 +20,7 @@ #include "service-area-cluster-objects.h" #include "service-area-delegate.h" +#include "service-area-storage-delegate.h" #include #include @@ -56,7 +57,8 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface * * @note the caller must ensure that the delegate lives throughout the instance's lifetime. */ - Instance(Delegate * aDelegate, EndpointId aEndpointId, BitMask aFeature); + Instance(StorageDelegate * storageDelegate, Delegate * aDelegate, EndpointId aEndpointId, + BitMask aFeature); ~Instance() override; @@ -68,12 +70,15 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface /** * @brief Initialise the Service Area server instance. - * @return an error if the given endpoint and cluster Id have not been enabled in zap or if the - * CommandHandler or AttributeHandler registration fails, else CHIP_NO_ERROR. + * @return CHIP_NO_ERROR if there are on errors. Returns an error if + * - the given endpoint and cluster ID have not been enabled in zap + * - if the CommandHandler or AttributeHandler registration fails + * - if the StorageDelegate or Delegate initialisation fails. */ CHIP_ERROR Init(); private: + StorageDelegate * mStorageDelegate; Delegate * mDelegate; EndpointId mEndpointId; ClusterId mClusterId; @@ -137,12 +142,7 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface void NotifyProgressChanged(); //************************************************************************* - // Supported Areas manipulators - - /** - * @return true if an area with the aAreaId ID exists in the supported areas attribute. False otherwise. - */ - bool IsSupportedArea(uint32_t aAreaId); + // Supported Areas helpers /** * @brief Check if the given area adheres to the restrictions required by the supported areas attribute. @@ -167,7 +167,38 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface */ bool ReportEstimatedEndTimeChange(const DataModel::Nullable & aEstimatedEndTime); + /** + * This method will ensure that the values in the Selected Areas, Current Area and Progress attributes correspond to areas in + * the Supported Areas attribute. + * Any invalid area IDs in the Selected Areas attribute will be removed. + * If the Current Area is not in the Selected Areas attribute, it will be set to null. + * Any progres elements with area IDs not in the Selected Areas attribute will be removed. + */ + virtual void HandleSupportedAreasUpdated(); + public: + //************************************************************************* + // Supported Areas accessors and manipulators + + uint32_t GetNumberOfSupportedAreas(); + + /** + * @brief Get a supported area using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedArea a copy of the area contents, if found. + * @return true if an area is found, false otherwise. + */ + bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea); + + /** + * @brief Get a supported area that matches a areaID. + * @param[in] aAreaId the areaID to search for. + * @param[out] listIndex the area's index in the list, if found. + * @param[out] aSupportedArea a copy of the area contents, if found. + * @return true if an area is found, false otherwise. + */ + bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea); + /** * @brief Add new location to the supported locations list. * @param[in] aNewArea The area to add. @@ -195,13 +226,36 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface */ bool ClearSupportedAreas(); + /** + * Removes the supported area with areaId. + * If a supported area is removed, the Delegate's HandleSupportedAreasUpdated method is called to ensure that the + * SelectedAreas, CurrentArea, and Progress attributes remain valid. + * @param areaId The ID of the area to be removed. + * @return true if an area with the areaId was removed. False otherwise. + */ + bool RemoveSupportedArea(uint32_t areaId); + //************************************************************************* - // Supported Maps manipulators + // Supported Maps accessors and manipulators + + uint32_t GetNumberOfSupportedMaps(); + + /** + * @brief Get a supported map using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedMap copy of the map contents, if found. + * @return true if a supported map is found, false otherwise. + */ + bool GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap); /** - * @return true if a map with the aMapId ID exists in the supported maps attribute. False otherwise. + * @brief Get a supported map that matches a mapID. + * @param[in] aMapId the mapID to search for. + * @param[out] listIndex the map's index in the list, if found. + * @param[out] aSupportedMap copy of the location contents, if found. + * @return true if a supported map is found, false otherwise. */ - bool IsSupportedMap(uint32_t aMapId); + bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap); /** * @brief Add a new map to the supported maps list. @@ -228,8 +282,26 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface */ bool ClearSupportedMaps(); + /** + * Removes the supported map with mapId. + * If a supported map is removed, any supported areas that are no longer valid will also be removed. + * @param mapId the ID of the map to be removed. + * @return true if a map is removed. False otherwise. + */ + bool RemoveSupportedMap(uint32_t mapId); + //************************************************************************* - // Selected Areas manipulators + // Selected Areas accessors and manipulators + + uint32_t GetNumberOfSelectedAreas(); + + /** + * @brief Get a selected area using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] selectedArea the selected area value, if found. + * @return true if a selected area is found, false otherwise. + */ + bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea); /** * @brief Add a selected area. @@ -243,8 +315,14 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface */ bool ClearSelectedAreas(); + /** + * @param areaId the area ID to be removed from the SelectedAreas attribute. + * @return ture if this ID was removed, false otherwise. + */ + bool RemoveSelectedAreas(uint32_t areaId); + //************************************************************************* - // Current Area manipulators + // Current Area accessors and manipulators DataModel::Nullable GetCurrentArea(); @@ -258,7 +336,7 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface bool SetCurrentArea(const DataModel::Nullable & aCurrentArea); //************************************************************************* - // Estimated End Time manipulators + // Estimated End Time accessors and manipulators /** * @return The estimated epoch time in seconds when operation at the location indicated by the CurrentArea attribute will be @@ -274,7 +352,26 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface bool SetEstimatedEndTime(const DataModel::Nullable & aEstimatedEndTime); //************************************************************************* - // Progress list manipulators + // Progress list accessors and manipulators + + uint32_t GetNumberOfProgressElements(); + + /** + * @brief Get a progress element using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + */ + bool GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement); + + /** + * @brief Get a progress element that matches a areaID. + * @param[in] aAreaId the areaID to search for. + * @param[out] listIndex the location's index in the list, if found. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + */ + bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement); /** * @brief Add a progress element in a pending status to the progress list. @@ -314,6 +411,12 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface */ bool ClearProgress(); + /** + * @param areaId the area ID of the progress element to be removed. + * @return ture if the progress element was removed, false otherwise. + */ + bool RemoveProgressElement(uint32_t areaId); + //************************************************************************* // Feature Map attribute diff --git a/src/app/clusters/service-area-server/service-area-delegate.cpp b/src/app/clusters/service-area-server/service-area-storage-delegate.cpp similarity index 56% rename from src/app/clusters/service-area-server/service-area-delegate.cpp rename to src/app/clusters/service-area-server/service-area-storage-delegate.cpp index 9b63eb5b9f2496..43330fccba7697 100644 --- a/src/app/clusters/service-area-server/service-area-delegate.cpp +++ b/src/app/clusters/service-area-server/service-area-storage-delegate.cpp @@ -1,9 +1,8 @@ -#include "service-area-delegate.h" -#include "service-area-server.h" +#include "service-area-storage-delegate.h" using namespace chip::app::Clusters::ServiceArea; -bool Delegate::GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea) +bool StorageDelegate::GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea) { listIndex = 0; @@ -21,14 +20,20 @@ bool Delegate::GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, Area return false; } -void Delegate::HandleSupportedAreasUpdated() +bool StorageDelegate::IsSupportedArea(uint32_t aAreaId) { - mInstance->ClearSelectedAreas(); - mInstance->SetCurrentArea(DataModel::NullNullable); - mInstance->ClearProgress(); + uint32_t ignoredIndex; + AreaStructureWrapper ignoredArea; + + return GetSupportedAreaById(aAreaId, ignoredIndex, ignoredArea); } -bool Delegate::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) +bool StorageDelegate::RemoveSupportedAreaRaw(uint32_t areaId) +{ + return false; +} + +bool StorageDelegate::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) { listIndex = 0; @@ -45,7 +50,20 @@ bool Delegate::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStr return false; } -bool Delegate::IsSelectedArea(uint32_t aAreaId) +bool StorageDelegate::IsSupportedMap(uint32_t aMapId) +{ + uint32_t ignoredIndex; + MapStructureWrapper ignoredMap; + + return GetSupportedMapById(aMapId, ignoredIndex, ignoredMap); +} + +bool StorageDelegate::RemoveSupportedMapRaw(uint32_t mapId) +{ + return false; +} + +bool StorageDelegate::IsSelectedArea(uint32_t aAreaId) { uint32_t listIndex = 0; uint32_t selectedArea; @@ -63,7 +81,8 @@ bool Delegate::IsSelectedArea(uint32_t aAreaId) return false; } -bool Delegate::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement) +bool StorageDelegate::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, + Structs::ProgressStruct::Type & aProgressElement) { listIndex = 0; @@ -81,7 +100,7 @@ bool Delegate::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, St return false; } -bool Delegate::IsProgressElement(uint32_t aAreaId) +bool StorageDelegate::IsProgressElement(uint32_t aAreaId) { uint32_t index; Structs::ProgressStruct::Type progressElement; @@ -89,5 +108,5 @@ bool Delegate::IsProgressElement(uint32_t aAreaId) return GetProgressElementById(aAreaId, index, progressElement); } -// todo: Should we add default implementations for the accessor methods of the non-mandatory attributes? +// todo: Should we add default implementations for the accessor methods of the optional attributes? // This is so that devices that do not support these attributes are not forced to provide an implementation. diff --git a/src/app/clusters/service-area-server/service-area-storage-delegate.h b/src/app/clusters/service-area-server/service-area-storage-delegate.h new file mode 100644 index 00000000000000..2ad0f0674d9d77 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-storage-delegate.h @@ -0,0 +1,280 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "service-area-cluster-objects.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ServiceArea { + +/** + * ServiceArea::StorageDelegate Defines methods for implementing target/application-specific + * logic for managing the storage of some Service Area cluster attributes. + */ +class StorageDelegate +{ +public: + StorageDelegate() = default; + virtual ~StorageDelegate() = default; + + /** + * @brief This method will be called during the ServiceArea server initialization after the Instance information has been + * validated and the Instance has been registered. This can be used to initialise the memory required. + */ + virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; }; + + //************************************************************************* + // Supported Areas accessors and manipulators + + virtual uint32_t GetNumberOfSupportedAreas() = 0; + + /** + * @brief Get a supported area using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedArea a copy of the area contents, if found. + * @return true if an area is found, false otherwise. + */ + virtual bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea) = 0; + + /** + * @brief Get a supported area that matches a areaID. + * @param[in] aAreaId the areaID to search for. + * @param[out] listIndex the area's index in the list, if found. + * @param[out] aSupportedArea a copy of the area contents, if found. + * @return true if an area is found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea); + + /** + * @return true if an area with the aAreaId ID exists in the supported areas attribute. False otherwise. + */ + virtual bool IsSupportedArea(uint32_t aAreaId); + + /** + * This method is called by the server instance to add a new area to the list. + * The server instance will ensure that the newArea is a valid, unique area. + * @param [in] newArea new area to add. + * @param [out] listIndex filled with the list index for the new area, if successful. + * @return true if successful, false otherwise. + + * @note this method SHOULD double check that the added area won't exceed the maximum list size. + */ + virtual bool AddSupportedAreaRaw(const AreaStructureWrapper & newArea, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing area in the list. + * The server instance will ensure that the modifiedArea is a valid, unique area. + * @param[in] listIndex The index of the area being modified. + * @param[in] modifiedArea An area with the modified contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that newArea's areaID matches the object at listIndex. + */ + virtual bool ModifySupportedAreaRaw(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) = 0; + + /** + * @return true if supported locations was not already null, false otherwise. + */ + virtual bool ClearSupportedAreasRaw() = 0; + + /** + * @param areaId the ID af the area to be removed. + * @return true if the area was removed, false otherwise. + */ + virtual bool RemoveSupportedAreaRaw(uint32_t areaId); + + //************************************************************************* + // Supported Maps accessors and manipulators + + virtual uint32_t GetNumberOfSupportedMaps() = 0; + + /** + * @brief Get a supported map using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedMap copy of the map contents, if found. + * @return true if a supported map is found, false otherwise. + */ + virtual bool GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) = 0; + + /** + * @brief Get a supported map that matches a mapID. + * @param[in] aMapId the mapID to search for. + * @param[out] listIndex the map's index in the list, if found. + * @param[out] aSupportedMap copy of the location contents, if found. + * @return true if a supported map is found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap); + + /** + * @return true if a map with the aMapId ID exists in the supported maps attribute. False otherwise. + */ + bool IsSupportedMap(uint32_t aMapId); + + /** + * This method is called by the server instance to add a new map to the list. + * The server instance will ensure that the newMap is a valid, unique map. + * @param[in] newMap The new map to add. + * @param[out] listIndex filled with the list index of the new map, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added map won't exceed the maximum list size + */ + virtual bool AddSupportedMapRaw(const MapStructureWrapper & newMap, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing map in the list. + * The server instance will ensure that the modifiedMap is a valid, unique map. + * @param[in] listIndex The index of the map being modified. + * @param[in] modifiedMapA map with the modified contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that modifiedMap's mapID matches the object at listIndex. + */ + virtual bool ModifySupportedMapRaw(uint32_t listIndex, const MapStructureWrapper & modifiedMap) = 0; + + /** + * @return true if supported maps was not already null, false otherwise. + */ + virtual bool ClearSupportedMapsRaw() = 0; + + /** + * @param mapId the ID of the map to be removed. + * @return true if a map is removed. False otherwise. + */ + virtual bool RemoveSupportedMapRaw(uint32_t mapId); + + //************************************************************************* + // Selected Areas accessors and manipulators + + virtual uint32_t GetNumberOfSelectedAreas() = 0; + + /** + * @brief Get a selected area using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] selectedArea the selected area value, if found. + * @return true if a selected area is found, false otherwise. + */ + virtual bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) = 0; + + /** + * @return true if the aAreaId areaID is found in the SelectedAreas list, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool IsSelectedArea(uint32_t aAreaId); + + /** + * This method is called by the server instance to add a new selected area to the list. + * The server instance will ensure that the aAreaId references a SUPPORTED area, and is unique within selected + * areas. + * @param[in] aAreaId The new areaID to add. + * @param[out] listIndex filled with the list index of the new area, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added area won't exceed the maximum list size. + */ + virtual bool AddSelectedAreaRaw(uint32_t aAreaId, uint32_t & listIndex) = 0; + + /** + * @return true if selected locations was not already null, false otherwise. + */ + virtual bool ClearSelectedAreasRaw() = 0; + + /** + * @param areaId the area ID to be removed from the SelectedAreas attribute. + * @return ture if this ID was removed, false otherwise. + */ + virtual bool RemoveSelectedAreasRaw(uint32_t areaId) = 0; + + //************************************************************************* + // Progress accessors and manipulators + + virtual uint32_t GetNumberOfProgressElements() = 0; + + /** + * @brief Get a progress element using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + */ + virtual bool GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) = 0; + + /** + * @brief Get a progress element that matches a areaID. + * @param[in] aAreaId the areaID to search for. + * @param[out] listIndex the location's index in the list, if found. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement); + + /** + * @brief Is the progress element in the progress list? + * @param[in] aAreaId location id of the progress element. + * @return true if the progress element identified by Id is in the progress list. + */ + virtual bool IsProgressElement(uint32_t aAreaId); + + /** + * This method is called by the server instance to add a new progress element to the list. + * The server instance will ensure that the newProgressElement is a valid, unique progress element. + * @param[in] newProgressElement The new element to add. + * @param[out] listIndex is filled with the list index for the new element, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added element won't exceed the maximum list size. + */ + virtual bool AddProgressElementRaw(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing progress element in the list. + * The server instance will ensure that the modifiedProgressElement is a valid and unique progress element. + * @param[in] listIndex The list index of the progress element being modified. + * @param[in] modifiedProgressElement modified element's contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that modifiedProgressElement's areaID matches the object at listIndex + */ + virtual bool ModifyProgressElementRaw(uint32_t listIndex, const Structs::ProgressStruct::Type & modifiedProgressElement) = 0; + + /** + * @return true if progress list was not already null, false otherwise. + */ + virtual bool ClearProgressRaw() = 0; + + /** + * @param areaId the area ID of the progress element to be removed. + * @return ture if the progress element was removed, false otherwise. + */ + virtual bool RemoveProgressElementRaw(uint32_t areaId) = 0; +}; + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip From a6f083eb3207c9e317852b0e0f430597700847ce Mon Sep 17 00:00:00 2001 From: achaulk-goog <107196446+achaulk-goog@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:08:24 -0400 Subject: [PATCH 17/70] Fix kotlin tests, remove unused code (#32880) * Fix kotlin tests, remove unused code assertThat(false) doesn't actually do anythung, it returns an object you can then make assertions against, use assertTrue instead testQRCodeWithOptionalData relied upon an implicit ordering, however the underlying representation (HashMap) is unordered * re-add line with unused val * Revert val unused = --- .../QRCodeBasicOnboardingPayloadGenerator.kt | 3 -- .../onboardingpayload/ManualCodeTest.kt | 27 ++++++++--------- .../matter/onboardingpayload/QRCodeTest.kt | 29 ++++++++++--------- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt b/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt index 853b3308953afd..49befbdb675d44 100644 --- a/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt +++ b/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt @@ -68,9 +68,6 @@ fun payloadBase38RepresentationWithTLV( // Copy the subBuffer back to the outBuffer subBuffer.copyInto(outBuffer, prefixLen) - - // Reduce output buffer size to be the size of written data - outBuffer.copyOf(prefixLen + subBuffer.size) } } diff --git a/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt b/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt index 900a3eb1a7ff72..42e60e7bfac37d 100644 --- a/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt +++ b/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt @@ -24,6 +24,7 @@ import kotlin.math.ceil import kotlin.math.log10 import kotlin.math.pow import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -444,7 +445,7 @@ class ManualCodeTest { // Override the discriminator in the input payload with the short version, // since that's what we will produce. inPayload.setShortDiscriminatorValue(inPayload.getShortDiscriminatorValue()) - assertThat(inPayload == outPayload) + assertEquals(inPayload, outPayload) } /* @@ -464,7 +465,7 @@ class ManualCodeTest { // Override the discriminator in the input payload with the short version, // since that's what we will produce. inPayload.setShortDiscriminatorValue(inPayload.getShortDiscriminatorValue()) - assertThat(inPayload == outPayload) + assertEquals(inPayload, outPayload) } /* @@ -479,7 +480,7 @@ class ManualCodeTest { try { ManualOnboardingPayloadParser.checkDecimalStringValidity(representationWithoutCheckDigit) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -487,7 +488,7 @@ class ManualCodeTest { representationWithoutCheckDigit = "1" try { ManualOnboardingPayloadParser.checkDecimalStringValidity(representationWithoutCheckDigit) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -516,28 +517,28 @@ class ManualCodeTest { try { ManualOnboardingPayloadParser.checkCodeLengthValidity("01234567891", false) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } try { ManualOnboardingPayloadParser.checkCodeLengthValidity("012345678", false) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } try { ManualOnboardingPayloadParser.checkCodeLengthValidity("012345678901234567891", true) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } try { ManualOnboardingPayloadParser.checkCodeLengthValidity("0123456789012345678", true) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -562,14 +563,14 @@ class ManualCodeTest { try { ManualOnboardingPayloadParser.toNumber("012345.123456789") - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } try { ManualOnboardingPayloadParser.toNumber("/") - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -631,14 +632,14 @@ class ManualCodeTest { try { index.set(1) ManualOnboardingPayloadParser.readDigitsFromDecimalString("12345", index, 5) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } try { ManualOnboardingPayloadParser.readDigitsFromDecimalString("12", index, 5) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -646,7 +647,7 @@ class ManualCodeTest { try { index.set(200) ManualOnboardingPayloadParser.readDigitsFromDecimalString("6256276377282", index, 1) - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } diff --git a/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt b/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt index 62dff45174b7ed..4cc9477521e3fc 100644 --- a/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt +++ b/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt @@ -20,6 +20,7 @@ package matter.onboardingpayload import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -224,7 +225,7 @@ class QRCodeTest { try { QRCodeOnboardingPayloadParser(invalidString).populatePayload() - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -240,7 +241,7 @@ class QRCodeTest { try { QRCodeOnboardingPayloadParser(invalidString).populatePayload() - assertThat(false) + assertTrue(false) } catch (e: Exception) { println("Expected exception occurred: ${e.message}") } @@ -396,21 +397,21 @@ class QRCodeTest { // verify we can grab just the serial number as well assertThat(parsedQrCode.getSerialNumber()).isEqualTo("123456789") - // Test 2nd optional field - optionalQRCodeInfo = OptionalQRCodeInfoExtension() - optionalQRCodeInfo.tag = 130 - optionalQRCodeInfo.type = OptionalQRCodeInfoType.TYPE_STRING - optionalQRCodeInfo.data = "myData" + val optionalQRCodeInfo1 = OptionalQRCodeInfoExtension() + optionalQRCodeInfo1.tag = 130 + optionalQRCodeInfo1.type = OptionalQRCodeInfoType.TYPE_STRING + optionalQRCodeInfo1.data = "myData" - assertThat(parsedQrCode.getAllOptionalVendorData()[0]).isEqualTo(optionalQRCodeInfo) + val optionalQRCodeInfo2 = OptionalQRCodeInfoExtension() + optionalQRCodeInfo2.tag = 131 + optionalQRCodeInfo2.type = OptionalQRCodeInfoType.TYPE_INT32 + optionalQRCodeInfo2.int32 = 12 - // Test 3rd optional field - optionalQRCodeInfo = OptionalQRCodeInfoExtension() - optionalQRCodeInfo.tag = 131 - optionalQRCodeInfo.type = OptionalQRCodeInfoType.TYPE_INT32 - optionalQRCodeInfo.int32 = 12 + val vendor1 = parsedQrCode.getAllOptionalVendorData()[0] + val vendor2 = parsedQrCode.getAllOptionalVendorData()[1] - assertThat(parsedQrCode.getAllOptionalVendorData()[1]).isEqualTo(optionalQRCodeInfo) + assertTrue(vendor1 == optionalQRCodeInfo1 || vendor1 == optionalQRCodeInfo2) + assertTrue(vendor2 == optionalQRCodeInfo1 || vendor2 == optionalQRCodeInfo2) } companion object { From 34098d2492ad25dba2217efcc2a1e195b17b7cef Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 3 Sep 2024 18:57:44 +0200 Subject: [PATCH 18/70] Add fabric-sync-app to TH image (#35367) * Add fabric-sync-app to TH image * Search PATH for fabric-admin and fabric-bridge-app * Apply suggestions from code review Co-authored-by: Andrei Litvin --------- Co-authored-by: Andrei Litvin --- examples/fabric-admin/scripts/fabric-sync-app.py | 12 +++++++++--- integrations/docker/images/chip-cert-bins/Dockerfile | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/fabric-admin/scripts/fabric-sync-app.py b/examples/fabric-admin/scripts/fabric-sync-app.py index c6faed8b67ac00..2a8508231f8fa0 100755 --- a/examples/fabric-admin/scripts/fabric-sync-app.py +++ b/examples/fabric-admin/scripts/fabric-sync-app.py @@ -17,6 +17,7 @@ import asyncio import contextlib import os +import shutil import signal import sys from argparse import ArgumentParser @@ -286,10 +287,10 @@ def terminate(signum, frame): if __name__ == "__main__": parser = ArgumentParser(description="Fabric-Sync Example Application") parser.add_argument("--app-admin", metavar="PATH", - default="out/linux-x64-fabric-admin-rpc/fabric-admin", + default=shutil.which("fabric-admin"), help="path to the fabric-admin executable; default=%(default)s") parser.add_argument("--app-bridge", metavar="PATH", - default="out/linux-x64-fabric-bridge-rpc/fabric-bridge-app", + default=shutil.which("fabric-bridge-app"), help="path to the fabric-bridge executable; default=%(default)s") parser.add_argument("--app-admin-rpc-port", metavar="PORT", type=int, help="fabric-admin RPC server port") @@ -314,5 +315,10 @@ def terminate(signum, frame): help="discriminator to use for the bridge") parser.add_argument("--passcode", metavar="NUM", type=int, help="passcode to use for the bridge") + args = parser.parse_args() + if args.app_admin is None or not os.path.exists(args.app_admin): + parser.error("fabric-admin executable not found in PATH. Use '--app-admin' argument to provide it.") + if args.app_bridge is None or not os.path.exists(args.app_bridge): + parser.error("fabric-bridge-app executable not found in PATH. Use '--app-bridge' argument to provide it.") with contextlib.suppress(KeyboardInterrupt): - asyncio.run(main(parser.parse_args())) + asyncio.run(main(args)) diff --git a/integrations/docker/images/chip-cert-bins/Dockerfile b/integrations/docker/images/chip-cert-bins/Dockerfile index b8a1b1f6022af2..c5f04d53d12db8 100644 --- a/integrations/docker/images/chip-cert-bins/Dockerfile +++ b/integrations/docker/images/chip-cert-bins/Dockerfile @@ -306,6 +306,7 @@ COPY --from=chip-build-cert-bins /root/connectedhomeip/out/lit-icd-app lit-icd-a COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-energy-management-app chip-energy-management-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-microwave-oven-app chip-microwave-oven-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-rvc-app chip-rvc-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/examples/fabric-admin/scripts/fabric-sync-app.py fabric-sync-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/fabric-bridge-app fabric-bridge-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/fabric-admin fabric-admin COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lighting-data-model-no-unique-id-app chip-lighting-data-model-no-unique-id-app From ea859c67dc82ccc226f0dfced4627e9123a9f415 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 3 Sep 2024 13:04:42 -0400 Subject: [PATCH 19/70] TC-IDM-10.2: Get provisional cluster status from spec (#35081) * TC-IDM-10.2: Get provisional cluster status from spec Test: Please see unit tests. Also runs in CI against the door lock cluster. * Restyled by isort * linter * fix ci * move cluster revision numbers up --------- Co-authored-by: Restyled.io --- .github/workflows/tests.yaml | 2 + src/python_testing/TC_DeviceConformance.py | 34 ++--- src/python_testing/TestConformanceTest.py | 140 +++++++++++++++++++ src/python_testing/TestSpecParsingSupport.py | 49 +++++++ src/python_testing/execute_python_tests.py | 1 + src/python_testing/spec_parsing_support.py | 11 +- 6 files changed, 216 insertions(+), 21 deletions(-) create mode 100644 src/python_testing/TestConformanceTest.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 5265f82b09454c..9fcfc5cc5c033c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -521,6 +521,8 @@ jobs: scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingDeviceType.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingSupport.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceTest.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceSupport.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestChoiceConformanceSupport.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_IDM_10_4.py' diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 3cc57e2b018ab6..060228a5170f17 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -50,7 +50,7 @@ async def setup_class_helper(self): self.xml_device_types, problems = build_xml_device_types() self.problems.extend(problems) - def check_conformance(self, ignore_in_progress: bool, is_ci: bool): + def check_conformance(self, ignore_in_progress: bool, is_ci: bool, allow_provisional: bool): problems = [] success = True @@ -87,32 +87,27 @@ def record_warning(location, problem): ignore_attributes.update(ci_ignore_attributes) success = True - allow_provisional = self.user_params.get("allow_provisional", False) - # TODO: automate this once https://github.com/csa-data-model/projects/issues/454 is done. - provisional_cluster_ids = [Clusters.ContentControl.id, Clusters.ScenesManagement.id, Clusters.BallastConfiguration.id, - Clusters.EnergyPreference.id, Clusters.DeviceEnergyManagement.id, Clusters.DeviceEnergyManagementMode.id, Clusters.PulseWidthModulation.id, - Clusters.ProxyConfiguration.id, Clusters.ProxyDiscovery.id, Clusters.ProxyValid.id] - # TODO: Remove this once the latest 1.3 lands with the clusters removed from the DM XML and change the warning below about missing DM XMLs into a proper error - # These are clusters that weren't part of the 1.3 spec that landed in the SDK before the branch cut + provisional_cluster_ids = [] + # TODO: Remove this once we have a scrape without items not going to the test events + # These are clusters that weren't part of the 1.3 or 1.4 spec that landed in the SDK before the branch cut + # They're not marked provisional, but are present in the ToT spec under an ifdef. provisional_cluster_ids.extend([Clusters.DemandResponseLoadControl.id]) - # These clusters are zigbee only. I don't even know why they're part of the codegen, but we should get rid of them. - provisional_cluster_ids.extend([Clusters.BarrierControl.id, Clusters.OnOffSwitchConfiguration.id, - Clusters.BinaryInputBasic.id, Clusters.ElectricalMeasurement.id]) + for endpoint_id, endpoint in self.endpoints_tlv.items(): for cluster_id, cluster in endpoint.items(): cluster_location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id) - if not allow_provisional and cluster_id in provisional_cluster_ids: - record_error(location=cluster_location, problem='Provisional cluster found on device') - continue - if cluster_id not in self.xml_clusters.keys(): if (cluster_id & 0xFFFF_0000) != 0: # manufacturer cluster continue - # TODO: update this from a warning once we have all the data - record_warning(location=cluster_location, - problem='Standard cluster found on device, but is not present in spec data') + record_error(location=cluster_location, + problem='Standard cluster found on device, but is not present in spec data') + continue + + is_provisional = cluster_id in provisional_cluster_ids or self.xml_clusters[cluster_id].is_provisional + if not allow_provisional and is_provisional: + record_error(location=cluster_location, problem='Provisional cluster found on device') continue feature_map = cluster[GlobalAttributeIds.FEATURE_MAP_ID] @@ -340,7 +335,8 @@ def test_TC_IDM_10_2(self): # https://github.com/project-chip/connectedhomeip/issues/34615 ignore_in_progress = self.user_params.get("ignore_in_progress", True) is_ci = self.check_pics('PICS_SDK_CI_ONLY') - success, problems = self.check_conformance(ignore_in_progress, is_ci) + allow_provisional = self.user_params.get("allow_provisional", False) + success, problems = self.check_conformance(ignore_in_progress, is_ci, allow_provisional) self.problems.extend(problems) if not success: self.fail_current_test("Problems with conformance") diff --git a/src/python_testing/TestConformanceTest.py b/src/python_testing/TestConformanceTest.py new file mode 100644 index 00000000000000..23b06fb67c7e2a --- /dev/null +++ b/src/python_testing/TestConformanceTest.py @@ -0,0 +1,140 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from typing import Any + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts +from spec_parsing_support import build_xml_clusters, build_xml_device_types +from TC_DeviceConformance import DeviceConformanceTests + + +def create_onoff_endpoint(endpoint: int) -> dict[int, dict[int, dict[int, Any]]]: + # Really simple device with one endpoint that includes scenes management, which is provisional + # I'm ONLY populating the global attributes since the conformance test only uses these. + endpoint_tlv = {endpoint: {}} + + on_off_device_type_id = 0x0100 + on_off_device_type_revision = 3 + descriptor_cluster_revision = 3 + identify_cluster_revision = 5 + on_off_cluster_revision = 6 + scenes_cluster_revision = 1 + + # Descriptor + attr = Clusters.Descriptor.Attributes + attrs = {} + attrs[attr.FeatureMap.attribute_id] = 0 + attrs[attr.AcceptedCommandList.attribute_id] = [] + attrs[attr.GeneratedCommandList.attribute_id] = [] + attrs[attr.ClusterRevision.attribute_id] = descriptor_cluster_revision + attrs[attr.DeviceTypeList.attribute_id] = [Clusters.Descriptor.Structs.DeviceTypeStruct( + deviceType=on_off_device_type_id, revision=on_off_device_type_revision)] + attrs[attr.ServerList.attribute_id] = [Clusters.Identify.id, + Clusters.Groups.id, Clusters.ScenesManagement.id, Clusters.OnOff.id] + attrs[attr.ClientList.attribute_id] = [] + attrs[attr.PartsList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = list[attrs.keys()] + + endpoint_tlv[endpoint][Clusters.Descriptor.id] = attrs + + # Identify + attr = Clusters.Identify.Attributes + attrs = {} + attrs[attr.FeatureMap.attribute_id] = 0 + attrs[attr.AcceptedCommandList.attribute_id] = [Clusters.Identify.Commands.Identify.command_id] + attrs[attr.GeneratedCommandList.attribute_id] = [] + attrs[attr.ClusterRevision.attribute_id] = identify_cluster_revision + attrs[attr.IdentifyTime.attribute_id] = 0 + attrs[attr.IdentifyType.attribute_id] = Clusters.Identify.Enums.IdentifyTypeEnum.kNone + attrs[attr.AttributeList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = list[attrs.keys()] + + endpoint_tlv[endpoint][Clusters.Identify.id] = attrs + + # OnOff + attr = Clusters.OnOff.Attributes + attrs = {} + # device type requires LT feature + attrs[attr.FeatureMap.attribute_id] = Clusters.OnOff.Bitmaps.Feature.kLighting + cmd = Clusters.OnOff.Commands + attrs[attr.AcceptedCommandList.attribute_id] = [cmd.Off.command_id, cmd.On.command_id, cmd.Toggle.command_id, + cmd.OffWithEffect.command_id, cmd.OnWithRecallGlobalScene.command_id, cmd.OnWithTimedOff.command_id] + attrs[attr.GeneratedCommandList.attribute_id] = [] + attrs[attr.ClusterRevision.attribute_id] = on_off_cluster_revision + attrs[attr.OnOff.attribute_id] = False + attrs[attr.GlobalSceneControl.attribute_id] = False + attrs[attr.OnTime.attribute_id] = 0 + attrs[attr.OffWaitTime.attribute_id] = 0 + attrs[attr.StartUpOnOff.attribute_id] = Clusters.OnOff.Enums.StartUpOnOffEnum.kOff + attrs[attr.AttributeList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = list[attrs.keys()] + + endpoint_tlv[endpoint][Clusters.OnOff.id] = attrs + + # Scenes + attr = Clusters.ScenesManagement.Attributes + attrs = {} + attrs[attr.FeatureMap.attribute_id] = 0 + cmd = Clusters.ScenesManagement.Commands + attrs[attr.AcceptedCommandList.attribute_id] = [cmd.AddScene.command_id, cmd.ViewScene.command_id, cmd.RemoveScene.command_id, + cmd.RemoveAllScenes.command_id, cmd.StoreScene.command_id, cmd.RecallScene.command_id, cmd.GetSceneMembership.command_id] + attrs[attr.GeneratedCommandList.attribute_id] = [cmd.AddSceneResponse.command_id, cmd.ViewSceneResponse.command_id, + cmd.RemoveSceneResponse.command_id, cmd.RemoveAllScenesResponse.command_id, + cmd.StoreSceneResponse.command_id, cmd.GetSceneMembershipResponse.command_id] + attrs[attr.ClusterRevision.attribute_id] = scenes_cluster_revision + attrs[attr.SceneTableSize.attribute_id] = 16 + attrs[attr.FabricSceneInfo.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = list[attrs.keys()] + + endpoint_tlv[endpoint][Clusters.ScenesManagement.id] = attrs + + return endpoint_tlv + + +class TestConformanceSupport(MatterBaseTest, DeviceConformanceTests): + def setup_class(self): + self.xml_clusters, self.problems = build_xml_clusters() + self.xml_device_types, problems = build_xml_device_types() + self.problems.extend(problems) + + @async_test_body + async def test_provisional_cluster(self): + # NOTE: I'm actually FORCING scenes to provisional in this test because it will not be provisional + # forever. + self.xml_clusters[Clusters.ScenesManagement.id].is_provisional = True + + self.endpoints_tlv = create_onoff_endpoint(1) + + # The CI flag here is to deal with example code that improperly implements the network commissioning cluster. + # It does not apply here. + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=False) + asserts.assert_false(success, "Unexpected success parsing endpoint with provisional cluster") + + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True) + asserts.assert_true(success, "Unexpected failure parsing endpoint with provisional cluster and allow_provisional enabled") + + self.xml_clusters[Clusters.ScenesManagement.id].is_provisional = False + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=False) + asserts.assert_true(success, "Unexpected failure parsing endpoint with no clusters marked as provisional") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index 1741f8dba1a869..aa2a68427607e4 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -19,6 +19,7 @@ import xml.etree.ElementTree as ElementTree import chip.clusters as Clusters +import jinja2 from global_attribute_ids import GlobalAttributeIds from matter_testing_support import MatterBaseTest, ProblemNotice, default_matter_test_main from mobly import asserts @@ -225,6 +226,28 @@ def get_access_enum_from_string(access_str: str) -> Clusters.AccessControl.Enums '' ) +PROVISIONAL_CLUSTER_TEMPLATE = """ + + + + + + + {% if provisional %} + + {% endif %} + + + + + + + + + + +""" + class TestSpecParsingSupport(MatterBaseTest): def setup_class(self): @@ -413,6 +436,32 @@ def test_known_derived_clusters(self): for d in known_derived_clusters: asserts.assert_true(self.spec_xml_clusters is not None, "Derived cluster with no base cluster marker") + def test_provisional_clusters(self): + clusters: dict[int, XmlCluster] = {} + pure_base_clusters: dict[str, XmlCluster] = {} + ids_by_name: dict[str, int] = {} + problems: list[ProblemNotice] = [] + id = 0x0001 + + environment = jinja2.Environment() + template = environment.from_string(PROVISIONAL_CLUSTER_TEMPLATE) + + provisional = template.render(provisional=True, id=id) + cluster_xml = ElementTree.fromstring(provisional) + add_cluster_data_from_xml(cluster_xml, clusters, pure_base_clusters, ids_by_name, problems) + + asserts.assert_equal(len(problems), 0, "Unexpected problems parsing provisional cluster") + asserts.assert_in(id, clusters.keys(), "Provisional cluster not parsed") + asserts.assert_true(clusters[id].is_provisional, "Provisional cluster not marked as provisional") + + non_provisional = template.render(provisional=False, id=id) + cluster_xml = ElementTree.fromstring(non_provisional) + add_cluster_data_from_xml(cluster_xml, clusters, pure_base_clusters, ids_by_name, problems) + + asserts.assert_equal(len(problems), 0, "Unexpected problems parsing non-provisional cluster") + asserts.assert_in(id, clusters.keys(), "Non-provisional cluster not parsed") + asserts.assert_false(clusters[id].is_provisional, "Non-provisional cluster marked as provisional") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/execute_python_tests.py b/src/python_testing/execute_python_tests.py index 1f6afa9d7035fd..a1965ec6360392 100644 --- a/src/python_testing/execute_python_tests.py +++ b/src/python_testing/execute_python_tests.py @@ -87,6 +87,7 @@ def main(search_directory, env_file): "choice_conformance_support.py", "TestIdChecks.py", "TestSpecParsingDeviceType.py", + "TestConformanceTest.py", "TestMatterTestingSupport.py", "TestSpecParsingSupport.py", "TestTimeSyncTrustedTimeSource.py", diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 867c8a91e3ea58..b279c759641249 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -108,6 +108,7 @@ class XmlCluster: unknown_commands: list[XmlCommand] events: dict[uint, XmlEvent] pics: str + is_provisional: bool class ClusterSide(Enum): @@ -206,6 +207,7 @@ def __init__(self, cluster, cluster_id, name): self._name = name self._derived = None + self._is_provisional = False try: classification = next(cluster.iter('classification')) hierarchy = classification.attrib['hierarchy'] @@ -214,6 +216,9 @@ def __init__(self, cluster, cluster_id, name): except (KeyError, StopIteration): self._derived = None + if list(cluster.iter('provisionalConform')): + self._is_provisional = True + try: classification = next(cluster.iter('classification')) self._pics = classification.attrib['picsCode'] @@ -451,7 +456,7 @@ def create_cluster(self) -> XmlCluster: accepted_commands=self.parse_commands(CommandType.ACCEPTED), generated_commands=self.parse_commands(CommandType.GENERATED), unknown_commands=self.parse_unknown_commands(), - events=self.parse_events(), pics=self._pics) + events=self.parse_events(), pics=self._pics, is_provisional=self._is_provisional) def get_problems(self) -> list[ProblemNotice]: return self._problems @@ -666,11 +671,13 @@ def combine_attributes(base: dict[uint, XmlAttribute], derived: dict[uint, XmlAt generated_commands[cmd.id].conformance = cmd.conformance else: unknown_commands.append(cmd) + provisional = c.is_provisional or base.is_provisional new = XmlCluster(revision=c.revision, derived=c.derived, name=c.name, feature_map=feature_map, attribute_map=attribute_map, command_map=command_map, features=features, attributes=attributes, accepted_commands=accepted_commands, - generated_commands=generated_commands, unknown_commands=unknown_commands, events=events, pics=c.pics) + generated_commands=generated_commands, unknown_commands=unknown_commands, events=events, pics=c.pics, + is_provisional=provisional) xml_clusters[id] = new From ae4ee1c4fd5a21b3ac29075711421e5cc8a6ec4c Mon Sep 17 00:00:00 2001 From: Anu Biradar <104591549+abiradarti@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:16:11 -0500 Subject: [PATCH 20/70] [TI] Enable LIT ICD support for CC13x4_26x4, remove all-clusters-app (#35295) * Enable LIT, CIP and UAT support for CC13x4_26x4, and remove CC13x4 all-clusters-app * restyled changes * misspell correction * remove TI All Clusters ref from darwin.md * empty commit --- docs/guides/darwin.md | 1 - .../enabling_icd_on_ti_devices.md | 29 +- examples/all-clusters-app/cc13x4_26x4/.gn | 30 - .../all-clusters-app/cc13x4_26x4/BUILD.gn | 141 ----- .../all-clusters-app/cc13x4_26x4/README.md | 310 ----------- .../all-clusters-app/cc13x4_26x4/args.gni | 72 --- .../cc13x4_26x4/build_overrides | 1 - .../all-clusters-app/cc13x4_26x4/chip.syscfg | 241 -------- .../cc13x4_26x4/main/AppTask.cpp | 527 ------------------ .../cc13x4_26x4/main/ClusterManager.cpp | 177 ------ .../cc13x4_26x4/main/Globals.cpp | 24 - .../cc13x4_26x4/main/ZclCallbacks.cpp | 81 --- .../cc13x4_26x4/main/include/AppConfig.h | 21 - .../cc13x4_26x4/main/include/AppEvent.h | 60 -- .../cc13x4_26x4/main/include/AppTask.h | 81 --- .../main/include/CHIPProjectConfig.h | 129 ----- .../cc13x4_26x4/main/include/ClusterManager.h | 50 -- .../cc13x4_26x4/main/include/Globals.h | 42 -- .../cc13x4_26x4/main/main.cpp | 96 ---- .../cc13x4_26x4/third_party/connectedhomeip | 1 - .../light-switch-app/cc13x4_26x4/README.md | 9 + .../light-switch-app/cc13x4_26x4/args.gni | 1 + .../cc13x4_26x4/src/AppTask.cpp | 25 + examples/lighting-app/cc13x4_26x4/README.md | 9 + examples/lighting-app/cc13x4_26x4/args.gni | 3 +- .../lighting-app/cc13x4_26x4/src/AppTask.cpp | 13 + examples/lock-app/cc13x4_26x4/README.md | 9 + examples/lock-app/cc13x4_26x4/args.gni | 3 +- examples/lock-app/cc13x4_26x4/src/AppTask.cpp | 23 + examples/pump-app/cc13x4_26x4/README.md | 8 + examples/pump-app/cc13x4_26x4/args.gni | 3 +- .../pump-app/cc13x4_26x4/main/AppTask.cpp | 10 + .../pump-controller-app/cc13x4_26x4/README.md | 8 + .../pump-controller-app/cc13x4_26x4/args.gni | 3 +- .../cc13x4_26x4/main/AppTask.cpp | 11 +- scripts/build/build/targets.py | 1 - scripts/build/builders/ti.py | 10 - .../build/testdata/all_targets_linux_x64.txt | 2 +- 38 files changed, 156 insertions(+), 2109 deletions(-) delete mode 100644 examples/all-clusters-app/cc13x4_26x4/.gn delete mode 100644 examples/all-clusters-app/cc13x4_26x4/BUILD.gn delete mode 100644 examples/all-clusters-app/cc13x4_26x4/README.md delete mode 100644 examples/all-clusters-app/cc13x4_26x4/args.gni delete mode 120000 examples/all-clusters-app/cc13x4_26x4/build_overrides delete mode 100644 examples/all-clusters-app/cc13x4_26x4/chip.syscfg delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h delete mode 100644 examples/all-clusters-app/cc13x4_26x4/main/main.cpp delete mode 120000 examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip diff --git a/docs/guides/darwin.md b/docs/guides/darwin.md index d44e44cc04afd9..00165e6fcac14f 100644 --- a/docs/guides/darwin.md +++ b/docs/guides/darwin.md @@ -303,7 +303,6 @@ Example: - [Simulated Linux](./simulated_device_linux.md) - [Telink](/examples/lighting-app/telink/README.md) - [TI Platform](./ti/ti_matter_overview.md) -- [TI All Clusters](/examples/all-clusters-app/cc13x4_26x4/README.md) - [Tizen](/examples/lighting-app/tizen/README.md) ## Providing Feedback to Apple diff --git a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md index 2603343ac0c26c..50495a601e3fad 100644 --- a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md +++ b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md @@ -17,6 +17,13 @@ and set the following parameter to true: chip_enable_icd_server = true ``` +To enable LIT ICD behavior, Check In Protocol Support and User Active Mode +Trigger Support, set the following parameter to true: + +``` +chip_enable_icd_lit = true +``` + TI examples have only been tested with the ICD Server configuration. To enable the client configuration, set `chip_enable_icd_client` to true. @@ -43,17 +50,25 @@ mode threshold, and polling intervals can be configured in #define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(100) ``` +To enable LIT ICD behavior, set the polling period to be greater than 15 +seconds, and the active mode threshold to at least 5000 milliseconds. + ## ZAP File Changes Open up the ZAP file (in `examples//-common`) for the example being configured as an ICD. Add the ICD Management Cluster for -Endpoint 0. +Endpoint 0 as either a Server or Client, depending on your configuration. + +To enable LIT ICD behavior, set the FeatureMap to 0x0007 to enable Check-In +Protocol Support, User Active Mode Trigger Support, and Long Idle Time Support. +In addition, enable the UserActiveModeTriggerHint, +UserActiveModeTriggerInstruction, and MaximumCheckInBackOff attributes. -Open up the .matter file (in `examples//-common`) -corresponding to the example and add in the ICDManagement cluster. +After making the desired changes in the zap file, generate the .matter file by +running the following commands: -In addition, each endpoint has a list of clusters that it supports. Add the -ICDManagement cluster to this list. +``` +$ cd /connectedhomeip/scripts/tools/zap +$ ./generate.py examples//-common/-app.zap -The lock-app example's .matter file can be used as a reference. These additions -allow the ICDManagement cluster's callbacks to be accessed. +``` diff --git a/examples/all-clusters-app/cc13x4_26x4/.gn b/examples/all-clusters-app/cc13x4_26x4/.gn deleted file mode 100644 index cf974b2eb1df22..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/.gn +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/build.gni") - -# The location of the build configuration file. -buildconfig = "${build_root}/config/BUILDCONFIG.gn" - -# CHIP uses angle bracket includes. -check_system_includes = true - -default_args = { - target_cpu = "arm" - target_os = "freertos" - - import("//args.gni") - pw_build_PIP_REQUIREMENTS += - [ "${chip_root}/scripts/setup/requirements.ti.txt" ] -} diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn deleted file mode 100644 index bda63caa38dff5..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") -import("//build_overrides/openthread.gni") -import("//build_overrides/ti_simplelink_sdk.gni") - -import("${build_root}/config/defaults.gni") - -import("${chip_root}/src/platform/device.gni") - -import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") -import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") - -assert(current_os == "freertos") - -project_dir = "${chip_root}/examples/all-clusters-app/cc13x4_26x4" - -ti_simplelink_sdk("sdk") { - include_dirs = [ "${project_dir}/main/include" ] - public_configs = [ ":all-clusters-app_config" ] -} - -ti_sysconfig("sysconfig") { - sources = [ "${project_dir}/chip.syscfg" ] - - outputs = [ - "ti_radio_config.c", - "ti_radio_config.h", - "ti_drivers_config.c", - "ti_drivers_config.h", - "ti_ble_config.c", - "ti_ble_config.h", - "ti_dmm_application_policy.c", - "ti_dmm_application_policy.h", - ] - - public_configs = [ ":sdk_cc13x4_26x4_dmm_config" ] - - cflags = [ - "-Wno-comment", - "@" + rebase_path("${target_gen_dir}/sysconfig/ti_utils_build_compiler.opt", - root_build_dir), - ] -} - -ti_simplelink_executable("all-clusters-app") { - output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" - - 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/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/device-energy-management-stub.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/common/src/EnergyTimeUtils.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementDelegateImpl.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementManager.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/ChargingTargetsMemMgr.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/EVSEManufacturerImpl.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseManager.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/ElectricalPowerMeasurementDelegate.cpp", - "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", - "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", - "${project_dir}/main/AppTask.cpp", - "${project_dir}/main/ClusterManager.cpp", - "${project_dir}/main/Globals.cpp", - "${project_dir}/main/ZclCallbacks.cpp", - "${project_dir}/main/main.cpp", - ] - - public = [ - "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", - ] - - deps = [ - ":sdk", - ":sysconfig", - "${chip_root}/examples/all-clusters-app/all-clusters-common", - "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", - "${chip_root}/src/lib", - "${chip_root}/src/platform/logging:default", - "${chip_root}/third_party/openthread:openthread", - ] - defines = [] - if (custom_factory_data) { - defines += [ "CC13XX_26XX_FACTORY_DATA" ] - } - - if (chip_enable_icd_server) { - defines += [ "TI_ICD_ENABLE_SERVER" ] - } - - include_dirs = [ - "${project_dir}", - "${project_dir}/main", - "${chip_root}/examples/all-clusters-app/all-clusters-common/include", - "${chip_root}/examples/energy-management-app/energy-management-common/common/include", - "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/include", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/include", - "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/include", - "${chip_root}/examples/providers/", - ] - - cflags = [ - "-Wno-implicit-fallthrough", - "-Wno-sign-compare", - "-Wconversion", - ] - - output_dir = root_out_dir -} - -group("cc13x4_26x4") { - deps = [ ":all-clusters-app" ] -} - -group("default") { - deps = [ ":cc13x4_26x4" ] -} diff --git a/examples/all-clusters-app/cc13x4_26x4/README.md b/examples/all-clusters-app/cc13x4_26x4/README.md deleted file mode 100644 index b90e3933c351e5..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/README.md +++ /dev/null @@ -1,310 +0,0 @@ -# Matter All-clusters Example Application - -An example application showing the use of [Matter][matter] on the Texas -Instruments CC13XX_26XX family of Wireless MCUs. - ---- - -- [Matter All Clusters Example Application](#matter-all-clusters-example-application) - - [Introduction](#introduction) - - [Device UI](#device-ui) - - [Building](#building) - - [Preparation](#preparation) - - [Compilation](#compilation) - - [Programming](#programming) - - [Code Composer Studio](#code-composer-studio) - - [UniFlash](#uniflash) - - [Running the Example](#running-the-example) - - [Provisioning](#provisioning) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - - [TI Support](#ti-support) - ---- - -## Introduction - -The CC13XX_26XX all clusters example application provides the basis to query and -run commands for all currently implemented Matter clusters. This uses the -open-source Matter implementation and the Texas Instruments SimpleLinkâ„¢ CC13XX -and CC26XX software development kit. - -This example is enabled to build for CC1354P10 devices. - -The all-clusters example is intended to serve both as a means to explore the -workings of Matter, as well as a template for creating real products based on -the Texas Instruments devices. - -## Device UI - -| Action | Functionality | -| ------------------------------------------------ | --------------------------------------------- | -| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | -| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | -| Red LED Solid Blinking State | Identify Trigger Effect in progress (`EP0/1`) | -| Red LED Off State | No Identify Trigger Effect in progress | -| Green LED Blinking State | Identify Trigger Effect in progress (`EP2`) | -| Green LED Off State | No Identify Trigger Effect in progress | - -## Building - -### Preparation - -Some initial setup is necessary for preparing the build environment. This -section will need to be done when migrating to new versions of the SDK. This -guide assumes that the environment is linux based, and recommends Ubuntu 20.04. - -- Download and install [SysConfig][sysconfig]. This can be done simply with - the following commands. - - ``` - $ cd ~ - $ wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.18.1.3343/sysconfig-1.18.1_3343-setup.run - $ chmod +x sysconfig-1.18.1_3343-setup.run - $ ./sysconfig-1.18.1_3343-setup.run - ``` - -- Run the bootstrap script to setup the build environment. -- Note, a recursive submodule checkout is required to utilize TI's Openthread - reference commit. -- Note, in order to build the chip-tool and ota-provider examples, a recursive - submodule checkout is required for the linux platform as seen in the command - below. - - ``` - $ cd ~/connectedhomeip - $ source ./scripts/bootstrap.sh - $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive - - ``` - -### Compilation - -It is necessary to activate the environment in every new shell. Then run GN and -Ninja to build the executable. - -- Activate the build environment with the repository activate script. - - ``` - $ cd ~/connectedhomeip - $ source ./scripts/activate.sh - - ``` - -- Run the build to produce a default executable. By default on Linux both the - TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's - home directory, and you must provide the absolute path to them. For example - `/home/username/ti/sysconfig_1.18.1`. On Windows the default directory is - `C:\ti`. Take note of this install path, as it will be used in the next - step. - - ``` - $ cd ~/connectedhomeip/examples/all-clusters-minimal-app/cc13x4_26x4 - $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\"" - $ ninja -C out/debug - - ``` - - If you would like to define arguments on the command line you may add them - to the GN call. - - ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" - ``` - -## Programming - -Loading the built image onto a LaunchPad is supported through two methods; -Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. -Code Composer Studio can be used to load the image and debug the source code. - -### Code Composer Studio - -Programming with CCS will allow for a full debug environment within the IDE. -This is accomplished by creating a target connection to the XDS110 debugger and -starting a project-less debug session. The CCS IDE will attempt to find the -source files on the local machine based on the debug information embedded within -the ELF. CCS may prompt you to find the source code if the image was built on -another machine or the source code is located in a different location than is -recorded within the ELF. - -Download and install [Code Composer Studio][ccs]. - -First open CCS and create a new workspace. - -Create a target connection (sometimes called the CCXML) for your target SoC and -debugger as described in the [Manual Method][ccs_manual_method] section of the -CCS User's Guide. - -Next initiate a project-less debug session as described in the [Manual -Launch][ccs_manual_launch] section of the CCS User's Guide. - -CCS should switch to the debug view described in the [After -Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely -be disconnected and symbols will not be loaded. Connect to the core as described -in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core -is connected, use the `Load` button on the toolbar to load the ELF image. - -Note that the default configuration of the CCXML uses 2-wire cJTAG instead of -the full 4-wire JTAG connection to match the default jumper configuration of the -LaunchPad. - -### UniFlash - -Uniflash is Texas Instrument's uniform programming tool for embedded processors. -This will allow you to erase, flash, and inspect the SoC without setting up a -debugging environment. - -Download and install [UniFlash][uniflash]. - -First open UniFlash. Debug probes connected to the computer will usually be -displayed under the Detected Devices due to the automatic device detection -feature. If your device does not show up in this view it my be disconnected, or -you may have to create a New Configuration. If you already have a CCXML for your -SoC and debug connection you can use that in the section at the bottom. Once -your device is selected, click the `Start` button within the section to launch -the session. - -Select the ELF image to load on the device with the `Browse` button. This file -is placed in the `out/debug` folder by this guide and ends with the `*.out` file -extension. For OTA enabled applications, the standalone image will instead end -with the `*-mcuboot.hex` file extension. This this is a combined image with -application and `MCUBoot` included. The flag to enable or disable the OTA -feature is determined by "chip_enable_ota_requestor" in the application's -args.gni file. - -Finally click the `Load Image` button to load the executable image onto the -device. You should be able to see the log output over the XDS110 User UART. - -Note that programming the device through JTAG sets the Halt-in-Boot flag and may -cause issues when performing a software reset. This flag can be reset by -power-cycling the LaunchPad. - -## Running the Example - -By default the log output will be sent to the Application/User UART. Open a -terminal emulator to that port to see the output with the following options: - -| Parameter | Value | -| ------------ | -------- | -| Speed (baud) | `115200` | -| Data bits | `8` | -| Stop bits | `1` | -| Parity | `None` | -| Flow control | `None` | - -## Running the Example - -Once a device has been flashed with this example, it can now join and operate in -an existing Matter network. The following sections assume that a Matter network -is already active, and has at least one [OpenThread Border -Router][ot_border_router_setup]. - -For insight into what other components are needed to run this example, please -refer to our [Matter Getting Started Guide][matter-e2e-faq]. - -The steps below should be followed to commission the device onto the network and -control it once it has been commissioned. - -**Step 0** - -Set up the CHIP tool by following the instructions outlined in our [Matter -Getting Started Guide][matter-e2e-faq]. - -**Step 1** - -Commission the device onto the Matter network. Run the following command on the -CHIP tool: - -``` - -./chip-tool pairing ble-thread hex: 20202021 3840 - -``` - -Interacting with the application begins by enabling BLE advertisements and then -pairing the device into a Thread network. To provision this example onto a -Matter network, the device must be discoverable over Bluetooth LE. - -On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more -than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the -device is fully provisioned, BLE advertising will stop. - -Once the device has been successfully commissioned, you will see the following -message on the CHIP tool output: - -``` - -[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 -[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' - -``` - -An accompanying message will be seen from the device: - -``` - -Commissioning complete, notify platform driver to persist network credentials. - -``` - -**Step 2** - -Send commands to the all-cluster-app. Here are some example commands: - -Basic - -``` -./chip-tool basic read e.g. ./chip-tool basic read product-id 1 0 -``` - -Identify - -``` -./chip-tool identify identify e.g. ./chip-tool identify identify 100 1 1 -``` - -### Provisioning - -Interacting with the application begins by enabling BLE advertisements and then -pairing the device into a Thread network. - -#### Bluetooth LE Advertising - -To provision this example onto a Thread network, the device must be discoverable -over Bluetooth LE. BLE advertising is started by long pressing the right button -(greater than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is -fully provisioned, BLE advertising will stop. - -#### Bluetooth LE Rendezvous - -Pairing this application with `ble-thread` can be done with any of the enabled -[CHIP Controller](../../../src/controller/README.md) applications. Use the -information printed on the console to aide in pairing the device. The controller -application can also be used to control the example app with the cluster -commands. - -## TI Support - -For technical support, please consider creating a post on TI's [E2E forum][e2e]. -Additionally, we welcome any feedback. - -[matter]: https://csa-iot.org/all-solutions/matter/ -[ccs]: https://www.ti.com/tool/CCSTUDIO -[ccs_after_launch]: - https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch -[ccs_debug_view]: - https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view -[ccs_manual_launch]: - https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch -[ccs_manual_method]: - https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method -[e2e]: - https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum -[matter-e2e-faq]: - https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide -[sysconfig]: https://www.ti.com/tool/SYSCONFIG -[ti_thread_dnd]: - https://www.ti.com/wireless-connectivity/thread/design-development.html -[ot_border_router_setup]: https://openthread.io/guides/border-router/build -[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/all-clusters-app/cc13x4_26x4/args.gni b/examples/all-clusters-app/cc13x4_26x4/args.gni deleted file mode 100644 index 56b7504ebf03f5..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/args.gni +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") -import("//build_overrides/freertos.gni") -import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") - -ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") -ti_simplelink_sysconfig_target = - get_label_info(":sysconfig", "label_no_toolchain") - -ti_simplelink_board = "LP_EM_CC1354P10_6" - -# Size Optimizations -# use -Os instead of -Og, LWIP release build -optimize_debug_level = "s" -lwip_debug = false - -chip_enable_ota_requestor = true - -openthread_external_platform = - "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" - -# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert -# For source builds, set to empty string. -chip_openthread_target = - "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" - -chip_openthread_ftd = true - -# Disable CHIP Logging -#chip_progress_logging = false -#chip_detail_logging = false -#chip_automation_logging = false - -# BLE options -chip_config_network_layer_ble = true - -# Disable lock tracking, since our FreeRTOS configuration does not set -# INCLUDE_xSemaphoreGetMutexHolder -chip_stack_lock_tracking = "none" - -matter_device_vid = "0xFFF1" -matter_device_pid = "0x8006" -matter_software_ver = "0x0001" -matter_software_ver_str = "1.0.1+1" - -custom_factory_data = true - -# ICD Default configurations -chip_enable_icd_server = false -chip_persist_subscriptions = false -chip_subscription_timeout_resumption = false - -freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" - -if (chip_openthread_target != "") { - openthread_root = - "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" -} diff --git a/examples/all-clusters-app/cc13x4_26x4/build_overrides b/examples/all-clusters-app/cc13x4_26x4/build_overrides deleted file mode 120000 index e578e73312ebd1..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../build_overrides \ No newline at end of file diff --git a/examples/all-clusters-app/cc13x4_26x4/chip.syscfg b/examples/all-clusters-app/cc13x4_26x4/chip.syscfg deleted file mode 100644 index 16ce3520e42674..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/chip.syscfg +++ /dev/null @@ -1,241 +0,0 @@ -/* - * - * Copyright (c) 2020 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. - */ - - -/* Modules */ -var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); -var AESECB = scripting.addModule("/ti/drivers/AESECB"); -var Button = scripting.addModule("/ti/drivers/apps/Button"); -var LED = scripting.addModule("/ti/drivers/apps/LED"); -var NVS = scripting.addModule("/ti/drivers/NVS"); -var RF = scripting.addModule("/ti/drivers/RF"); -var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); -var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); -var TRNG = scripting.addModule("/ti/drivers/TRNG"); -var SHA2 = scripting.addModule("/ti/drivers/SHA2"); -var UART2 = scripting.addModule("/ti/drivers/UART2"); -var ble = scripting.addModule("/ti/ble5stack/ble"); -var dmm = scripting.addModule("/ti/dmm/dmm"); -var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); -var ECDH = scripting.addModule("/ti/drivers/ECDH"); - -/* Instances */ -var AESCCM1 = AESCCM.addInstance(); -var AESECB1 = AESECB.addInstance(); -var AESECB2 = AESECB.addInstance(); -var Button1 = Button.addInstance(); -var Button2 = Button.addInstance(); -var NVS1 = NVS.addInstance(); -var NVS2 = NVS.addInstance(); -var SHA21 = SHA2.addInstance(); -var LED1 = LED.addInstance(); -var LED2 = LED.addInstance(); -var TRNG1 = TRNG.addInstance(); -var TRNG2 = TRNG.addInstance(); -var TRNG3 = TRNG.addInstance(); -var UART2 = UART2.addInstance(); -var AESCTRDRBG1 = AESCTRDRBG.addInstance(); -var ECDH1 = ECDH.addInstance(); - -AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; - -AESCCM1.$name = "CONFIG_AESCCM0"; - -AESECB1.$name = "CONFIG_AESECB0"; -AESECB2.$name = "CONFIG_AESECB_1"; - -ECDH1.$name = "CONFIG_ECDH0"; - -/* Left Button */ -Button1.$name = "CONFIG_BTN_LEFT"; -Button1.$hardware = system.deviceData.board.components["BTN-1"]; -Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; -Button1.gpioPin.pull = "Pull Up"; -Button1.gpioPin.interruptTrigger = "Falling Edge"; - -/* Left Button */ -Button2.$name = "CONFIG_BTN_RIGHT"; -Button2.$hardware = system.deviceData.board.components["BTN-2"]; -Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; -Button2.gpioPin.pull = "Pull Up"; -Button2.gpioPin.interruptTrigger = "Falling Edge"; - -/* ======== CCFG ======== */ -var CCFG = scripting.addModule("/ti/devices/CCFG"); -const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; -for(var setting in ccfgSettings) -{ - CCFG[setting] = ccfgSettings[setting]; -} - -/* disable CCFG for OTA-able application */ -CCFG.enableCodeGeneration = false; - - -/* NVS */ -NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xF8800; -NVS1.internalFlash.regionSize = 0x6000; - - -NVS2.$name = "CONFIG_NVSEXTERNAL"; -NVS2.nvsType = "External"; // NVS Region Type -NVS2.$hardware = system.deviceData.board.components.MX25R8035F; - -/* RF */ -/* if an antenna component exists, assign it to the rf instance */ -if (system.deviceData.board && system.deviceData.board.components.RF) { - RF.$hardware = system.deviceData.board.components.RF; -} - -const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; -for(var setting in rfDesignSettings) -{ - RFDesign[setting] = rfDesignSettings[setting]; -} - - - -/* Handling for RF frontend characterization */ -if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) -{ - RFCustom.ieee = ["ieee154p10"]; - var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig -} -else -{ - RFCustom.ieee = ["ieee154"]; - var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig -} - -var cmdList = [ - "cmdIeeeTx", - "cmdIeeeRx", - "cmdIeeeCsma", - "cmdIeeeEdScan", - "cmdIeeeRxAck", - "cmdTxTest" -]; - -rfCodeExportConfig.useConst = true; -rfCodeExportConfig.useMulti = true; -rfCodeExportConfig.symGenMethod = "Custom"; - -const deviceId = system.deviceData.deviceId; - -// Add high PA options if present -if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) -{ - cmdList.push("cmdRadioSetup"); - rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; -} -else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) -{ - cmdList.push("cmdRadioSetupPa"); - rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; - rfCodeExportConfig.paExport = "combined"; -} -else if(deviceId.match(/CC(265[34]|1354)P/)) -{ - cmdList.push("cmdRadioSetupPa"); - rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; - // currently not characterized for high PA -} -else -{ - throw new Error("Could not match platform to any known platform types"); -} - -rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; - -/* Red LED */ -LED1.$name = "CONFIG_LED_RED"; -LED1.$hardware = system.deviceData.board.components.LED_RED; -LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; -LED1.gpioPin.mode = "Output"; - -/* Green LED */ -LED2.$name = "CONFIG_LED_GREEN"; -LED2.$hardware = system.deviceData.board.components.LED_GREEN; -LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; -LED2.gpioPin.mode = "Output"; - -/* Debug UART */ -UART2.$hardware = system.deviceData.board.components.XDS110UART; -UART2.$name = "CONFIG_UART2_DEBUG"; - -/* TRNG */ -TRNG1.$name = "CONFIG_TRNG_0"; -TRNG2.$name = "CONFIG_TRNG_THREAD"; -TRNG3.$name = "CONFIG_TRNG_APP"; - -/* BLE */ -ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; -ble.maxConnNum = 1; -ble.numOfAdvSets = 1; -ble.lockProject = true; -ble.oneLibSizeOpt = true; -ble.maxPDUSize = 255; -ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; -ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; -ble.connUpdateParamsPeripheral.reqMinConnInt = 30; -ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; - -ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; -ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; - -ble.rfDesign = "LP_EM_CC1354P10_6"; - -ble.thorPg = 2; -/* DMM */ -dmm.project = "ti_thread_thermostat_remote_display"; -dmm.stackRoles = ["blePeripheral","threadFTD"]; -dmm.lockStackRoles = true; -dmm.numApplicationStates = 10; -dmm.applicationState0 = "ANY"; -dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; -dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; -dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; -dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; -dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; -dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; -dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; -dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; -dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; -dmm.policyArray.create(4); -dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; -dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; -dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; -dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; -dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; -dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; -dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; -dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; -dmm.policyArray[1].blePeripheral.weight = 25; -dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; -dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; -dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; -dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; -dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; -dmm.policyArray[2].threadFTD.weight = 30; -dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; -dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; -dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; -dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; -dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; -dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp deleted file mode 100644 index c9a54347657c3d..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" -#include "AppConfig.h" -#include "AppEvent.h" -#include - -#include "FreeRTOS.h" -#include "Globals.h" -#include -#include -#include - -#include -#include - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -#include -#include -#include -#include -#include -#endif -#include -#include - -#if AUTO_PRINT_METRICS -// #include -#endif -#include - -#include -#include -#include - -#include -#include -#include - -/* syscfg */ -#include - -#define APP_TASK_STACK_SIZE (5000) -#define APP_TASK_PRIORITY 4 -#define APP_EVENT_QUEUE_SIZE 10 -#define BUTTON_ENABLE 1 - -#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 - -using namespace ::chip; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -static TaskHandle_t sAppTaskHandle; -static QueueHandle_t sAppEventQueue; -static Button_Handle sAppLeftHandle; -static Button_Handle sAppRightHandle; -static DeviceInfoProviderImpl sExampleDeviceInfoProvider; - -AppTask AppTask::sAppTask; -app::Clusters::ModeSelect::StaticSupportedModesManager sStaticSupportedModesManager; - -constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void StartTimer(uint32_t aTimeoutMs); -void CancelTimer(void); -#endif - -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static DefaultOTARequestor sRequestorCore; -static DefaultOTARequestorStorage sRequestorStorage; -static DefaultOTARequestorDriver sRequestorUser; -static BDXDownloader sDownloader; -static OTAImageProcessorImpl sImageProcessor; - -void InitializeOTARequestor(void) -{ - // Initialize and interconnect the Requestor and Image Processor objects - SetRequestorInstance(&sRequestorCore); - - sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); - sRequestorCore.Init(Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); - sImageProcessor.SetOTADownloader(&sDownloader); - sDownloader.SetImageProcessorDelegate(&sImageProcessor); - sRequestorUser.Init(&sRequestorCore, &sImageProcessor); -} - -TimerHandle_t sOTAInitTimer = 0; -#endif - -// The OTA Init Timer is only started upon the first Thread State Change -// detected if the device is already on a Thread Network, or during the AppTask -// Init sequence if the device is not yet on a Thread Network. Once the timer -// has been started once, it does not need to be started again so the flag will -// be set to false. -bool isAppStarting = true; - -#ifdef AUTO_PRINT_METRICS -static void printMetrics(void) -{ - chip::DeviceLayer::ThreadMetrics *threadMetricsOut, *currThread; - uint64_t heapFree, heapUsed; - - DiagnosticDataProviderImpl::GetDefaultInstance().GetCurrentHeapUsed(heapUsed); - DiagnosticDataProviderImpl::GetDefaultInstance().GetCurrentHeapFree(heapFree); - DiagnosticDataProviderImpl::GetDefaultInstance().GetThreadMetrics(&threadMetricsOut); - - PLAT_LOG("Heap Metrics\n Heap Free: %d Heap Used: %d", (uint32_t) heapFree, (uint32_t) heapUsed); - - PLAT_LOG("Thread Metrics\n"); - - currThread = threadMetricsOut; - while (currThread) - { - PLAT_LOG("Task Name: %s ID: %d Stack Free Min: %d", currThread->name, (uint32_t) currThread->id, - (uint32_t) currThread->stackFreeMinimum); - - currThread = currThread->Next; - } - - DiagnosticDataProviderImpl::GetDefaultInstance().ReleaseThreadMetrics(threadMetricsOut); -} -#endif - -void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEConnectionEstablished: - PLAT_LOG("CHIPoBLE connection established"); - break; - - case DeviceEventType::kCHIPoBLEConnectionClosed: - PLAT_LOG("CHIPoBLE disconnected"); - break; - - case DeviceEventType::kCommissioningComplete: - PLAT_LOG("Commissioning complete"); - break; - case DeviceEventType::kThreadStateChange: - PLAT_LOG("Thread State Change"); - bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); - - if (isThreadAttached) - { - PLAT_LOG("Device is on the Thread Network"); -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (isAppStarting) - { - StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); - isAppStarting = false; - } -#endif - } - break; - } - -#ifdef AUTO_PRINT_METRICS - printMetrics(); -#endif -} - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void OTAInitTimerEventHandler(TimerHandle_t xTimer) -{ - InitializeOTARequestor(); -} -#endif - -int AppTask::StartAppTask() -{ - int ret = 0; - - sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); - if (sAppEventQueue == NULL) - { - PLAT_LOG("Failed to allocate app event queue"); - while (1) - ; - } - - // Start App task. - if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != - pdPASS) - { - PLAT_LOG("Failed to create app task"); - while (1) - ; - } - return ret; -} - -int AppTask::Init() -{ - cc13xx_26xxLogInit(); - - uiInit(); - - // Init Chip memory management before the stack - Platform::MemoryInit(); - - PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); - PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - CHIP_ERROR ret = PlatformMgr().InitChipStack(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().InitChipStack() failed"); - while (1) - ; - } - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - // Create FreeRTOS sw timer for OTA timer. - sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel - OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = light obj context - OTAInitTimerEventHandler // timer callback handler - ); - - if (sOTAInitTimer == NULL) - { - PLAT_LOG("sOTAInitTimer timer create failed"); - } - else - { - PLAT_LOG("sOTAInitTimer timer created successfully "); - } -#endif - - ret = ThreadStackMgr().InitThreadStack(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); - while (1) - ; - } - -#if CHIP_DEVICE_CONFIG_THREAD_FTD - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#elif CHIP_CONFIG_ENABLE_ICD_SERVER - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#else - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#endif - - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); - while (1) - ; - } - - ret = ThreadStackMgrImpl().StartThreadTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); - while (1) - ; - } - -// Initialize device attestation config -#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS -#ifdef CC13XX_26XX_FACTORY_DATA - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); -#else - SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); -#endif -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - // Init ZCL Data Model and start server - PLAT_LOG("Initialize Server"); - static chip::CommonCaseDeviceServerInitParams initParams; - static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; - initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; - - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - - // Initialize info provider - sExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); - SetDeviceInfoProvider(&sExampleDeviceInfoProvider); - - chip::Server::GetInstance().Init(initParams); - - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); - while (1) - ; - } - - ConfigurationMgr().LogDeviceConfig(); - - // We only have network commissioning on endpoint 0. - emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); - - // Register a function to receive events from the CHIP device layer. Note that calls to - // this function will happen on the CHIP event loop thread, not the app_main thread. - PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); - - bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); - if (!isThreadEnabled && isAppStarting) - { -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - PLAT_LOG("Thread is Disabled, enable OTA Requestor"); - StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); - isAppStarting = false; -#endif - } - // QR code will be used with CHIP Tool - PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); - - app::Clusters::ModeSelect::setSupportedModesManager(&sStaticSupportedModesManager); - return 0; -} - -void AppTask::AppTaskMain(void * pvParameter) -{ - AppEvent event; - - sAppTask.Init(); - - while (1) - { - /* Task pend until we have stuff to do */ - if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) - { - sAppTask.DispatchEvent(&event); - } - } -} - -void StartTimer(uint32_t aTimeoutMs) -{ - PLAT_LOG("Start OTA Init Timer") - if (xTimerIsTimerActive(sOTAInitTimer)) - { - PLAT_LOG("app timer already started!"); - CancelTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) - { - PLAT_LOG("sOTAInitTimer timer start() failed"); - } -} - -void CancelTimer(void) -{ - if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) - { - PLAT_LOG("sOTAInitTimer stop() failed"); - } -} - -void AppTask::PostEvent(const AppEvent * aEvent) -{ - if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS) - { - /* Failed to post the message */ - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - switch (aEvent->Type) - { - case AppEvent::kEventType_ButtonLeft: - if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) - { - } - else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - break; - - case AppEvent::kEventType_ButtonRight: - if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) - { - } - else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) - { - // Enable BLE advertisements - if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) - { - PLAT_LOG("Enabled BLE Advertisements"); - } - else - { - PLAT_LOG("OpenBasicCommissioningWindow() failed"); - } - } - else - { - // Disable BLE advertisements - ConnectivityMgr().SetBLEAdvertisingEnabled(false); - PLAT_LOG("Disabled BLE Advertisements"); - } - } - break; - - case AppEvent::kEventType_AppEvent: - if (NULL != aEvent->Handler) - { - aEvent->Handler(aEvent); - } - break; - - case AppEvent::kEventType_None: - default: - break; - } -} - -#if (BUTTON_ENABLE == 1) -void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) -{ - AppEvent event; - event.Type = AppEvent::kEventType_ButtonLeft; - - if (events & Button_EV_CLICKED) - { - event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; - } - else if (events & Button_EV_LONGCLICKED) - { - event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; - } - // button callbacks are in ISR context - if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) - { - /* Failed to post the message */ - } -} - -void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) -{ - AppEvent event; - event.Type = AppEvent::kEventType_ButtonRight; - - if (events & Button_EV_CLICKED) - { - event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; - } - else if (events & Button_EV_LONGCLICKED) - { - event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; - } - // button callbacks are in ISR context - if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) - { - /* Failed to post the message */ - } -} -#endif // BUTTON_ENABLE - -void AppTask::uiInit(void) -{ -#if (LED_ENABLE == 1) - - LED_Params ledParams; - - // Initialize LEDs - PLAT_LOG("Initialize LEDs"); - LED_init(); - - LED_Params_init(&ledParams); // default PWM LED - sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); - LED_setOff(sAppRedHandle); - - LED_Params_init(&ledParams); // default PWM LED - sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); - LED_setOff(sAppGreenHandle); -#endif // LED ENABLE - -#if (BUTTON_ENABLE == 1) - Button_Params buttonParams; - - // Initialize buttons - PLAT_LOG("Initialize buttons"); - Button_init(); - - Button_Params_init(&buttonParams); - buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; - buttonParams.longPressDuration = 1000U; // ms - sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); - Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); - - Button_Params_init(&buttonParams); - buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; - buttonParams.longPressDuration = 1000U; // ms - sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); - Button_setCallback(sAppRightHandle, ButtonRightEventHandler); -#endif // BUTTON ENABLE -} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp b/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp deleted file mode 100644 index bf5176fc060ae9..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "ClusterManager.h" -#include "Globals.h" -#include -#include -#include -#include -#include - -#ifdef AUTO_PRINT_METRICS -#include -#endif - -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Inet; -using namespace ::chip::System; -using namespace ::chip::DeviceLayer; - -constexpr uint32_t kIdentifyTimerDelayMS = 250; -constexpr uint32_t kIdentifyTimerDelayPerSec = 4; -ClusterManager ClusterManager::sCluster; - -#define ENDPOINT_ID_0 (0) -#define ENDPOINT_ID_1 (1) -#define ENDPOINT_ID_2 (2) - -void OnIdentifyTriggerEffect(Identify * identify) -{ - switch (identify->mCurrentEffectIdentifier) - { - case Clusters::Identify::EffectIdentifierEnum::kBlink: - PLAT_LOG("Clusters::Identify::EffectIdentifierEnum::kBlink"); - break; - case Clusters::Identify::EffectIdentifierEnum::kBreathe: - PLAT_LOG("Clusters::Identify::EffectIdentifierEnum::kBreathe"); - break; - case Clusters::Identify::EffectIdentifierEnum::kOkay: - PLAT_LOG("Clusters::Identify::EffectIdentifierEnum::kOkay"); - break; - case Clusters::Identify::EffectIdentifierEnum::kChannelChange: - PLAT_LOG("Clusters::Identify::EffectIdentifierEnum::kChannelChange"); - break; - default: - PLAT_LOG("No identifier effect"); - break; - } - return; -} - -Identify gIdentify0 = { - chip::EndpointId{ 0 }, - [](Identify *) { PLAT_LOG("onIdentifyStart"); }, - [](Identify *) { PLAT_LOG("onIdentifyStop"); }, - Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - OnIdentifyTriggerEffect, -}; - -Identify gIdentify1 = { - chip::EndpointId{ 1 }, - [](Identify *) { PLAT_LOG("onIdentifyStart"); }, - [](Identify *) { PLAT_LOG("onIdentifyStop"); }, - Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - OnIdentifyTriggerEffect, -}; - -void ClusterManager::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) -{ - using namespace app::Clusters::OnOff::Attributes; - VerifyOrExit(attributeId == OnOff::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); - VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, - PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); - - // At this point we can assume that value points to a bool value. - mEndpointOnOffState[endpointId - 1] = *value; - endpointId == ENDPOINT_ID_1 ? LED_write(sAppGreenHandle, *value) : LED_write(sAppRedHandle, *value); - -exit: - return; -} - -void ClusterManager::OnLevelControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) -{ - using namespace app::Clusters::LevelControl::Attributes; - bool onOffState = mEndpointOnOffState[endpointId - 1]; - uint8_t brightness = onOffState ? *value : 0; - - VerifyOrExit(brightness > 0, PLAT_LOG("Brightness set to 0, ignoring")); - VerifyOrExit(attributeId == CurrentLevel::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); - VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, - PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); - - if (brightness > LED_BRIGHTNESS_MAX) - { - brightness = LED_BRIGHTNESS_MAX; - } - - endpointId == ENDPOINT_ID_1 ? LED_setOn(sAppGreenHandle, brightness) : LED_setOn(sAppRedHandle, brightness); - -exit: - return; -} - -void ClusterManager::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) -{ - using namespace app::Clusters::ColorControl::Attributes; - - VerifyOrExit(attributeId == CurrentHue::Id || attributeId == CurrentSaturation::Id, - PLAT_LOG("Unhandled AttributeId ID: '0x%04x", attributeId)); - VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, - PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); - - if (endpointId == ENDPOINT_ID_1) - { - uint8_t hue, saturation; - if (attributeId == CurrentHue::Id) - { - hue = *value; - /* Read Current Saturation value when Attribute change callback for HUE Attribute */ - CurrentSaturation::Get(endpointId, &saturation); - } - else - { - saturation = *value; - /* Read Current Hue value when Attribute change callback for SATURATION Attribute */ - CurrentHue::Get(endpointId, &hue); - } - PLAT_LOG("Color Control triggered: Hue: %d Saturation: %d", hue, saturation); - } -exit: - return; -} - -void ClusterManager::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint16_t size, - uint8_t * value) -{ - if (attributeId == app::Clusters::Identify::Attributes::IdentifyTime::Id && size == 2) - { - uint16_t identifyTime; - memcpy(&identifyTime, value, size); - if (identifyTime) - { - // Currently we have no separate indicator LEDs on each endpoints. - // We are using LED1 for endpoint 0,1 and LED2 for endpoint 2 - if (endpointId == ENDPOINT_ID_2) - { - LED_startBlinking(sAppGreenHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec); - } - else - { - LED_startBlinking(sAppRedHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec); - } - } - else - { - bool onOffState; - endpointId == ENDPOINT_ID_0 ? onOffState = mEndpointOnOffState[0] : onOffState = mEndpointOnOffState[endpointId - 1]; - endpointId == ENDPOINT_ID_2 ? LED_write(sAppRedHandle, onOffState) : LED_write(sAppGreenHandle, onOffState); - } - } -} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp b/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp deleted file mode 100644 index 00fd64e3125218..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Globals.h" - -#if (LED_ENABLE == 1) -LED_Handle sAppRedHandle; -LED_Handle sAppGreenHandle; -#endif diff --git a/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp b/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp deleted file mode 100644 index b21e2ad4c1b9f0..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Copyright (c) 2021 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 - * This file implements the handler for data model messages. - */ - -#include "AppConfig.h" -#include "Globals.h" -#include - -#include "ClusterManager.h" - -#include -#include -#include -#include -#include - -using namespace ::chip; -using namespace ::chip::app::Clusters; - -void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, - uint8_t * value) -{ - EndpointId endpoint = attributePath.mEndpointId; - ClusterId clusterId = attributePath.mClusterId; - AttributeId attributeId = attributePath.mAttributeId; - PLAT_LOG("MatterPostAttributeChangeCallback - Cluster ID: " ChipLogFormatMEI - ", EndPoint ID: '0x%02x', Attribute ID: " ChipLogFormatMEI, - ChipLogValueMEI(clusterId), endpoint, ChipLogValueMEI(attributeId)); - - switch (clusterId) - { - case OnOff::Id: - ClusterMgr().OnOnOffPostAttributeChangeCallback(endpoint, attributeId, value); - break; - - case Identify::Id: - ClusterMgr().OnIdentifyPostAttributeChangeCallback(endpoint, attributeId, size, value); - break; - - case LevelControl::Id: - ClusterMgr().OnLevelControlAttributeChangeCallback(endpoint, attributeId, value); - break; - - case ColorControl::Id: - ClusterMgr().OnColorControlAttributeChangeCallback(endpoint, attributeId, value); - break; - default: - PLAT_LOG("Unhandled cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - break; - } -} -/** @brief OnOff Cluster Init - * - * This function is called when a specific cluster is initialized. It gives the - * application an opportunity to take care of cluster initialization procedures. - * It is called exactly once for each endpoint where cluster is present. - * - * @param endpoint Ver.: always - */ -void emberAfOnOffClusterInitCallback(EndpointId endpoint) -{ - // TODO: implement any additional Cluster Server init actions -} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h deleted file mode 100644 index 7f6ce19a384bdc..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ - -#ifndef APP_CONFIG_H -#define APP_CONFIG_H - -#endif // APP_CONFIG_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h deleted file mode 100644 index 1d1efd369495b6..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APP_EVENT_H -#define APP_EVENT_H - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -struct AppEvent -{ - enum AppEventType - { - kEventType_None = 0, - kEventType_ButtonLeft, - kEventType_ButtonRight, - kEventType_AppEvent, - }; - - enum AppEventButtonType - { - kAppEventButtonType_None = 0, - kAppEventButtonType_Clicked, - kAppEventButtonType_LongClicked, - }; - - enum AppEventType Type; - - union - { - struct - { - enum AppEventButtonType Type; - } ButtonEvent; - - struct - { - void * Context; - } BoltLockEvent; - }; - - EventHandler Handler; -}; - -#endif // APP_EVENT_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h deleted file mode 100644 index 55297d715d95ca..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * 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. - */ - -#ifndef APP_TASK_H -#define APP_TASK_H - -#include -#include - -#include "FreeRTOS.h" -#include "semphr.h" -#include "task.h" - -#include "AppEvent.h" - -#include - -#ifdef CC13XX_26XX_FACTORY_DATA -#include -#endif - -class AppTask -{ -public: - int StartAppTask(); - static void AppTaskMain(void * pvParameter); - - void PostEvent(const AppEvent * event); - -private: - friend AppTask & GetAppTask(void); - - int Init(); - - void DispatchEvent(AppEvent * event); - void uiInit(); - - static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); - static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); - static void TimerEventHandler(void * p_context); - - enum Function_t - { - kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, - kFunction_FactoryReset, - - kFunction_Invalid - } Function; - - Function_t mFunction; - bool mFunctionTimerActive; - - static AppTask sAppTask; - -#ifdef CC13XX_26XX_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif -}; - -inline AppTask & GetAppTask(void) -{ - return AppTask::sAppTask; -} - -#endif // APP_TASK_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h deleted file mode 100644 index f42469c54a5880..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Example project configuration file for CHIP. - * - * This is a place to put application or project-specific overrides - * to the default configuration values for general CHIP features. - * - */ - -#ifndef CHIP_PROJECT_CONFIG_H -#define CHIP_PROJECT_CONFIG_H - -#if BUILD_RELEASE // release build -// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds -#endif // BUILD_RELEASE - -// Use a default pairing code if one hasn't been provisioned in flash. -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 - -/** - * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER - * - * Enables the use of a hard-coded default serial number if none - * is found in CHIP NV storage. - */ -#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" - -/** - * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION - * - * The hardware version number assigned to device or product by the device vendor. This - * number is scoped to the device product id, and typically corresponds to a revision of the - * physical device, a change to its packaging, and/or a change to its marketing presentation. - * This value is generally *not* incremented for device software versions. - */ -#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 - -/** - * Values set by args.gni: - * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING - * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION - */ - -/** - * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE - * - * Enable support for CHIP-over-BLE (CHIPOBLE). - */ -#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 - -/** - * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC - * - * Enables synchronizing the device's real time clock with a remote CHIP Time service - * using the CHIP Time Sync protocol. - */ -// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 - -/** - * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE - * - * A size, in bytes, of the individual debug event logging buffer. - */ -#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) - -#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 - -/** - * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - * - * Enable the OpenThread SRP client to allow for CHIP device discovery. - */ -#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 - -/** - * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE - * - * For a development build, set the default importance of events to be logged as Debug. - * Since debug is the lowest importance level, this means all standard, critical, info and - * debug importance level vi events get logged. - */ -#if BUILD_RELEASE -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production -#else -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug -#endif // BUILD_RELEASE - -#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 - -/** - * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER - * - * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. - */ -#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 1 - -/** - * @def CHIP_IM_MAX_NUM_WRITE_HANDLER - * - * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. - */ -#define CHIP_IM_MAX_NUM_WRITE_HANDLER 1 - -// All clusters app has 3 group endpoints. This needs to defined here so that -// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. -#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 - -#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h b/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h deleted file mode 100644 index 7a9a363980ca6f..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ClusterManager.h - * - * Declarations for the ClusterManager callbacks for this application - * - **/ - -#pragma once - -#include -#include -#include - -class ClusterManager -{ -public: - void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); - void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); - void OnColorControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); - void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint16_t size, - uint8_t * value); - -private: - friend ClusterManager & ClusterMgr(void); - bool mEndpointOnOffState[2]; - static ClusterManager sCluster; -}; - -inline ClusterManager & ClusterMgr(void) -{ - return ClusterManager::sCluster; -} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h b/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h deleted file mode 100644 index 8320b01ac79bb7..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright (c) 2020 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 -// Logging -#ifdef __cplusplus -extern "C" { -#endif - -int cc13xx_26xxLogInit(void); -void cc13xx_26xxLog(const char * aFormat, ...); -#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); - -#ifdef __cplusplus -} -#endif - -#if (CHIP_CONFIG_ENABLE_ICD_SERVER == 1) -#define LED_ENABLE 0 -#else -#define LED_ENABLE 1 -#endif - -extern LED_Handle sAppRedHandle; -extern LED_Handle sAppGreenHandle; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/main.cpp b/examples/all-clusters-app/cc13x4_26x4/main/main.cpp deleted file mode 100644 index 8162d893d5c198..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/main/main.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright (c) 2020 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 - -#include -#include - -#include - -/* Driver Header files */ -#include -#include -#include - -#include -#include -#include -#include - -#include -#define TOTAL_ICALL_HEAP_SIZE (0xd000) - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; -uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; - -// ================================================================================ -// FreeRTOS Callbacks -// ================================================================================ -/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ -extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) -{ - /* This function is intentionally left empty as the Queue Registry is disabled */ -} - -extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) -{ - /* This function is intentionally left empty as the Queue Registry is disabled */ -} - -// ================================================================================ -// Main Code -// ================================================================================ -int main(void) -{ - Board_init(); - bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); - - GPIO_init(); - - NVS_init(); - - ECDH_init(); - - ECDSA_init(); - - AESECB_init(); - - SHA2_init(); - - int ret = GetAppTask().StartAppTask(); - if (ret != 0) - { - // can't log until the kernel is started - // PLAT_LOG("GetAppTask().StartAppTask() failed"); - while (1) - ; - } - - vTaskStartScheduler(); - - // Should never get here. - while (1) - ; -} diff --git a/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip b/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip deleted file mode 120000 index c866b86874994d..00000000000000 --- a/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../.. \ No newline at end of file diff --git a/examples/light-switch-app/cc13x4_26x4/README.md b/examples/light-switch-app/cc13x4_26x4/README.md index a27c702714c5a8..fed466da7941e4 100644 --- a/examples/light-switch-app/cc13x4_26x4/README.md +++ b/examples/light-switch-app/cc13x4_26x4/README.md @@ -42,6 +42,15 @@ the Texas Instruments devices. | Right Button (`BTN-2`) Press (less than 1000 ms) | Turns connected bulb on | | Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +When the device has LIT ICD functionality enabled (`chip_enable_icd_lit` set to +true in args.gni), the functionality of the short button presses changes as +described below: + +| Action | Functionality | +| ------------------------------------------------ | ------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | User Active Mode Trigger | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Connected Bulb is toggled | + ## Building ### Preparation diff --git a/examples/light-switch-app/cc13x4_26x4/args.gni b/examples/light-switch-app/cc13x4_26x4/args.gni index 1223bfef03d761..0f04705b08265c 100644 --- a/examples/light-switch-app/cc13x4_26x4/args.gni +++ b/examples/light-switch-app/cc13x4_26x4/args.gni @@ -65,6 +65,7 @@ custom_factory_data = false chip_enable_icd_server = false chip_persist_subscriptions = false chip_subscription_timeout_resumption = false +chip_enable_icd_lit = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" diff --git a/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp b/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp index eec72be98096b7..7dedcac6477629 100644 --- a/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp @@ -60,6 +60,10 @@ #include #include +#if CHIP_CONFIG_ENABLE_ICD_UAT +#include "app/icd/server/ICDNotifier.h" +#endif + /* syscfg */ #include @@ -146,6 +150,10 @@ TimerHandle_t sOTAInitTimer = 0; // be set to false. bool isAppStarting = true; +#if CHIP_CONFIG_ENABLE_ICD_UAT +bool switchIsTurnedOn = false; +#endif + ::Identify stIdentify = { SWITCH_APPLICATION_IDENTIFY_ENDPOINT, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, AppTask::TriggerIdentifyEffectHandler }; @@ -479,8 +487,12 @@ void AppTask::DispatchEvent(AppEvent * aEvent) case AppEvent::kEventType_ButtonLeft: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { +#if CHIP_CONFIG_ENABLE_ICD_UAT + PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); +#else actor = AppEvent::kEventType_ButtonLeft; LightSwitchMgr().InitiateAction(actor, LightSwitchManager::SWITCH_OFF_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { @@ -492,7 +504,20 @@ void AppTask::DispatchEvent(AppEvent * aEvent) if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { actor = AppEvent::kEventType_ButtonRight; +#if CHIP_CONFIG_ENABLE_ICD_UAT + if (switchIsTurnedOn) + { + LightSwitchMgr().InitiateAction(actor, LightSwitchManager::SWITCH_OFF_ACTION); + switchIsTurnedOn = false; + } + else + { + LightSwitchMgr().InitiateAction(actor, LightSwitchManager::SWITCH_ON_ACTION); + switchIsTurnedOn = true; + } +#else LightSwitchMgr().InitiateAction(actor, LightSwitchManager::SWITCH_ON_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { diff --git a/examples/lighting-app/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md index 5a6f6efb6a53ae..ea68690b0aefae 100644 --- a/examples/lighting-app/cc13x4_26x4/README.md +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -45,6 +45,15 @@ the Texas Instruments devices. | Green LED Blinking State | Identify Trigger Effect in progress | | Green LED Off State | No Identify Trigger Effect in progress | +When the device has LIT ICD functionality enabled (`chip_enable_icd_lit` set to +true in args.gni), the functionality of the short button presses changes as +described below: + +| Action | Functionality | +| ------------------------------------------------ | ------------------------ | +| Left Button (`BTN-1`) Press (less than 1000 ms) | User Active Mode Trigger | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Light is toggled | + ## Building ### Preparation diff --git a/examples/lighting-app/cc13x4_26x4/args.gni b/examples/lighting-app/cc13x4_26x4/args.gni index 2c9257e09e9a68..e9b2778905f153 100644 --- a/examples/lighting-app/cc13x4_26x4/args.gni +++ b/examples/lighting-app/cc13x4_26x4/args.gni @@ -41,7 +41,7 @@ openthread_external_platform = chip_openthread_target = "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" -# Disable CHIP Logging +# Enable CHIP Logging chip_progress_logging = true chip_detail_logging = true chip_automation_logging = true @@ -65,6 +65,7 @@ custom_factory_data = false chip_enable_icd_server = false chip_persist_subscriptions = false chip_subscription_timeout_resumption = false +chip_enable_icd_lit = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp index 6c4ffacdda2565..91aad59a9d1edd 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -55,6 +55,10 @@ #include #include +#if CHIP_CONFIG_ENABLE_ICD_UAT +#include "app/icd/server/ICDNotifier.h" +#endif + /* syscfg */ #include @@ -475,8 +479,12 @@ void AppTask::DispatchEvent(AppEvent * aEvent) case AppEvent::kEventType_ButtonLeft: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { +#if CHIP_CONFIG_ENABLE_ICD_UAT + PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); +#else actor = AppEvent::kEventType_ButtonLeft; LightMgr().InitiateAction(actor, LightingManager::ON_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { @@ -488,7 +496,12 @@ void AppTask::DispatchEvent(AppEvent * aEvent) if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { actor = AppEvent::kEventType_ButtonRight; +#if CHIP_CONFIG_ENABLE_ICD_UAT + LightMgr().IsLightOn() ? LightMgr().InitiateAction(actor, LightingManager::OFF_ACTION) + : LightMgr().InitiateAction(actor, LightingManager::ON_ACTION); +#else LightMgr().InitiateAction(actor, LightingManager::OFF_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { diff --git a/examples/lock-app/cc13x4_26x4/README.md b/examples/lock-app/cc13x4_26x4/README.md index c7d15dcc8533fe..57dfa75b5bfdbf 100644 --- a/examples/lock-app/cc13x4_26x4/README.md +++ b/examples/lock-app/cc13x4_26x4/README.md @@ -46,6 +46,15 @@ Instruments devices. | Red LED On State | Lock state locked | | Red & Green LED Off State | Lock state unlocked | +When the device has LIT ICD functionality enabled (`chip_enable_icd_lit` set to +true in args.gni), the functionality of the short button presses changes as +described below: + +| Action | Functionality | +| ------------------------------------------------ | ------------------------ | +| Left Button (`BTN-1`) Press (less than 1000 ms) | User Active Mode Trigger | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Lock state is toggled | + ## Building ### Preparation diff --git a/examples/lock-app/cc13x4_26x4/args.gni b/examples/lock-app/cc13x4_26x4/args.gni index c2e2e643a2f2ef..1531b21c00c365 100644 --- a/examples/lock-app/cc13x4_26x4/args.gni +++ b/examples/lock-app/cc13x4_26x4/args.gni @@ -59,12 +59,13 @@ matter_software_ver_str = "1.0.1+1" # should be maj.min.rev+build with later parts optional for MCUBoot -custom_factory_data = true +custom_factory_data = false # ICD Default configurations chip_enable_icd_server = false chip_persist_subscriptions = false chip_subscription_timeout_resumption = false +chip_enable_icd_lit = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp index f210aaf1a6e1de..43d8f61ef1ab52 100644 --- a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -54,6 +54,10 @@ #include #include +#if CHIP_CONFIG_ENABLE_ICD_UAT +#include "app/icd/server/ICDNotifier.h" +#endif + /* syscfg */ #include @@ -518,7 +522,11 @@ void AppTask::DispatchEvent(AppEvent * aEvent) case AppEvent::kEventType_ButtonLeft: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { +#if CHIP_CONFIG_ENABLE_ICD_UAT + PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); +#else LockMgr().InitiateAction(LockManager::UNLOCK_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { @@ -529,7 +537,22 @@ void AppTask::DispatchEvent(AppEvent * aEvent) case AppEvent::kEventType_ButtonRight: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { +#if CHIP_CONFIG_ENABLE_ICD_UAT + chip::app::DataModel::Nullable state; + EndpointId endpointId{ 1 }; + Attributes::LockState::Get(endpointId, state); + + if (state.Value() == DlLockState::kLocked) + { + LockMgr().InitiateAction(LockManager::UNLOCK_ACTION); + } + else + { + LockMgr().InitiateAction(LockManager::LOCK_ACTION); + } +#else LockMgr().InitiateAction(LockManager::LOCK_ACTION); +#endif } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { diff --git a/examples/pump-app/cc13x4_26x4/README.md b/examples/pump-app/cc13x4_26x4/README.md index 5cd2e3c367be79..55d4f486697458 100644 --- a/examples/pump-app/cc13x4_26x4/README.md +++ b/examples/pump-app/cc13x4_26x4/README.md @@ -45,6 +45,14 @@ Instruments devices. | Red & Green LED On State | Pump is started | | Red & Green LED Off State | Pump stopped | +When the device has LIT ICD functionality enabled (`chip_enable_icd_lit` set to +true in args.gni), the functionality of the right long button press changes as +described below: + +| Action | Functionality | +| ------------------------------------------------ | ------------------------ | +| Right Button (`BTN-2`) Press (more than 1000 ms) | User Active Mode Trigger | + ## Building ### Preparation diff --git a/examples/pump-app/cc13x4_26x4/args.gni b/examples/pump-app/cc13x4_26x4/args.gni index b14472acfe551d..03b02411caf942 100644 --- a/examples/pump-app/cc13x4_26x4/args.gni +++ b/examples/pump-app/cc13x4_26x4/args.gni @@ -58,12 +58,13 @@ matter_device_pid = "0x800A" matter_software_ver = "0x0001" matter_software_ver_str = "1.0.1+1" -custom_factory_data = true +custom_factory_data = false # ICD Default configurations chip_enable_icd_server = false chip_persist_subscriptions = false chip_subscription_timeout_resumption = false +chip_enable_icd_lit = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp index 9c409b09256d8b..0a7d6a26003221 100644 --- a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -56,6 +56,10 @@ #include #include +#if CHIP_CONFIG_ENABLE_ICD_UAT +#include "app/icd/server/ICDNotifier.h" +#endif + /* syscfg */ #include @@ -461,6 +465,12 @@ void AppTask::DispatchEvent(AppEvent * aEvent) PumpMgr().InitiateAction(0, PumpManager::START_ACTION); } } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { +#if CHIP_CONFIG_ENABLE_ICD_UAT + PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); +#endif + } break; case AppEvent::kEventType_ButtonLeft: diff --git a/examples/pump-controller-app/cc13x4_26x4/README.md b/examples/pump-controller-app/cc13x4_26x4/README.md index 9b5eb0e693426d..acdd1d035c7d38 100644 --- a/examples/pump-controller-app/cc13x4_26x4/README.md +++ b/examples/pump-controller-app/cc13x4_26x4/README.md @@ -46,6 +46,14 @@ Instruments devices. | Red & LED On State | Pump is started | | Red & Green LED Off State | Pump stopped | +When the device has LIT ICD functionality enabled (`chip_enable_icd_lit` set to +true in args.gni), the functionality of the short button presses changes as +described below: + +| Action | Functionality | +| ------------------------------------------------ | ------------------------ | +| Right Button (`BTN-2`) Press (more than 1000 ms) | User Active Mode Trigger | + ## Building ### Preparation diff --git a/examples/pump-controller-app/cc13x4_26x4/args.gni b/examples/pump-controller-app/cc13x4_26x4/args.gni index d6af087119dfe5..33e110bd070d47 100644 --- a/examples/pump-controller-app/cc13x4_26x4/args.gni +++ b/examples/pump-controller-app/cc13x4_26x4/args.gni @@ -58,12 +58,13 @@ matter_device_pid = "0x8011" matter_software_ver = "0x0001" matter_software_ver_str = "1.0.1+1" -custom_factory_data = true +custom_factory_data = false # ICD Default configurations chip_enable_icd_server = false chip_persist_subscriptions = false chip_subscription_timeout_resumption = false +chip_enable_icd_lit = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp index d437da1c06d304..ac7eb545a18f0c 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -51,6 +51,10 @@ #include #include +#if CHIP_CONFIG_ENABLE_ICD_UAT +#include "app/icd/server/ICDNotifier.h" +#endif + /* syscfg */ #include @@ -457,8 +461,13 @@ void AppTask::DispatchEvent(AppEvent * aEvent) PumpMgr().InitiateAction(0, PumpManager::START_ACTION); } } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { +#if CHIP_CONFIG_ENABLE_ICD_UAT + PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); +#endif + } break; - case AppEvent::kEventType_ButtonLeft: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 77e55b8874946c..efb66120ebd97b 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -545,7 +545,6 @@ def BuildCC13x4Target(): ]) target.AppendFixedTargets([ - TargetPart('all-clusters', app=TIApp.ALL_CLUSTERS), TargetPart('lighting', app=TIApp.LIGHTING), TargetPart('lock', app=TIApp.LOCK, openthread_ftd=True), TargetPart('pump', app=TIApp.PUMP, openthread_ftd=False), diff --git a/scripts/build/builders/ti.py b/scripts/build/builders/ti.py index f0691f541b3157..6be55b5be9ec7a 100644 --- a/scripts/build/builders/ti.py +++ b/scripts/build/builders/ti.py @@ -24,8 +24,6 @@ class TIApp(Enum): LOCK = auto() PUMP = auto() PUMP_CONTROLLER = auto() - ALL_CLUSTERS = auto() - ALL_CLUSTERS_MINIMAL = auto() LIGHTING = auto() SHELL = auto() @@ -36,10 +34,6 @@ def ExampleName(self): return 'pump-app' elif self == TIApp.PUMP_CONTROLLER: return 'pump-controller-app' - elif self == TIApp.ALL_CLUSTERS: - return 'all-clusters-app' - elif self == TIApp.ALL_CLUSTERS_MINIMAL: - return 'all-clusters-minimal-app' elif self == TIApp.LIGHTING: return 'lighting-app' elif self == TIApp.SHELL: @@ -54,10 +48,6 @@ def AppNamePrefix(self, board): return f'chip-{board.BoardName()}-pump-example' elif self == TIApp.PUMP_CONTROLLER: return f'chip-{board.BoardName()}-pump-controller-example' - elif self == TIApp.ALL_CLUSTERS: - return f'chip-{board.BoardName()}-all-clusters-example' - elif self == TIApp.ALL_CLUSTERS_MINIMAL: - return f'chip-{board.BoardName()}-all-clusters-minimal-example' elif self == TIApp.LIGHTING: return f'chip-{board.BoardName()}-lighting-example' elif self == TIApp.SHELL: diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 85246d9a88a9d1..3c5b29050621fe 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -3,7 +3,7 @@ asr-{asr582x,asr595x,asr550x}-{all-clusters,all-clusters-minimal,lighting,light- android-{arm,arm64,x86,x64,androidstudio-arm,androidstudio-arm64,androidstudio-x86,androidstudio-x64}-{chip-tool,chip-test,tv-server,tv-casting-app,java-matter-controller,kotlin-matter-controller,virtual-device-app}[-no-debug] bouffalolab-{bl602dk,bl704ldk,bl706dk,bl602-night-light,bl706-night-light,bl602-iot-matter-v1,xt-zb6-devkit}-light[-ethernet][-wifi][-thread][-easyflash][-shell][-mfd][-rotating_device_id][-rpc][-cdc][-mot][-resetcnt][-memmonitor][-115200][-fp] cc32xx-{lock,air-purifier} -ti-cc13x4_26x4-{all-clusters,lighting,lock,pump,pump-controller}[-mtd][-ftd] +ti-cc13x4_26x4-{lighting,lock,pump,pump-controller}[-mtd][-ftd] cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw930739m2evb_01,cyw930739m2evb_02}-{light,light-switch,lock,thermostat} efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,brd4187c,brd4186c,brd2703a,brd4338a}-{window-covering,switch,unit-test,light,lock,thermostat,pump}[-rpc][-with-ota-requestor][-icd][-low-power][-shell][-no-logging][-openthread-mtd][-heap-monitoring][-no-openthread-cli][-show-qr-code][-wifi][-rs9116][-wf200][-siwx917][-ipv4][-additional-data-advertising][-use-ot-lib][-use-ot-coap-lib][-no-version][-skip-rps-generation] esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing] From 7f33e09c0ffd7d22ce9e81957f6430c3f2bd6179 Mon Sep 17 00:00:00 2001 From: Thomas Lea <35579828+tleacmcsa@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:24:52 -0500 Subject: [PATCH 21/70] Fix GlobalAttributes check in TC_ACL_2_11 (#35322) * Update TC_ACL_2_11 for global attributes * fixed linter issue * Fixed GlobalAttribute check * restyled * ARL test updates - fixed AccessRestrictionProvider to honor global attributes - fixed TC_ACL_2_11.py so write and invoke ARL tests work - fixed wildcard testing in test script --- src/access/AccessRestrictionProvider.cpp | 10 ++- src/python_testing/TC_ACL_2_11.py | 77 ++++++++++++++++++------ 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/access/AccessRestrictionProvider.cpp b/src/access/AccessRestrictionProvider.cpp index e1a818fde0fc41..95e5f2b15799da 100644 --- a/src/access/AccessRestrictionProvider.cpp +++ b/src/access/AccessRestrictionProvider.cpp @@ -197,13 +197,19 @@ CHIP_ERROR AccessRestrictionProvider::DoCheck(const std::vector & entries if (requestPath.requestType == RequestType::kAttributeReadRequest || requestPath.requestType == RequestType::kAttributeWriteRequest) { - return CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL; + if (!IsGlobalAttribute(requestPath.entityId.value())) + { + return CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL; + } } break; case Type::kAttributeWriteForbidden: if (requestPath.requestType == RequestType::kAttributeWriteRequest) { - return CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL; + if (!IsGlobalAttribute(requestPath.entityId.value())) + { + return CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL; + } } break; case Type::kCommandForbidden: diff --git a/src/python_testing/TC_ACL_2_11.py b/src/python_testing/TC_ACL_2_11.py index 91df448217e2f9..5fb897f8c5b379 100644 --- a/src/python_testing/TC_ACL_2_11.py +++ b/src/python_testing/TC_ACL_2_11.py @@ -31,10 +31,11 @@ import queue import chip.clusters as Clusters -from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction +from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction, ValueDecodeFailure from chip.clusters.ClusterObjects import ALL_ACCEPTED_COMMANDS, ALL_ATTRIBUTES, ALL_CLUSTERS, ClusterEvent from chip.clusters.Objects import AccessControl -from chip.interaction_model import Status +from chip.clusters.Types import NullValue +from chip.interaction_model import InteractionModelError, Status from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -64,6 +65,15 @@ def WaitForEventReport(q: queue.Queue, expected_event: ClusterEvent): class TC_ACL_2_11(MatterBaseTest): + global_attributes = [ + Clusters.Descriptor.Attributes.GeneratedCommandList.attribute_id, + Clusters.Descriptor.Attributes.AcceptedCommandList.attribute_id, + Clusters.Descriptor.Attributes.AttributeList.attribute_id, + Clusters.Descriptor.Attributes.FeatureMap.attribute_id, + Clusters.Descriptor.Attributes.ClusterRevision.attribute_id, + Clusters.Descriptor.Attributes.EventList.attribute_id + ] + def desc_TC_ACL_2_11(self) -> str: return "[TC-ACL-2.11] Verification of Managed Device feature" @@ -113,24 +123,47 @@ async def test_TC_ACL_2_11(self): care_struct = Clusters.AccessControl.Structs.AccessRestrictionEntryStruct(E1, C1, R1) cluster = ALL_CLUSTERS[C1] - for restriction in R1: restriction_type = restriction.type ID1 = restriction.id - attribute = ALL_ATTRIBUTES[C1][ID1] - command = ALL_ACCEPTED_COMMANDS[C1][ID1] - if restriction_type == AccessControl.Enums.AccessRestrictionTypeEnum.kAttributeAccessForbidden: - await self.read_single_attribute_expect_error(cluster=cluster, attribute=attribute, error=Status.AccessRestricted, endpoint=E1) + # if ID1 is null, it means it is a wildcard. We need to read all attributes on the cluster + if ID1 is NullValue: + for attr_id, attribute in ALL_ATTRIBUTES[C1].items(): + if attr_id not in self.global_attributes: + await self.read_single_attribute_expect_error(cluster=cluster, attribute=attribute, error=Status.AccessRestricted, endpoint=E1) + else: + attribute = ALL_ATTRIBUTES[C1][ID1] + await self.read_single_attribute_expect_error(cluster=cluster, attribute=attribute, error=Status.AccessRestricted, endpoint=E1) elif restriction_type == AccessControl.Enums.AccessRestrictionTypeEnum.kAttributeWriteForbidden: - status = await self.write_single_attribute(attribute_value=attribute, endpoint_id=E1) - asserts.assert_equal(status, Status.AccessRestricted, - f"Failed to verify ACCESS_RESTRICTED when writing to Attribute {ID1} Cluster {C1} Endpoint {E1}") + if ID1 is NullValue: + for attr_id, attribute in ALL_ATTRIBUTES[C1].items(): + if attr_id not in self.global_attributes: + status = await self.write_single_attribute(attribute_value=attribute(), endpoint_id=E1, expect_success=False) + if status is not Status.UnsupportedWrite: + asserts.assert_equal(status, Status.AccessRestricted, + f"Failed to verify ACCESS_RESTRICTED when writing to Attribute {attr_id} Cluster {C1} Endpoint {E1}") + else: + attribute = ALL_ATTRIBUTES[C1][ID1] + status = await self.write_single_attribute(attribute_value=attribute(), endpoint_id=E1, expect_success=False) + asserts.assert_equal(status, Status.AccessRestricted, + f"Failed to verify ACCESS_RESTRICTED when writing to Attribute {ID1} Cluster {C1} Endpoint {E1}") elif restriction_type == AccessControl.Enums.AccessRestrictionTypeEnum.kCommandForbidden: - result = await self.send_single_cmd(cmd=command, endpoint=E1) - asserts.assert_equal(result.status, Status.AccessRestricted, - f"Failed to verify ACCESS_RESTRICTED when sending command {ID1} to Cluster {C1} Endpoint {E1}") + if ID1 is NullValue: + for cmd_id, command in ALL_ACCEPTED_COMMANDS[C1].items(): + try: + await self.send_single_cmd(cmd=command(), endpoint=E1, timedRequestTimeoutMs=1000) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.AccessRestricted, + f"Failed to verify ACCESS_RESTRICTED when sending command {cmd_id} to Cluster {C1} Endpoint {E1}") + else: + command = ALL_ACCEPTED_COMMANDS[C1][ID1] + try: + await self.send_single_cmd(cmd=command(), endpoint=E1, timedRequestTimeoutMs=1000) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.AccessRestricted, + f"Failed to verify ACCESS_RESTRICTED when sending command {ID1} to Cluster {C1} Endpoint {E1}") # Belongs to step 6, but needs to be subscribed before executing step 5: begin arru_queue = queue.Queue() @@ -160,12 +193,18 @@ async def test_TC_ACL_2_11(self): server_list = ret[endpoint][Clusters.Descriptor][Clusters.Descriptor.Attributes.ServerList] for server in server_list: cluster = Clusters.ClusterObjects.ALL_CLUSTERS[server] - await dev_ctrl.ReadAttribute(dut_node_id, [endpoint, - cluster.Attributes.GeneratedCommandList, - cluster.Attributes.AcceptedCommandList, - cluster.Attributes.AttributeList, - cluster.Attributes.FeatureMap, - cluster.Attributes.ClusterRevision]) + data = await dev_ctrl.ReadAttribute(dut_node_id, [(endpoint, cluster.Attributes.GeneratedCommandList), + (endpoint, cluster.Attributes.AcceptedCommandList), + (endpoint, cluster.Attributes.AttributeList), + (endpoint, cluster.Attributes.FeatureMap), + (endpoint, cluster.Attributes.ClusterRevision)]) + for endpoint, clusters in data.items(): + for cluster, attributes in clusters.items(): + for attribute, value in attributes.items(): + asserts.assert_false(isinstance(value, ValueDecodeFailure) and + isinstance(value.Reason, InteractionModelError) and + value.Reason.status == Status.AccessRestricted, + "AccessRestricted is not allowed on Global attributes") self.step(6) response = await self.send_single_cmd(cmd=Clusters.AccessControl.Commands.ReviewFabricRestrictions([care_struct]), endpoint=0) From 5dd517c05d0b3c1b0a662c794bc483d5d232f7e1 Mon Sep 17 00:00:00 2001 From: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> Date: Wed, 4 Sep 2024 02:29:59 +0900 Subject: [PATCH 22/70] Enhance Android Logging with setLogCallback API (#35254) * Enhance Android Logging with setLogCallback API This change adds the setLogCallback API to the AndroidChipLogging class of the Matter SDK, enhancing its logging capabilities. With this API, developers can customize logging behavior and integrate it with Android's logging system, allowing for more flexible and comprehensive logging. An example of usage in Kotlin is as follows: ChipDeviceController.loadJni() AndroidChipLogging.setLogCallback { module, priority, message -> when (priority) { Log.ERROR -> Log.e(module, message) Log.INFO -> Log.i(module, message) Log.DEBUG -> Log.d(module, message) } } Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Add s prefix for global variables Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Do not call onLogMessage callback when msg is null Handle the case where jMsg is null due to UTF decode errors in buffer. Don't call the callback when the string is null. Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Return logRedirectCallback when env is nullptr Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Use JniLocalReferenceScope instead of DeleteLocalRef Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Change type of global ref to JniGlobalReference Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Use CharToStringUTF instead of NewStringUTF Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> * Use VerifyOrReturn for CharToStringUTF Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> --------- Signed-off-by: Youngho Yoon <34558998+yhoyoon@users.noreply.github.com> --- .../android/AndroidChipPlatform-JNI.cpp | 72 +++++++++++++++++++ .../chip/platform/AndroidChipLogging.java | 7 ++ 2 files changed, 79 insertions(+) diff --git a/src/platform/android/AndroidChipPlatform-JNI.cpp b/src/platform/android/AndroidChipPlatform-JNI.cpp index 45f54835d44e08..2f758719457971 100644 --- a/src/platform/android/AndroidChipPlatform-JNI.cpp +++ b/src/platform/android/AndroidChipPlatform-JNI.cpp @@ -60,6 +60,8 @@ static bool JavaBytesToUUID(JNIEnv * env, jbyteArray value, chip::Ble::ChipBleUU namespace { JavaVM * sJVM = nullptr; JniGlobalReference sAndroidChipPlatformExceptionCls; +jmethodID sOnLogMessageMethod = nullptr; +JniGlobalReference sJavaLogCallbackObject; } // namespace CHIP_ERROR AndroidChipPlatformJNI_OnLoad(JavaVM * jvm, void * reserved) @@ -274,6 +276,76 @@ JNI_LOGGING_METHOD(void, setLogFilter)(JNIEnv * env, jclass clazz, jint level) SetLogFilter(category); } +static void ENFORCE_FORMAT(3, 0) logRedirectCallback(const char * module, uint8_t category, const char * msg, va_list args) +{ + using namespace chip::Logging; + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != nullptr); + VerifyOrReturn(sJavaLogCallbackObject.HasValidObjectRef()); + VerifyOrReturn(sOnLogMessageMethod != nullptr); + + JniLocalReferenceScope scope(env); + int priority = ANDROID_LOG_DEBUG; + switch (category) + { + case kLogCategory_Error: + priority = ANDROID_LOG_ERROR; + break; + case kLogCategory_Progress: + priority = ANDROID_LOG_INFO; + break; + case kLogCategory_Detail: + priority = ANDROID_LOG_DEBUG; + break; + default: + break; + } + + jint jPriority = static_cast(priority); + jobject jModule; + VerifyOrReturn(JniReferences::GetInstance().CharToStringUTF(CharSpan::fromCharString(module), jModule) == CHIP_NO_ERROR); + VerifyOrReturn(jModule != nullptr); + + char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; + vsnprintf(buffer, sizeof(buffer), msg, args); + jobject jMsg; + VerifyOrReturn(JniReferences::GetInstance().CharToStringUTF(CharSpan::fromCharString(buffer), jMsg) == CHIP_NO_ERROR); + VerifyOrReturn(jMsg != nullptr); + + env->CallVoidMethod(sJavaLogCallbackObject.ObjectRef(), sOnLogMessageMethod, static_cast(jModule), jPriority, + static_cast(jMsg)); +} + +JNI_LOGGING_METHOD(void, setLogCallback)(JNIEnv * env, jclass clazz, jobject callback) +{ + using namespace chip::Logging; + + if (sOnLogMessageMethod == nullptr) + { + jclass callbackClass = env->GetObjectClass(callback); + sOnLogMessageMethod = env->GetMethodID(callbackClass, "onLogMessage", "(Ljava/lang/String;ILjava/lang/String;)V"); + } + VerifyOrReturn(sOnLogMessageMethod != nullptr, + ChipLogError(DeviceLayer, "Failed to access AndroidChipLogging.LogCallback 'onLogMessage' method")); + + if (sJavaLogCallbackObject.HasValidObjectRef()) + { + sJavaLogCallbackObject.Reset(); + } + + if (env->IsSameObject(callback, NULL)) + { + SetLogRedirectCallback(nullptr); + } + else + { + VerifyOrReturn(sJavaLogCallbackObject.Init(callback) == CHIP_NO_ERROR, + ChipLogError(DeviceLayer, "Failed to init sJavaLogCallbackObject")); + SetLogRedirectCallback(logRedirectCallback); + } +} + JNI_MDNSCALLBACK_METHOD(void, handleServiceResolve) (JNIEnv * env, jclass self, jstring instanceName, jstring serviceType, jstring hostName, jstring address, jint port, jobject attributes, jlong callbackHandle, jlong contextHandle) diff --git a/src/platform/android/java/chip/platform/AndroidChipLogging.java b/src/platform/android/java/chip/platform/AndroidChipLogging.java index 4f41b21b78b732..58bcb062e80a88 100644 --- a/src/platform/android/java/chip/platform/AndroidChipLogging.java +++ b/src/platform/android/java/chip/platform/AndroidChipLogging.java @@ -20,4 +20,11 @@ public class AndroidChipLogging { // logging level is in android.util.Log class public static native void setLogFilter(int level); + + // This must be called after System.loadLibrary + public static native void setLogCallback(LogCallback callback); + + public interface LogCallback { + void onLogMessage(String module, int priority, String message); + } } From 6d8ec81eebd4334f5216eab01ee43f67ec40a06f Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:28:33 +0100 Subject: [PATCH 23/70] Add Q Quality test for EVSE (#35339) * Initial stab at Q Quality test for EVSE - but issue with events not being received so commented out for now. * Removed some debug * Fixed issue with events - keepSubscriptions needs to be True on step 4 * Updated TC_EEVSE_2_6 to check session ID does increment on next plug-in (not on unplugged). * Added StopSession() to update values once unplugged. Fixed issue with session reporting which was using (wrong) endpoint 0. Avoided recursive update when getting session duration causing attribute to be marked as dirty. Fix to state machine from real EV testing. * Corrected test script assert. * Restyled by whitespace * Restyled by clang-format * Restyled by isort * Reverted change to state machine which broke EEVSE_2_2 * Updated TC_EEVSE_2.6 based on code review comments - added step 3 for event subscription. * Updated with code review comments. --------- Co-authored-by: Restyled.io --- .../include/EnergyEvseDelegateImpl.h | 28 +- .../src/EnergyEvseDelegateImpl.cpp | 52 +++- src/python_testing/TC_EEVSE_2_6.py | 293 ++++++++++++++++++ 3 files changed, 349 insertions(+), 24 deletions(-) create mode 100644 src/python_testing/TC_EEVSE_2_6.py diff --git a/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseDelegateImpl.h b/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseDelegateImpl.h index c43707d9d09589..0b84e8fcc87c22 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseDelegateImpl.h +++ b/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseDelegateImpl.h @@ -56,33 +56,47 @@ enum EVSEStateMachineEvent class EvseSession { public: - EvseSession(EndpointId aEndpoint) { mEndpointId = aEndpoint; } + EvseSession() {} /** * @brief This function records the start time and provided energy meter values as part of the new session. * + * @param endpointId - The endpoint to report the update on * @param chargingMeterValue - The current value of the energy meter (charging) in mWh * @param dischargingMeterValue - The current value of the energy meter (discharging) in mWh */ - void StartSession(int64_t chargingMeterValue, int64_t dischargingMeterValue); + void StartSession(EndpointId endpointId, int64_t chargingMeterValue, int64_t dischargingMeterValue); + + /** + * @brief This function updates the session information at the unplugged event + * + * @param endpointId - The endpoint to report the update on + * @param chargingMeterValue - The current value of the energy meter (charging) in mWh + * @param dischargingMeterValue - The current value of the energy meter (discharging) in mWh + */ + void StopSession(EndpointId endpointId, int64_t chargingMeterValue, int64_t dischargingMeterValue); /** * @brief This function updates the session Duration to allow read attributes to return latest values + * + * @param endpointId - The endpoint to report the update on */ - void RecalculateSessionDuration(); + void RecalculateSessionDuration(EndpointId endpointId); /** * @brief This function updates the EnergyCharged meter value * + * @param endpointId - The endpoint to report the update on * @param chargingMeterValue - The value of the energy meter (charging) in mWh */ - void UpdateEnergyCharged(int64_t chargingMeterValue); + void UpdateEnergyCharged(EndpointId endpointId, int64_t chargingMeterValue); /** * @brief This function updates the EnergyDischarged meter value * + * @param endpointId - The endpoint to report the update on * @param dischargingMeterValue - The value of the energy meter (discharging) in mWh */ - void UpdateEnergyDischarged(int64_t dischargingMeterValue); + void UpdateEnergyDischarged(EndpointId endpointId, int64_t dischargingMeterValue); /* Public members - represent attributes in the cluster */ DataModel::Nullable mSessionID; @@ -91,8 +105,6 @@ class EvseSession DataModel::Nullable mSessionEnergyDischarged; private: - EndpointId mEndpointId = 0; - uint32_t mStartTime = 0; // Epoch_s - 0 means it hasn't started yet int64_t mSessionEnergyChargedAtStart = 0; // in mWh - 0 means it hasn't been set yet int64_t mSessionEnergyDischargedAtStart = 0; // in mWh - 0 means it hasn't been set yet @@ -358,7 +370,7 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate DataModel::Nullable mVehicleID; /* Session Object */ - EvseSession mSession = EvseSession(mEndpointId); + EvseSession mSession = EvseSession(); /* Helper variable to hold meter val since last EnergyTransferStarted event */ int64_t mMeterValueAtEnergyTransferStart; diff --git a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseDelegateImpl.cpp b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseDelegateImpl.cpp index 6266be245c2a4a..0294a0349e8f29 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseDelegateImpl.cpp +++ b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseDelegateImpl.cpp @@ -672,8 +672,8 @@ Status EnergyEvseDelegate::HandleEVPluggedInEvent() if (mState == StateEnum::kNotPluggedIn) { /* EV was not plugged in - start a new session */ - // TODO get energy meter readings - mSession.StartSession(0, 0); + // TODO get energy meter readings - #35370 + mSession.StartSession(mEndpointId, 0, 0); SendEVConnectedEvent(); /* Set the state to either PluggedInNoDemand or PluggedInDemand as indicated by mHwState */ @@ -694,6 +694,8 @@ Status EnergyEvseDelegate::HandleEVNotDetectedEvent() SendEnergyTransferStoppedEvent(EnergyTransferStoppedReasonEnum::kOther); } + // TODO get energy meter readings - #35370 + mSession.StopSession(mEndpointId, 0, 0); SendEVNotDetectedEvent(); SetState(StateEnum::kNotPluggedIn); return Status::Success; @@ -706,7 +708,7 @@ Status EnergyEvseDelegate::HandleEVNoDemandEvent() /* * EV was transferring current - EV decided to stop */ - mSession.RecalculateSessionDuration(); + mSession.RecalculateSessionDuration(mEndpointId); SendEnergyTransferStoppedEvent(EnergyTransferStoppedReasonEnum::kEVStopped); } /* We must still be plugged in to get here - so no need to check if we are plugged in! */ @@ -1601,7 +1603,6 @@ DataModel::Nullable EnergyEvseDelegate::GetSessionID() } DataModel::Nullable EnergyEvseDelegate::GetSessionDuration() { - mSession.RecalculateSessionDuration(); return mSession.mSessionDuration; } DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyCharged() @@ -1626,10 +1627,11 @@ bool EnergyEvseDelegate::IsEvsePluggedIn() /** * @brief This function samples the start-time, and energy meter to hold the session info * + * @param endpointId - The endpoint to report the update on * @param chargingMeterValue - The current value of the energy meter (charging) in mWh * @param dischargingMeterValue - The current value of the energy meter (discharging) in mWh */ -void EvseSession::StartSession(int64_t chargingMeterValue, int64_t dischargingMeterValue) +void EvseSession::StartSession(EndpointId endpointId, int64_t chargingMeterValue, int64_t dischargingMeterValue) { /* Get Timestamp */ uint32_t chipEpoch = 0; @@ -1661,13 +1663,13 @@ void EvseSession::StartSession(int64_t chargingMeterValue, int64_t dischargingMe mSessionEnergyCharged = MakeNullable(static_cast(0)); mSessionEnergyDischarged = MakeNullable(static_cast(0)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionID::Id); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionDuration::Id); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionEnergyCharged::Id); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionEnergyDischarged::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionID::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionDuration::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionEnergyCharged::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionEnergyDischarged::Id); // Write values to persistent storage. - ConcreteAttributePath path = ConcreteAttributePath(mEndpointId, EnergyEvse::Id, SessionID::Id); + ConcreteAttributePath path = ConcreteAttributePath(endpointId, EnergyEvse::Id, SessionID::Id); GetSafeAttributePersistenceProvider()->WriteScalarValue(path, mSessionID); // TODO persist mStartTime @@ -1675,12 +1677,28 @@ void EvseSession::StartSession(int64_t chargingMeterValue, int64_t dischargingMe // TODO persist mSessionEnergyDischargedAtStart } +/** + * @brief This function updates the session information at the unplugged event + * + * @param endpointId - The endpoint to report the update on + * @param chargingMeterValue - The current value of the energy meter (charging) in mWh + * @param dischargingMeterValue - The current value of the energy meter (discharging) in mWh + */ +void EvseSession::StopSession(EndpointId endpointId, int64_t chargingMeterValue, int64_t dischargingMeterValue) +{ + RecalculateSessionDuration(endpointId); + UpdateEnergyCharged(endpointId, chargingMeterValue); + UpdateEnergyDischarged(endpointId, dischargingMeterValue); +} + /*---------------------- EvseSession functions --------------------------*/ /** * @brief This function updates the session attrs to allow read attributes to return latest values + * + * @param endpointId - The endpoint to report the update on */ -void EvseSession::RecalculateSessionDuration() +void EvseSession::RecalculateSessionDuration(EndpointId endpointId) { /* Get Timestamp */ uint32_t chipEpoch = 0; @@ -1696,27 +1714,29 @@ void EvseSession::RecalculateSessionDuration() uint32_t duration = chipEpoch - mStartTime; mSessionDuration = MakeNullable(duration); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionDuration::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionDuration::Id); } /** * @brief This function updates the EnergyCharged meter value * + * @param endpointId - The endpoint to report the update on * @param chargingMeterValue - The value of the energy meter (charging) in mWh */ -void EvseSession::UpdateEnergyCharged(int64_t chargingMeterValue) +void EvseSession::UpdateEnergyCharged(EndpointId endpointId, int64_t chargingMeterValue) { mSessionEnergyCharged = MakeNullable(chargingMeterValue - mSessionEnergyChargedAtStart); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionEnergyCharged::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionEnergyCharged::Id); } /** * @brief This function updates the EnergyDischarged meter value * + * @param endpointId - The endpoint to report the update on * @param dischargingMeterValue - The value of the energy meter (discharging) in mWh */ -void EvseSession::UpdateEnergyDischarged(int64_t dischargingMeterValue) +void EvseSession::UpdateEnergyDischarged(EndpointId endpointId, int64_t dischargingMeterValue) { mSessionEnergyDischarged = MakeNullable(dischargingMeterValue - mSessionEnergyDischargedAtStart); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SessionEnergyDischarged::Id); + MatterReportingAttributeChangeCallback(endpointId, EnergyEvse::Id, SessionEnergyDischarged::Id); } diff --git a/src/python_testing/TC_EEVSE_2_6.py b/src/python_testing/TC_EEVSE_2_6.py new file mode 100644 index 00000000000000..4567f96c3e466a --- /dev/null +++ b/src/python_testing/TC_EEVSE_2_6.py @@ -0,0 +1,293 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --application evse +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +import time + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import (ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, TestStep, + async_test_body, default_matter_test_main) +from mobly import asserts +from TC_EEVSE_Utils import EEVSEBaseTestHelper + +logger = logging.getLogger(__name__) + + +class TC_EEVSE_2_6(MatterBaseTest, EEVSEBaseTestHelper): + + def desc_TC_EEVSE_2_6(self) -> str: + """Returns a description of this test""" + return "5.1.6. [TC-EEVSE-2.6] Test Q quality functionality with DUT as Server" + + def pics_TC_EEVSE_2_6(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + + return ["EEVSE.S"] + + def steps_TC_EEVSE_2_6(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)"), + TestStep("2", "TH reads from the DUT the FeatureMap", + "Verify that the DUT response contains the FeatureMap attribute. Store the value as FeatureMap."), + TestStep("3", "Set up a subscription to all EnergyEVSE cluster events"), + TestStep("4", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Value has to be 1 (True)"), + TestStep("5", "Set up a subscription to the EnergyEVSE cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 10 and KeepSubscriptions set to True", + "Subscription successfully established"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("6a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("8", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=12000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("9a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("10", "Reset all accumulated report counts, then wait 12 seconds"), + TestStep("10a", "TH counts all report transactions with an attribute report for the SessionID attribute", + "TH verifies that numberOfReportsReceived = 0"), + TestStep("10b", "TH counts all report transactions with an attribute report for the SessionDuration attribute", + "TH verifies that numberOfReportsReceived <= 2"), + TestStep("10c", "TH counts all report transactions with an attribute report for the SessionEnergyCharged attribute", + "TH verifies that numberOfReportsReceived <= 2"), + TestStep("10d", "TH counts all report transactions with an attribute report for the SessionEnergyDischarged attribute", + "TH verifies that numberOfReportsReceived <= 2"), + TestStep("11", "Reset all accumulated report counts"), + TestStep("12", "TH sends command Disable", + "Verify DUT responds w/ status SUCCESS(0x00) and Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("15", "Wait 5 seconds"), + TestStep("15a", "TH counts all report transactions with an attribute report for the SessionID attribute", + "TH verifies that numberOfReportsReceived = 0"), + TestStep("15b", "TH counts all report transactions with an attribute report for the SessionDuration attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("15c", "TH counts all report transactions with an attribute report for the SessionEnergyCharged attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("15d", "If V2X feature is supported on the cluster, TH counts all report transactions with an attribute report for the SessionEnergyDischarged attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("16", "Reset all accumulated report counts"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("18", "Wait 5 seconds"), + TestStep("18a", "TH counts all report transactions with an attribute report for the SessionID attribute", + "TH verifies that numberOfReportsReceived = 1"), + TestStep("18b", "TH counts all report transactions with an attribute report for the SessionDuration attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("18c", "TH counts all report transactions with an attribute report for the SessionEnergyCharged attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("18d", "If V2X feature is supported on the cluster, TH counts all report transactions with an attribute report for the SessionEnergyDischarged attribute", + "TH verifies that numberOfReportsReceived >= 1"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("21", "Cancel the subscription to the Device Energy Management cluster", + "The subscription is cancelled successfully"), + ] + + return steps + + @async_test_body + async def test_TC_EEVSE_2_6(self): + self.step("1") + # Commission DUT - already done + + self.step("2") + feature_map = await self.read_evse_attribute_expect_success(attribute="FeatureMap") + logger.info(f"FeatureMap: {feature_map}") + has_v2x = feature_map & Clusters.EnergyEvse.Bitmaps.Feature.kV2x + + # Subscribe to Events and when they are sent push them to a queue for checking later + self.step("3") + events_callback = EventChangeCallback(Clusters.EnergyEvse) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("4") + await self.check_test_event_triggers_enabled() + + self.step("5") + sub_handler = ClusterAttributeChangeAccumulator(Clusters.EnergyEvse) + await sub_handler.start(self.default_controller, self.dut_node_id, + self.matter_test_config.endpoint, + min_interval_sec=0, + max_interval_sec=10, keepSubscriptions=True) + + def accumulate_reports(wait_time): + logging.info(f"Test will now wait {wait_time} seconds to accumulate reports") + time.sleep(wait_time) + + self.step("6") + await self.send_test_event_trigger_basic() + + self.step("6a") + await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn) + + self.step("7") + await self.send_test_event_trigger_pluggedin() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) + + self.step("8") + charge_until = NullValue + min_charge_current = 6000 + max_charge_current = 12000 + await self.send_enable_charge_command(charge_until=charge_until, min_charge=min_charge_current, max_charge=max_charge_current) + + self.step("9") + await self.send_test_event_trigger_charge_demand() + event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) + + self.step("9a") + await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging) + + self.step("10") + wait = 12 # Wait 12 seconds - the spec says we should only get reports every 10s at most, unless a command changes it + sub_handler.reset() + accumulate_reports(wait) + + self.step("10a") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionID] + logging.info(f"Received {count} SessionID updates in {wait} seconds") + asserts.assert_equal(count, 0, f"Expected NO SessionID updates in {wait} seconds") + + self.step("10b") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionDuration] + logging.info(f"Received {count} SessionDuration updates in {wait} seconds") + asserts.assert_less_equal(count, 2, f"Expected <= 2 SessionDuration updates in {wait} seconds") + + self.step("10c") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyCharged] + logging.info(f"Received {count} SessionEnergyCharged updates in {wait} seconds") + asserts.assert_less_equal(count, 2, f"Expected <= 2 SessionEnergyCharged updates in {wait} seconds") + + self.step("10d") + if has_v2x: + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyDischarged] + logging.info(f"Received {count} SessionEnergyDischarged updates in {wait} seconds") + asserts.assert_less_equal(count, 2, f"Expected <= 2 SessionEnergyDischarged updates in {wait} seconds") + + self.step("11") + sub_handler.reset() + + self.step("12") + await self.send_disable_command() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) + expected_reason = Clusters.EnergyEvse.Enums.EnergyTransferStoppedReasonEnum.kEVSEStopped + asserts.assert_equal(expected_reason, event_data.reason, + f"EnergyTransferStopped event reason was {event_data.reason}, expected {expected_reason}") + + self.step("13") + await self.send_test_event_trigger_charge_demand_clear() + + self.step("14") + await self.send_test_event_trigger_pluggedin_clear() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) + + self.step("15") + wait = 5 # We expect a change to the Session attributes after the EV is unplugged, Wait 5 seconds - allow time for the report to come in + accumulate_reports(wait) + + self.step("15a") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionID] + logging.info(f"Received {count} SessionID updates in {wait} seconds") + asserts.assert_equal(count, 0, "Expected = 0 SessionID updates after a Unplugged operation - it changes on next plug-in") + + self.step("15b") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionDuration] + logging.info(f"Received {count} SessionDuration updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionDuration updates after a Unplugged operation") + + self.step("15c") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyCharged] + logging.info(f"Received {count} SessionEnergyCharged updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionEnergyCharged updates after a Unplugged operation") + + self.step("15d") + if has_v2x: + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyDischarged] + logging.info(f"Received {count} SessionEnergyDischarged updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionEnergyDischarged updates after a Unplugged operation") + + self.step("16") + sub_handler.reset() + + self.step("17") + await self.send_test_event_trigger_pluggedin() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) + + self.step("18") + wait = 5 # We expect a change to the Session attributes after the EV is plugged in again, Wait 5 seconds - allow time for the report to come in + accumulate_reports(wait) + + self.step("18a") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionID] + logging.info(f"Received {count} SessionID updates in {wait} seconds") + asserts.assert_equal(count, 1, "Expected = 1 SessionID updates after a plug-in") + + self.step("18b") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionDuration] + logging.info(f"Received {count} SessionDuration updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionDuration updates after a Unplugged operation") + + self.step("18c") + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyCharged] + logging.info(f"Received {count} SessionEnergyCharged updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionEnergyCharged updates after a Unplugged operation") + + self.step("18d") + if has_v2x: + count = sub_handler.attribute_report_counts[Clusters.EnergyEvse.Attributes.SessionEnergyDischarged] + logging.info(f"Received {count} SessionEnergyDischarged updates in {wait} seconds") + asserts.assert_greater_equal(count, 1, "Expected >= 1 SessionEnergyDischarged updates after a Unplugged operation") + + self.step("19") + await self.send_test_event_trigger_pluggedin_clear() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) + + self.step("20") + await self.send_test_event_trigger_basic_clear() + + self.step("21") + await sub_handler.cancel() + + +if __name__ == "__main__": + default_matter_test_main() From d9cfa6a6a8b45b2f6c02489e566f6867f8523d1b Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Tue, 3 Sep 2024 16:36:37 -0400 Subject: [PATCH 24/70] Make at least on/off light chef have endpoint ID > 10 (#35371) - To test corner cases where tests assume the single application endpoint is endpoint 1, this makes the only application endpoint be 13 in at least one sample. --- examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter | 2 +- examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index 4627385f5a4c44..9d4aa0c7362d22 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -2032,7 +2032,7 @@ endpoint 0 { ram attribute clusterRevision default = 1; } } -endpoint 1 { +endpoint 13 { device type ma_onofflight = 256, version 1; binding cluster Binding; diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap index e8625f2f612caf..aa402e3f0b0df2 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap @@ -3473,9 +3473,9 @@ "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 1, "profileId": 259, - "endpointId": 1, + "endpointId": 13, "networkId": 0, "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} From a704a384a5343b47c8d61ba8d5f3b0e3aba6cd0c Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 3 Sep 2024 16:53:30 -0400 Subject: [PATCH 25/70] TC-IDM-XX: try both PASE and CASE for basic comp tests. (#35109) * TC-IDM-XX: try both PASE and CASE for basic comp tests. These tests are disruptive at cert because they could run over PASE or CASE and defaulted to PASE. This meant that they couldn't be run in sequence with other tests that require commissioning. Because the PASE setup required a qr or manual code, it also meant that these needed special parameters to run. Now: - can use discriminator and passcode for PASE connection - device tries both PASE and CASE and runs over whichever works first. * fix CI * Restyled by whitespace * Restyled by clang-format * Fix tests for NO DUT (unit and mock) * Update src/python_testing/basic_composition_support.py Co-authored-by: Tennessee Carmel-Veilleux * Null terminate and add outbuf size * Restyled by clang-format * typo --------- Co-authored-by: Restyled.io Co-authored-by: Tennessee Carmel-Veilleux --- .github/workflows/tests.yaml | 4 +- .../python/ChipDeviceController-Discovery.cpp | 31 ++++++++++++ src/controller/python/chip/ChipDeviceCtrl.py | 16 +++++++ .../TC_DeviceBasicComposition.py | 46 +++++++++++++++++- .../basic_composition_support.py | 48 +++++++++++++------ src/python_testing/matter_testing_support.py | 38 ++++++++------- 6 files changed, 147 insertions(+), 36 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 9fcfc5cc5c033c..a99cc0a24d1f98 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -515,8 +515,6 @@ jobs: mkdir -p out/trace_data scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/controller/python/test/test_scripts/mobile-device-test.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/execute_python_tests.py --env-file /tmp/test_env.yaml --search-directory src/python_testing' - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --script "src/python_testing/TestMatterTestingSupport.py" --script-args "--trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --script "src/python_testing/TestSpecParsingSupport.py" --script-args "--trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' @@ -528,6 +526,8 @@ jobs: scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_IDM_10_4.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_TC_SC_7_1.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/TestDecorators.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestMatterTestingSupport.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingSupport.py' - name: Uploading core files diff --git a/src/controller/python/ChipDeviceController-Discovery.cpp b/src/controller/python/ChipDeviceController-Discovery.cpp index 7c669603f4ff1d..e4349b31bd1f09 100644 --- a/src/controller/python/ChipDeviceController-Discovery.cpp +++ b/src/controller/python/ChipDeviceController-Discovery.cpp @@ -23,12 +23,16 @@ * */ +#include + #include #include #include #include #include #include +#include +#include using namespace chip; @@ -186,4 +190,31 @@ bool pychip_DeviceController_GetIPForDiscoveredDevice(Controller::DeviceCommissi } return false; } + +PyChipError pychip_CreateManualCode(uint16_t longDiscriminator, uint32_t passcode, char * manualCodeBuffer, size_t inBufSize, + size_t * outBufSize) +{ + SetupPayload payload; + SetupDiscriminator discriminator; + discriminator.SetLongValue(longDiscriminator); + payload.discriminator = discriminator; + payload.setUpPINCode = passcode; + std::string setupManualCode; + + *outBufSize = 0; + CHIP_ERROR err = ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(setupManualCode); + if (err == CHIP_NO_ERROR) + { + MutableCharSpan span(manualCodeBuffer, inBufSize); + // Plus 1 so we copy the null terminator + CopyCharSpanToMutableCharSpan(CharSpan(setupManualCode.c_str(), setupManualCode.length() + 1), span); + *outBufSize = span.size(); + if (*outBufSize == 0) + { + err = CHIP_ERROR_NO_MEMORY; + } + } + + return ToPyChipError(err); +} } diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 24fe59486f78d5..011174185fd440 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -1711,6 +1711,19 @@ def InitGroupTestingData(self): self.devCtrl) ).raise_on_error() + def CreateManualCode(self, discriminator: int, passcode: int) -> str: + """ Creates a standard flow manual code from the given discriminator and passcode.""" + # 64 bytes is WAY more than required, but let's be safe + in_size = 64 + out_size = c_size_t(0) + buf = create_string_buffer(in_size) + self._ChipStack.Call( + lambda: self._dmLib.pychip_CreateManualCode(discriminator, passcode, buf, in_size, pointer(out_size)) + ).raise_on_error() + if out_size.value == 0 or out_size.value > in_size: + raise MemoryError("Invalid output size for manual code") + return buf.value.decode() + # ----- Private Members ----- def _InitLib(self): if self._dmLib is None: @@ -1938,6 +1951,9 @@ def _InitLib(self): self._dmLib.pychip_DeviceProxy_GetRemoteSessionParameters.restype = PyChipError self._dmLib.pychip_DeviceProxy_GetRemoteSessionParameters.argtypes = [c_void_p, c_char_p] + self._dmLib.pychip_CreateManualCode.restype = PyChipError + self._dmLib.pychip_CreateManualCode.argtypes = [c_uint16, c_uint32, c_char_p, c_size_t, POINTER(c_size_t)] + class ChipDeviceController(ChipDeviceControllerBase): ''' The ChipDeviceCommissioner binding, named as ChipDeviceController diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index 72e6e3e2418c8c..24a336e0b001e9 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -19,14 +19,58 @@ # for details about the block below. # # === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: run1 +# test-runner-runs: run1 run2 run3 run4 run5 run6 run7 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# +# test-runner-run/run2/app: ${CHIP_LOCK_APP} +# test-runner-run/run2/factoryreset: True +# test-runner-run/run2/quiet: True +# test-runner-run/run2/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run2/script-args: --storage-path admin_storage.json --manual-code 10054912339 +# +# test-runner-run/run3/app: ${CHIP_LOCK_APP} +# test-runner-run/run3/factoryreset: True +# test-runner-run/run3/quiet: True +# test-runner-run/run3/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run3/script-args: --storage-path admin_storage.json --qr-code MT:-24J0Q1212-10648G00 +# +# test-runner-run/run4/app: ${CHIP_LOCK_APP} +# test-runner-run/run4/factoryreset: True +# test-runner-run/run4/quiet: True +# test-runner-run/run4/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run4/script-args: --storage-path admin_storage.json --discriminator 1234 --passcode 20202021 +# +# test-runner-run/run5/app: ${CHIP_LOCK_APP} +# test-runner-run/run5/factoryreset: True +# test-runner-run/run5/quiet: True +# test-runner-run/run5/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run5/script-args: --storage-path admin_storage.json --manual-code 10054912339 --commissioning-method on-network +# +# test-runner-run/run6/app: ${CHIP_LOCK_APP} +# test-runner-run/run6/factoryreset: True +# test-runner-run/run6/quiet: True +# test-runner-run/run6/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run6/script-args: --storage-path admin_storage.json --qr-code MT:-24J0Q1212-10648G00 --commissioning-method on-network +# +# test-runner-run/run7/app: ${CHIP_LOCK_APP} +# test-runner-run/run7/factoryreset: True +# test-runner-run/run7/quiet: True +# test-runner-run/run7/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run7/script-args: --storage-path admin_storage.json --discriminator 1234 --passcode 20202021 --commissioning-method on-network # === END CI TEST ARGUMENTS === +# Run 1: runs through all tests +# Run 2: tests PASE connection using manual code (12.1 only) +# Run 3: tests PASE connection using QR code (12.1 only) +# Run 4: tests PASE connection using discriminator and passcode (12.1 only) +# Run 5: Tests CASE connection using manual code (12.1 only) +# Run 6: Tests CASE connection using QR code (12.1 only) +# Run 7: Tests CASE connection using manual discriminator and passcode (12.1 only) + import logging from dataclasses import dataclass from typing import Any, Callable diff --git a/src/python_testing/basic_composition_support.py b/src/python_testing/basic_composition_support.py index e25de55c0441a9..c09d78ef3027d8 100644 --- a/src/python_testing/basic_composition_support.py +++ b/src/python_testing/basic_composition_support.py @@ -15,7 +15,7 @@ # limitations under the License. # - +import asyncio import base64 import copy import json @@ -98,12 +98,15 @@ def ConvertValue(value) -> Any: class BasicCompositionTests: - async def connect_over_pase(self, dev_ctrl): - asserts.assert_true(self.matter_test_config.qr_code_content == [] or self.matter_test_config.manual_code == [], - "Cannot have both QR and manual code specified") - setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code - asserts.assert_equal(len(setupCode), 1, "Require one of either --qr-code or --manual-code.") - await dev_ctrl.FindOrEstablishPASESession(setupCode[0], self.dut_node_id) + def get_code(self, dev_ctrl): + created_codes = [] + for idx, discriminator in enumerate(self.matter_test_config.discriminators): + created_codes.append(dev_ctrl.CreateManualCode(discriminator, self.matter_test_config.setup_passcodes[idx])) + + setup_codes = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code + created_codes + asserts.assert_equal(len(setup_codes), 1, + "Require exactly one of either --qr-code, --manual-code or (--discriminator and --passcode).") + return setup_codes[0] def dump_wildcard(self, dump_device_composition_path: typing.Optional[str]) -> tuple[str, str]: """ Dumps a json and a txt file of the attribute wildcard for this device if the dump_device_composition_path is supplied. @@ -120,19 +123,34 @@ def dump_wildcard(self, dump_device_composition_path: typing.Optional[str]) -> t pprint(self.endpoints, outfile, indent=1, width=200, compact=True) return (json_dump_string, pformat(self.endpoints, indent=1, width=200, compact=True)) - async def setup_class_helper(self, default_to_pase: bool = True): + async def setup_class_helper(self, allow_pase: bool = True): dev_ctrl = self.default_controller self.problems = [] - do_test_over_pase = self.user_params.get("use_pase_only", default_to_pase) dump_device_composition_path: Optional[str] = self.user_params.get("dump_device_composition_path", None) - if do_test_over_pase: - await self.connect_over_pase(dev_ctrl) - node_id = self.dut_node_id - else: - # Using the already commissioned node - node_id = self.dut_node_id + node_id = self.dut_node_id + + task_list = [] + if allow_pase: + setup_code = self.get_code(dev_ctrl) + pase_future = dev_ctrl.EstablishPASESession(setup_code, self.dut_node_id) + task_list.append(asyncio.create_task(pase_future)) + + case_future = dev_ctrl.GetConnectedDevice(nodeid=node_id, allowPASE=False) + task_list.append(asyncio.create_task(case_future)) + + for task in task_list: + asyncio.ensure_future(task) + + done, pending = await asyncio.wait(task_list, return_when=asyncio.FIRST_COMPLETED) + + for task in pending: + try: + task.cancel() + await task + except asyncio.CancelledError: + pass wildcard_read = (await dev_ctrl.Read(node_id, [()])) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 1e0fa26ae8d722..65baf60e51752d 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -629,8 +629,8 @@ class MatterTestConfig: app_pid: int = 0 commissioning_method: Optional[str] = None - discriminators: Optional[List[int]] = None - setup_passcodes: Optional[List[int]] = None + discriminators: List[int] = field(default_factory=list) + setup_passcodes: List[int] = field(default_factory=list) commissionee_ip_address_just_for_testing: Optional[str] = None # By default, we start with maximized cert chains, as required for RR-1.1. # This allows cert tests to be run without re-commissioning for RR-1.1. @@ -646,7 +646,7 @@ class MatterTestConfig: pics: dict[bool, str] = field(default_factory=dict) # Node ID for basic DUT - dut_node_ids: Optional[List[int]] = None + dut_node_ids: List[int] = field(default_factory=list) # Node ID to use for controller/commissioner controller_node_id: int = _DEFAULT_CONTROLLER_NODE_ID # CAT Tags for default controller/commissioner @@ -1730,19 +1730,8 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf config.qr_code_content.extend(args.qr_code) config.manual_code.extend(args.manual_code) - - if args.commissioning_method is None: - return True - - if args.discriminators == [] and (args.qr_code == [] and args.manual_code == []): - print("error: Missing --discriminator when no --qr-code/--manual-code present!") - return False - config.discriminators = args.discriminators - - if args.passcodes == [] and (args.qr_code == [] and args.manual_code == []): - print("error: Missing --passcode when no --qr-code/--manual-code present!") - return False - config.setup_passcodes = args.passcodes + config.discriminators.extend(args.discriminators) + config.setup_passcodes.extend(args.passcodes) if args.qr_code != [] and args.manual_code != []: print("error: Cannot have both --qr-code and --manual-code present!") @@ -1759,9 +1748,11 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf return False if len(config.dut_node_ids) < len(device_descriptors): - missing = len(device_descriptors) - len(config.dut_node_ids) # We generate new node IDs sequentially from the last one seen for all # missing NodeIDs when commissioning many nodes at once. + if not config.dut_node_ids: + config.dut_node_ids = [_DEFAULT_DUT_NODE_ID] + missing = len(device_descriptors) - len(config.dut_node_ids) for i in range(missing): config.dut_node_ids.append(config.dut_node_ids[-1] + 1) @@ -1773,6 +1764,17 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf print("error: Duplicate value in discriminator list") return False + if args.commissioning_method is None: + return True + + if args.discriminators == [] and (args.qr_code == [] and args.manual_code == []): + print("error: Missing --discriminator when no --qr-code/--manual-code present!") + return False + + if args.passcodes == [] and (args.qr_code == [] and args.manual_code == []): + print("error: Missing --passcode when no --qr-code/--manual-code present!") + return False + if config.commissioning_method == "ble-wifi": if args.wifi_ssid is None: print("error: missing --wifi-ssid for --commissioning-method ble-wifi!") @@ -1869,7 +1871,7 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig default=_DEFAULT_CONTROLLER_NODE_ID, help='NodeID to use for initial/default controller (default: %d)' % _DEFAULT_CONTROLLER_NODE_ID) basic_group.add_argument('-n', '--dut-node-id', '--nodeId', type=int_decimal_or_hex, - metavar='NODE_ID', dest='dut_node_ids', default=[_DEFAULT_DUT_NODE_ID], + metavar='NODE_ID', dest='dut_node_ids', default=[], help='Node ID for primary DUT communication, ' 'and NodeID to assign if commissioning (default: %d)' % _DEFAULT_DUT_NODE_ID, nargs="+") basic_group.add_argument('--endpoint', type=int, default=0, help="Endpoint under test") From 91ac7b3ed9d845d00d9e2c8ce7ff9541c2c7fee9 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 3 Sep 2024 17:07:20 -0400 Subject: [PATCH 26/70] python testing: Per node endpoint fixes (#34819) * Change name of decorator * Add a force option for per endpoint tests * fix test * Add warning on force endpoint * Disallow --endpoint with automatic endpoint selection * Restyled by isort * merge conflict fix * Don't automatically override endpoint in MockRunner * Restyled by isort * Fix endpoint default on command line * Going the other way on this With the way the ATLs expect the test files currently, this is causing issues with submission. The ATLs aren't familiar with how to read these files and it's making cert challenging. Instead, we're going to gate or skip tests PER ENDPOINT such that the --endpoint flag can be set. This also (in theory) lets the tests run alongside other tests, where the --endpoint is specified. The auto-runner was too much, too soon. It's great for CI, but we don't have TH features to select these tests, nor ways to allow the file submission. Let's fall back to once per endpoint. It's still better, we're not relying on PICS. * Update comments. * Update all tests * more things * fix singleton test * Restyled by isort * fix var * Update src/python_testing/matter_testing_support.py Co-authored-by: Boris Zbarsky * Restyled by isort * add endpoint flags --------- Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- src/python_testing/TC_CCTRL_2_1.py | 4 +- src/python_testing/TC_CCTRL_2_2.py | 4 +- src/python_testing/TC_CC_2_2.py | 6 +- src/python_testing/TC_LVL_2_3.py | 6 +- src/python_testing/TC_SWTCH.py | 39 +++- src/python_testing/TC_TIMESYNC_2_1.py | 6 +- src/python_testing/matter_testing_support.py | 170 +++++++------- .../test_testing/MockTestRunner.py | 17 +- .../test_testing/TestDecorators.py | 218 +++++++++++------- .../test_testing/test_TC_CCNTL_2_2.py | 2 +- .../test_testing/test_TC_MCORE_FS_1_1.py | 2 +- 11 files changed, 269 insertions(+), 205 deletions(-) diff --git a/src/python_testing/TC_CCTRL_2_1.py b/src/python_testing/TC_CCTRL_2_1.py index 7822d101b16e02..a8aedb49ab3f2c 100644 --- a/src/python_testing/TC_CCTRL_2_1.py +++ b/src/python_testing/TC_CCTRL_2_1.py @@ -16,7 +16,7 @@ # import chip.clusters as Clusters -from matter_testing_support import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, per_endpoint_test +from matter_testing_support import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, run_if_endpoint_matches from mobly import asserts @@ -27,7 +27,7 @@ def steps_TC_CCTRL_2_1(self) -> list[TestStep]: TestStep(2, "Validate SupportedDeviceCategories is set accordingly based on MCORE.FS")] return steps - @per_endpoint_test(has_cluster(Clusters.CommissionerControl)) + @run_if_endpoint_matches(has_cluster(Clusters.CommissionerControl)) async def test_TC_CCTRL_2_1(self): self.step(1) is_fabric_sync_pics_enabled = self.check_pics("MCORE.FS") diff --git a/src/python_testing/TC_CCTRL_2_2.py b/src/python_testing/TC_CCTRL_2_2.py index ed4051feda3ebb..aa52703313ceaa 100644 --- a/src/python_testing/TC_CCTRL_2_2.py +++ b/src/python_testing/TC_CCTRL_2_2.py @@ -34,7 +34,7 @@ from chip import ChipDeviceCtrl from chip.interaction_model import InteractionModelError, Status from matter_testing_support import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main, has_cluster, - per_endpoint_test) + run_if_endpoint_matches) from mobly import asserts @@ -119,7 +119,7 @@ def steps_TC_CCTRL_2_2(self) -> list[TestStep]: return steps - @per_endpoint_test(has_cluster(Clusters.CommissionerControl)) + @run_if_endpoint_matches(has_cluster(Clusters.CommissionerControl)) async def test_TC_CCTRL_2_2(self): self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') diff --git a/src/python_testing/TC_CC_2_2.py b/src/python_testing/TC_CC_2_2.py index 86080efd358456..2cd9aef8a09f35 100644 --- a/src/python_testing/TC_CC_2_2.py +++ b/src/python_testing/TC_CC_2_2.py @@ -24,7 +24,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import logging @@ -33,7 +33,7 @@ import chip.clusters as Clusters from chip.clusters import ClusterObjects as ClusterObjects from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, - has_cluster, per_endpoint_test) + has_cluster, run_if_endpoint_matches) from mobly import asserts from test_plan_support import commission_if_required, if_feature_supported, read_attribute, verify_success @@ -107,7 +107,7 @@ def entry_count_verification() -> str: "The third entry in _reportedRemainingTimeValuesList_ is equal to 0") ] - @per_endpoint_test(has_cluster(Clusters.ColorControl)) + @run_if_endpoint_matches(has_cluster(Clusters.ColorControl)) async def test_TC_CC_2_2(self): gather_time = 20 diff --git a/src/python_testing/TC_LVL_2_3.py b/src/python_testing/TC_LVL_2_3.py index d45c459f1352d3..d0ac4c8c1ff893 100644 --- a/src/python_testing/TC_LVL_2_3.py +++ b/src/python_testing/TC_LVL_2_3.py @@ -24,7 +24,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import logging @@ -33,7 +33,7 @@ import chip.clusters as Clusters import test_plan_support from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, - has_cluster, per_endpoint_test) + has_cluster, run_if_endpoint_matches) from mobly import asserts @@ -84,7 +84,7 @@ def steps_TC_LVL_2_3(self) -> list[TestStep]: "The third entry in reportedRemainingTimeValuesList is equal to 0") ] - @per_endpoint_test(has_cluster(Clusters.LevelControl)) + @run_if_endpoint_matches(has_cluster(Clusters.LevelControl)) async def test_TC_LVL_2_3(self): # Commissioning - already done self.step(1) diff --git a/src/python_testing/TC_SWTCH.py b/src/python_testing/TC_SWTCH.py index 3db2b213428b39..3d369be456962d 100644 --- a/src/python_testing/TC_SWTCH.py +++ b/src/python_testing/TC_SWTCH.py @@ -18,13 +18,35 @@ # for details about the block below. # # === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: run1 +# test-runner-runs: run1 run2 run3 run4 +# # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# test-runner-run/run1/script-args: --endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# +# test-runner-run/run2/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run2/factoryreset: True +# test-runner-run/run2/quiet: True +# test-runner-run/run2/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run2/script-args: --endpoint 2 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# +# test-runner-run/run3/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run3/factoryreset: True +# test-runner-run/run3/quiet: True +# test-runner-run/run3/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run3/script-args: --endpoint 3 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# +# test-runner-run/run4/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run4/factoryreset: True +# test-runner-run/run4/quiet: True +# test-runner-run/run4/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run4/script-args: --endpoint 4 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# # === END CI TEST ARGUMENTS === +# +# These tests run on every endpoint regardless of whether a switch is present because they are set up to auto-select. import json import logging @@ -39,7 +61,8 @@ from chip.clusters.Attribute import EventReadResult from chip.tlv import uint from matter_testing_support import (AttributeValue, ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, - TestStep, await_sequence_of_reports, default_matter_test_main, has_feature, per_endpoint_test) + TestStep, await_sequence_of_reports, default_matter_test_main, has_feature, + run_if_endpoint_matches) from mobly import asserts logger = logging.getLogger(__name__) @@ -277,7 +300,7 @@ def steps_TC_SWTCH_2_2(self): "Verify that the value is 0, and that a subscription report was received for that change."), ] - @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kLatchingSwitch)) + @run_if_endpoint_matches(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kLatchingSwitch)) async def test_TC_SWTCH_2_2(self): post_prompt_settle_delay_seconds = 10.0 cluster = Clusters.Switch @@ -387,7 +410,7 @@ def steps_TC_SWTCH_2_3(self): TestStep(9, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), ] - @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) + @run_if_endpoint_matches(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) async def test_TC_SWTCH_2_3(self): # Commissioning - already done self.step(1) @@ -465,7 +488,7 @@ def steps_TC_SWTCH_2_4(self): """) ] - @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) + @run_if_endpoint_matches(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) async def test_TC_SWTCH_2_4(self): switch_pressed_position = self._default_pressed_position post_prompt_settle_delay_seconds = 10.0 @@ -639,7 +662,7 @@ def should_run_SWTCH_2_5(wildcard, endpoint): asf = has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kActionSwitch) return msm(wildcard, endpoint) and not asf(wildcard, endpoint) - @per_endpoint_test(should_run_SWTCH_2_5) + @run_if_endpoint_matches(should_run_SWTCH_2_5) async def test_TC_SWTCH_2_5(self): # Commissioning - already done self.step(1) @@ -818,7 +841,7 @@ def should_run_SWTCH_2_6(wildcard, endpoint): asf = has_feature(Clusters.Switch, 0x20) return msm(wildcard, endpoint) and asf(wildcard, endpoint) - @per_endpoint_test(should_run_SWTCH_2_6) + @run_if_endpoint_matches(should_run_SWTCH_2_6) async def test_TC_SWTCH_2_6(self): # Commissioning - already done self.step(1) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 1cfb22e17c7fc8..0f2fdba4d603f5 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -24,7 +24,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --endpoint 0 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import ipaddress @@ -32,7 +32,7 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue -from matter_testing_support import (MatterBaseTest, default_matter_test_main, has_attribute, has_cluster, per_endpoint_test, +from matter_testing_support import (MatterBaseTest, default_matter_test_main, has_attribute, has_cluster, run_if_endpoint_matches, utc_time_in_matter_epoch) from mobly import asserts @@ -42,7 +42,7 @@ async def read_ts_attribute_expect_success(self, attribute): cluster = Clusters.Objects.TimeSynchronization return await self.read_single_attribute_check_success(endpoint=None, cluster=cluster, attribute=attribute) - @per_endpoint_test(has_cluster(Clusters.TimeSynchronization) and has_attribute(Clusters.TimeSynchronization.Attributes.TimeSource)) + @run_if_endpoint_matches(has_cluster(Clusters.TimeSynchronization) and has_attribute(Clusters.TimeSynchronization.Attributes.TimeSource)) async def test_TC_TIMESYNC_2_1(self): attributes = Clusters.TimeSynchronization.Attributes features = await self.read_ts_attribute_expect_success(attribute=attributes.FeatureMap) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 65baf60e51752d..7c1ac60fd3910a 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -625,7 +625,7 @@ class MatterTestConfig: # List of explicit tests to run by name. If empty, all tests will run tests: List[str] = field(default_factory=list) timeout: typing.Union[int, None] = None - endpoint: int = 0 + endpoint: typing.Union[int, None] = 0 app_pid: int = 0 commissioning_method: Optional[str] = None @@ -1157,7 +1157,7 @@ async def read_single_attribute_check_success( if node_id is None: node_id = self.dut_node_id if endpoint is None: - endpoint = self.matter_test_config.endpoint + endpoint = 0 if self.matter_test_config.endpoint is None else self.matter_test_config.endpoint result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)], fabricFiltered=fabric_filtered) attr_ret = result[endpoint][cluster][attribute] @@ -1189,7 +1189,7 @@ async def read_single_attribute_expect_error( if node_id is None: node_id = self.dut_node_id if endpoint is None: - endpoint = self.matter_test_config.endpoint + endpoint = 0 if self.matter_test_config.endpoint is None else self.matter_test_config.endpoint result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)], fabricFiltered=fabric_filtered) attr_ret = result[endpoint][cluster][attribute] @@ -1218,12 +1218,13 @@ async def write_single_attribute(self, attribute_value: object, endpoint_id: int """ dev_ctrl = self.default_controller node_id = self.dut_node_id - endpoint = self.matter_test_config.endpoint if endpoint_id is None else endpoint_id + if endpoint_id is None: + endpoint_id = 0 if self.matter_test_config.endpoint is None else self.matter_test_config.endpoint - write_result = await dev_ctrl.WriteAttribute(node_id, [(endpoint, attribute_value)]) + write_result = await dev_ctrl.WriteAttribute(node_id, [(endpoint_id, attribute_value)]) if expect_success: asserts.assert_equal(write_result[0].Status, Status.Success, - f"Expected write success for write to attribute {attribute_value} on endpoint {endpoint}") + f"Expected write success for write to attribute {attribute_value} on endpoint {endpoint_id}") return write_result[0].Status async def send_single_cmd( @@ -1236,7 +1237,7 @@ async def send_single_cmd( if node_id is None: node_id = self.dut_node_id if endpoint is None: - endpoint = self.matter_test_config.endpoint + endpoint = 0 if self.matter_test_config.endpoint is None else self.matter_test_config.endpoint result = await dev_ctrl.SendCommand(nodeid=node_id, endpoint=endpoint, payload=cmd, timedRequestTimeoutMs=timedRequestTimeoutMs, payloadCapability=payloadCapability) @@ -1821,7 +1822,7 @@ def convert_args_to_matter_config(args: argparse.Namespace) -> MatterTestConfig: config.pics = {} if args.PICS is None else read_pics_from_file(args.PICS) config.tests = [] if args.tests is None else args.tests config.timeout = args.timeout # This can be none, we pull the default from the test if it's unspecified - config.endpoint = 0 if args.endpoint is None else args.endpoint + config.endpoint = args.endpoint config.app_pid = 0 if args.app_pid is None else args.app_pid config.controller_node_id = args.controller_node_id @@ -1874,7 +1875,7 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig metavar='NODE_ID', dest='dut_node_ids', default=[], help='Node ID for primary DUT communication, ' 'and NodeID to assign if commissioning (default: %d)' % _DEFAULT_DUT_NODE_ID, nargs="+") - basic_group.add_argument('--endpoint', type=int, default=0, help="Endpoint under test") + basic_group.add_argument('--endpoint', type=int, default=None, help="Endpoint under test") basic_group.add_argument('--app-pid', type=int, default=0, help="The PID of the app against which the test is going to run") basic_group.add_argument('--timeout', type=int, help="Test timeout in seconds") basic_group.add_argument("--PICS", help="PICS file path", type=str) @@ -1982,20 +1983,6 @@ def async_runner(self: MatterBaseTest, *args, **kwargs): return async_runner -def per_node_test(body): - """ Decorator to be used for PICS-free tests that apply to the entire node. - - Use this decorator when your script needs to be run once to validate the whole node. - To use this decorator, the test must NOT have an associated pics_ method. - """ - - def whole_node_runner(self: MatterBaseTest, *args, **kwargs): - asserts.assert_false(self.get_test_pics(self.current_test_info.name), "pics_ method supplied for per_node_test.") - return _async_runner(body, self, *args, **kwargs) - - return whole_node_runner - - EndpointCheckFunction = typing.Callable[[Clusters.Attribute.AsyncReadTransaction.ReadResponse, int], bool] @@ -2015,9 +2002,9 @@ def _has_cluster(wildcard, endpoint, cluster: ClusterObjects.Cluster) -> bool: def has_cluster(cluster: ClusterObjects.ClusterObjectDescriptor) -> EndpointCheckFunction: - """ EndpointCheckFunction that can be passed as a parameter to the per_endpoint_test decorator. + """ EndpointCheckFunction that can be passed as a parameter to the run_if_endpoint_matches decorator. - Use this function with the per_endpoint_test decorator to run this test on all endpoints with + Use this function with the run_if_endpoint_matches decorator to run this test on all endpoints with the specified cluster. For example, given a device with the following conformance EP0: cluster A, B, C @@ -2026,13 +2013,12 @@ def has_cluster(cluster: ClusterObjects.ClusterObjectDescriptor) -> EndpointChec EP3, cluster E And the following test specification: - @per_endpoint_test(has_cluster(Clusters.D)) + @run_if_endpoint_matches(has_cluster(Clusters.D)) test_mytest(self): ... - The test would be run on endpoint 1 and on endpoint 2. - - If the cluster is not found on any endpoint the decorator will call the on_skip function to + If you run this test with --endpoint 1 or --endpoint 2, the test will be run. If you run this test + with any other --endpoint the run_if_endpoint_matches decorator will call the on_skip function to notify the test harness that the test is not applicable to this node and the test will not be run. """ return partial(_has_cluster, cluster=cluster) @@ -2051,9 +2037,9 @@ def _has_attribute(wildcard, endpoint, attribute: ClusterObjects.ClusterAttribut def has_attribute(attribute: ClusterObjects.ClusterAttributeDescriptor) -> EndpointCheckFunction: - """ EndpointCheckFunction that can be passed as a parameter to the per_endpoint_test decorator. + """ EndpointCheckFunction that can be passed as a parameter to the run_if_endpoint_matches decorator. - Use this function with the per_endpoint_test decorator to run this test on all endpoints with + Use this function with the run_if_endpoint_matches decorator to run this test on all endpoints with the specified attribute. For example, given a device with the following conformance EP0: cluster A, B, C @@ -2062,13 +2048,12 @@ def has_attribute(attribute: ClusterObjects.ClusterAttributeDescriptor) -> Endpo EP3, cluster D without attribute d And the following test specification: - @per_endpoint_test(has_attribute(Clusters.D.Attributes.d)) + @run_if_endpoint_matches(has_attribute(Clusters.D.Attributes.d)) test_mytest(self): ... - The test would be run on endpoint 1 and on endpoint 2. - - If the cluster is not found on any endpoint the decorator will call the on_skip function to + If you run this test with --endpoint 1 or --endpoint 2, the test will be run. If you run this test + with any other --endpoint the run_if_endpoint_matches decorator will call the on_skip function to notify the test harness that the test is not applicable to this node and the test will not be run. """ return partial(_has_attribute, attribute=attribute) @@ -2087,9 +2072,9 @@ def _has_feature(wildcard, endpoint: int, cluster: ClusterObjects.ClusterObjectD def has_feature(cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFlag) -> EndpointCheckFunction: - """ EndpointCheckFunction that can be passed as a parameter to the per_endpoint_test decorator. + """ EndpointCheckFunction that can be passed as a parameter to the run_if_endpoint_matches decorator. - Use this function with the per_endpoint_test decorator to run this test on all endpoints with + Use this function with the run_if_endpoint_matches decorator to run this test on all endpoints with the specified feature. For example, given a device with the following conformance EP0: cluster A, B, C @@ -2098,31 +2083,69 @@ def has_feature(cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFla EP3: cluster D without feature F0 And the following test specification: - @per_endpoint_test(has_feature(Clusters.D.Bitmaps.Feature.F0)) + @run_if_endpoint_matches(has_feature(Clusters.D.Bitmaps.Feature.F0)) test_mytest(self): ... - The test would be run on endpoint 1 and on endpoint 2. - - If the cluster is not found on any endpoint the decorator will call the on_skip function to + If you run this test with --endpoint 1 or --endpoint 2, the test will be run. If you run this test + with any other --endpoint the run_if_endpoint_matches decorator will call the on_skip function to notify the test harness that the test is not applicable to this node and the test will not be run. """ return partial(_has_feature, cluster=cluster, feature=feature) -async def get_accepted_endpoints_for_test(self: MatterBaseTest, accept_function: EndpointCheckFunction) -> list[uint]: - """ Helper function for the per_endpoint_test decorator. +async def _get_all_matching_endpoints(self: MatterBaseTest, accept_function: EndpointCheckFunction) -> list[uint]: + """ Returns a list of endpoints matching the accept condition. """ + wildcard = await self.default_controller.Read(self.dut_node_id, [(Clusters.Descriptor), Attribute.AttributePath(None, None, GlobalAttributeIds.ATTRIBUTE_LIST_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.FEATURE_MAP_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID)]) + matching = [e for e in wildcard.attributes.keys() if accept_function(wildcard, e)] + return matching + + +async def should_run_test_on_endpoint(self: MatterBaseTest, accept_function: EndpointCheckFunction) -> bool: + """ Helper function for the run_if_endpoint_matches decorator. - Returns a list of endpoints on which the test should be run given the accept_function for the test. + Returns True if self.matter_test_config.endpoint matches the accept function. """ - wildcard = await self.default_controller.Read(self.dut_node_id, [(Clusters.Descriptor), Attribute.AttributePath(None, None, GlobalAttributeIds.ATTRIBUTE_LIST_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.FEATURE_MAP_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID)]) - return [e for e in wildcard.attributes.keys() if accept_function(wildcard, e)] + if self.matter_test_config.endpoint is None: + msg = """ + The --endpoint flag is required for this test. + """ + asserts.fail(msg) + matching = await (_get_all_matching_endpoints(self, accept_function)) + return self.matter_test_config.endpoint in matching + + +def run_on_singleton_matching_endpoint(accept_function: EndpointCheckFunction): + """ Test decorator for a test that needs to be run on the endpoint that matches the given accept function. + + This decorator should be used for tests where the endpoint is not known a-priori (dynamic endpoints). + Note that currently this test is limited to devices with a SINGLE matching endpoint. + """ + def run_on_singleton_matching_endpoint_internal(body): + def matching_runner(self: MatterBaseTest, *args, **kwargs): + runner_with_timeout = asyncio.wait_for(_get_all_matching_endpoints(self, accept_function), timeout=30) + matching = asyncio.run(runner_with_timeout) + asserts.assert_less_equal(len(matching), 1, "More than one matching endpoint found for singleton test.") + if not matching: + logging.info("Test is not applicable to any endpoint - skipping test") + asserts.skip('No endpoint matches test requirements') + return + # Exceptions should flow through, hence no except block + try: + old_endpoint = self.matter_test_config.endpoint + self.matter_test_config.endpoint = matching[0] + logging.info(f'Running test on endpoint {self.matter_test_config.endpoint}') + _async_runner(body, self, *args, **kwargs) + finally: + self.matter_test_config.endpoint = old_endpoint + return matching_runner + return run_on_singleton_matching_endpoint_internal -def per_endpoint_test(accept_function: EndpointCheckFunction): - """ Test decorator for a test that needs to be run once per endpoint that meets the accept_function criteria. +def run_if_endpoint_matches(accept_function: EndpointCheckFunction): + """ Test decorator for a test that needs to be run only if the endpoint meets the accept_function criteria. - Place this decorator above the test_ method to have the test framework run this test once per endpoint. + Place this decorator above the test_ method to have the test framework run this test only if the endpoint matches. This decorator takes an EndpointCheckFunction to assess whether a test needs to be run on a particular endpoint. @@ -2134,52 +2157,31 @@ def per_endpoint_test(accept_function: EndpointCheckFunction): EP3, cluster E And the following test specification: - @per_endpoint_test(has_cluster(Clusters.D)) + @run_if_endpoint_matches(has_cluster(Clusters.D)) test_mytest(self): ... - The test would be run on endpoint 1 and on endpoint 2. - - If the cluster is not found on any endpoint the decorator will call the on_skip function to + If you run this test with --endpoint 1 or --endpoint 2, the test will be run. If you run this test + with any other --endpoint the decorator will call the on_skip function to notify the test harness that the test is not applicable to this node and the test will not be run. - The decorator works by setting the self.matter_test_config.endpoint value and running the test function. - Therefore, tests that make use of this decorator should call controller functions against that endpoint. - Support functions in this file default to this endpoint. - Tests that use this decorator cannot use a pics_ method for test selection and should not reference any PICS values internally. """ - def per_endpoint_test_internal(body): + def run_if_endpoint_matches_internal(body): def per_endpoint_runner(self: MatterBaseTest, *args, **kwargs): - asserts.assert_false(self.get_test_pics(self.current_test_info.name), "pics_ method supplied for per_endpoint_test.") - runner_with_timeout = asyncio.wait_for(get_accepted_endpoints_for_test(self, accept_function), timeout=60) - endpoints = asyncio.run(runner_with_timeout) - if not endpoints: - logging.info("No matching endpoints found - skipping test") - asserts.skip('No endpoints match requirements') + asserts.assert_false(self.get_test_pics(self.current_test_info.name), + "pics_ method supplied for run_if_endpoint_matches.") + runner_with_timeout = asyncio.wait_for(should_run_test_on_endpoint(self, accept_function), timeout=60) + should_run_test = asyncio.run(runner_with_timeout) + if not should_run_test: + logging.info("Test is not applicable to this endpoint - skipping test") + asserts.skip('Endpoint does not match test requirements') return - logging.info(f"Running test on the following endpoints: {endpoints}") - # setup_class is meant to be called once, but setup_test is expected to be run before - # each iteration. Mobly will run it for us the first time, but since we're running this - # more than one time, we want to make sure we reset everything as expected. - # Ditto for teardown - we want to tear down after each iteration, and we want to notify the hook that - # the test iteration is stopped. test_stop is called by on_pass or on_fail during the last iteration or - # on failure. - original_ep = self.matter_test_config.endpoint - for e in endpoints: - logging.info(f'Running test on endpoint {e}') - if e != endpoints[0]: - self.setup_test() - self.matter_test_config.endpoint = e - _async_runner(body, self, *args, **kwargs) - if e != endpoints[-1] and not self.failed: - self.teardown_test() - test_duration = (datetime.now(timezone.utc) - self.test_start_time) / timedelta(microseconds=1) - self.runner_hook.test_stop(exception=None, duration=test_duration) - self.matter_test_config.endpoint = original_ep + logging.info(f'Running test on endpoint {self.matter_test_config.endpoint}') + _async_runner(body, self, *args, **kwargs) return per_endpoint_runner - return per_endpoint_test_internal + return run_if_endpoint_matches_internal class CommissionDeviceTest(MatterBaseTest): diff --git a/src/python_testing/test_testing/MockTestRunner.py b/src/python_testing/test_testing/MockTestRunner.py index 024228db7cd035..2d0afb8a5c2e67 100644 --- a/src/python_testing/test_testing/MockTestRunner.py +++ b/src/python_testing/test_testing/MockTestRunner.py @@ -38,13 +38,14 @@ async def __call__(self, *args, **kwargs): class MockTestRunner(): - def __init__(self, filename: str, classname: str, test: str, endpoint: int = 0, pics: dict[str, bool] = None, paa_trust_store_path=None): - self.test = test - self.endpoint = endpoint - self.pics = pics + def __init__(self, filename: str, classname: str, test: str, endpoint: int = None, pics: dict[str, bool] = None, paa_trust_store_path=None): self.kvs_storage = 'kvs_admin.json' - self.paa_path = paa_trust_store_path + self.config = MatterTestConfig(endpoint=endpoint, paa_trust_store_path=paa_trust_store_path, + pics=pics, storage_path=self.kvs_storage) self.set_test(filename, classname, test) + + self.set_test_config(self.config) + self.stack = MatterStackState(self.config) self.default_controller = self.stack.certificate_authorities[0].adminList[0].NewController( nodeId=self.config.controller_node_id, @@ -54,20 +55,16 @@ def __init__(self, filename: str, classname: str, test: str, endpoint: int = 0, def set_test(self, filename: str, classname: str, test: str): self.test = test - self.set_test_config() + self.config.tests = [self.test] module = importlib.import_module(Path(os.path.basename(filename)).stem) self.test_class = getattr(module, classname) def set_test_config(self, test_config: MatterTestConfig = MatterTestConfig()): self.config = test_config self.config.tests = [self.test] - self.config.endpoint = self.endpoint self.config.storage_path = self.kvs_storage - self.config.paa_trust_store_path = self.paa_path if not self.config.dut_node_ids: self.config.dut_node_ids = [1] - if self.pics: - self.config.pics = self.pics def Shutdown(self): self.stack.Shutdown() diff --git a/src/python_testing/test_testing/TestDecorators.py b/src/python_testing/test_testing/TestDecorators.py index 2ce418d6c5e43a..1ad5bc550bc237 100644 --- a/src/python_testing/test_testing/TestDecorators.py +++ b/src/python_testing/test_testing/TestDecorators.py @@ -32,12 +32,13 @@ from chip.clusters import Attribute try: - from matter_testing_support import (MatterBaseTest, async_test_body, get_accepted_endpoints_for_test, has_attribute, - has_cluster, has_feature, per_endpoint_test, per_node_test) + from matter_testing_support import (MatterBaseTest, MatterTestConfig, async_test_body, has_attribute, has_cluster, has_feature, + run_if_endpoint_matches, run_on_singleton_matching_endpoint, should_run_test_on_endpoint) except ImportError: sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) - from matter_testing_support import (MatterBaseTest, async_test_body, get_accepted_endpoints_for_test, has_attribute, - has_cluster, has_feature, per_endpoint_test, per_node_test) + from matter_testing_support import (MatterBaseTest, MatterTestConfig, async_test_body, has_attribute, + has_cluster, has_feature, run_if_endpoint_matches, run_on_singleton_matching_endpoint, + should_run_test_on_endpoint) from typing import Optional @@ -136,107 +137,101 @@ async def test_endpoints(self): all_endpoints = await self.default_controller.Read(self.dut_node_id, [()]) all_endpoints = list(all_endpoints.attributes.keys()) - msg = "Unexpected endpoint list returned" + msg = "Unexpected evaluation of should_run_test_on_endpoint" + for e in all_endpoints: + self.matter_test_config.endpoint = e + should_run = await should_run_test_on_endpoint(self, has_onoff) + asserts.assert_true(should_run, msg) - endpoints = await get_accepted_endpoints_for_test(self, has_onoff) - asserts.assert_equal(endpoints, all_endpoints, msg) + should_run = await should_run_test_on_endpoint(self, has_onoff_onoff) + asserts.assert_true(should_run, msg) - endpoints = await get_accepted_endpoints_for_test(self, has_onoff_onoff) - asserts.assert_equal(endpoints, all_endpoints, msg) + should_run = await should_run_test_on_endpoint(self, has_onoff_ontime) + asserts.assert_false(should_run, msg) - endpoints = await get_accepted_endpoints_for_test(self, has_onoff_ontime) - asserts.assert_equal(endpoints, [], msg) + should_run = await should_run_test_on_endpoint(self, has_timesync) + asserts.assert_false(should_run, msg) - endpoints = await get_accepted_endpoints_for_test(self, has_timesync) - asserts.assert_equal(endpoints, [], msg) - - endpoints = await get_accepted_endpoints_for_test(self, has_timesync_utc) - asserts.assert_equal(endpoints, [], msg) - - # This test should cause an assertion because it has pics_ method - @per_node_test - async def test_whole_node_with_pics(self): - pass - - # This method returns the top level pics for test_whole_node_with_pics - # It is used to test that test_whole_node_with_pics will fail since you can't have a whole node test gated on a PICS. - def pics_whole_node_with_pics(self): - return ['EXAMPLE.S'] + should_run = await should_run_test_on_endpoint(self, has_timesync_utc) + asserts.assert_false(should_run, msg) # This test should cause an assertion because it has a pics_ method - @per_endpoint_test(has_cluster(Clusters.OnOff)) - async def test_per_endpoint_with_pics(self): + @run_if_endpoint_matches(has_cluster(Clusters.OnOff)) + async def test_endpoint_with_pics(self): pass - # This method returns the top level pics for test_per_endpoint_with_pics - # It is used to test that test_per_endpoint_with_pics will fail since you can't have a per endpoint test gated on a PICS. - def pics_per_endpoint_with_pics(self): + # This method returns the top level pics for test_endpoint_with_pics + # It is used to test that test_endpoint_with_pics will fail since you can't have a per endpoint test gated on a PICS. + def pics_endpoint_with_pics(self): return ['EXAMPLE.S'] - # This test should be run once - @per_node_test - async def test_whole_node_ok(self): - pass - # This test should be run once per endpoint - @per_endpoint_test(has_cluster(Clusters.OnOff)) + @run_if_endpoint_matches(has_cluster(Clusters.OnOff)) async def test_endpoint_cluster_yes(self): pass # This test should be skipped since this cluster isn't on any endpoint - @per_endpoint_test(has_cluster(Clusters.TimeSynchronization)) + @run_if_endpoint_matches(has_cluster(Clusters.TimeSynchronization)) async def test_endpoint_cluster_no(self): pass # This test should be run once per endpoint - @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OnOff)) + @run_if_endpoint_matches(has_attribute(Clusters.OnOff.Attributes.OnOff)) async def test_endpoint_attribute_yes(self): pass # This test should be skipped since this attribute isn't on the supported cluster - @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OffWaitTime)) + @run_if_endpoint_matches(has_attribute(Clusters.OnOff.Attributes.OffWaitTime)) async def test_endpoint_attribute_supported_cluster_no(self): pass # This test should be skipped since this attribute is part of an unsupported cluster - @per_endpoint_test(has_attribute(Clusters.TimeSynchronization.Attributes.Granularity)) + @run_if_endpoint_matches(has_attribute(Clusters.TimeSynchronization.Attributes.Granularity)) async def test_endpoint_attribute_unsupported_cluster_no(self): pass # This test should be run once per endpoint - @per_endpoint_test(has_feature(Clusters.OnOff, Clusters.OnOff.Bitmaps.Feature.kLighting)) + @run_if_endpoint_matches(has_feature(Clusters.OnOff, Clusters.OnOff.Bitmaps.Feature.kLighting)) async def test_endpoint_feature_yes(self): pass # This test should be skipped since this attribute is part of an unsupported cluster - @per_endpoint_test(has_feature(Clusters.TimeSynchronization, Clusters.TimeSynchronization.Bitmaps.Feature.kNTPClient)) + @run_if_endpoint_matches(has_feature(Clusters.TimeSynchronization, Clusters.TimeSynchronization.Bitmaps.Feature.kNTPClient)) async def test_endpoint_feature_unsupported_cluster_no(self): pass # This test should be run since both are present - @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OnOff) and has_cluster(Clusters.OnOff)) + @run_if_endpoint_matches(has_attribute(Clusters.OnOff.Attributes.OnOff) and has_cluster(Clusters.OnOff)) async def test_endpoint_boolean_yes(self): pass # This test should be skipped since we have an OnOff cluster, but no Time sync - @per_endpoint_test(has_cluster(Clusters.OnOff) and has_cluster(Clusters.TimeSynchronization)) + @run_if_endpoint_matches(has_cluster(Clusters.OnOff) and has_cluster(Clusters.TimeSynchronization)) async def test_endpoint_boolean_no(self): pass - @per_endpoint_test(has_cluster(Clusters.OnOff)) + @run_if_endpoint_matches(has_cluster(Clusters.OnOff)) async def test_fail_on_ep0(self): if self.matter_test_config.endpoint == 0: asserts.fail("Expected failure") - @per_endpoint_test(has_cluster(Clusters.OnOff)) + @run_if_endpoint_matches(has_cluster(Clusters.OnOff)) async def test_fail_on_ep1(self): if self.matter_test_config.endpoint == 1: asserts.fail("Expected failure") - @per_node_test - async def test_fail_on_whole_node(self): + @run_on_singleton_matching_endpoint(has_cluster(Clusters.OnOff)) + async def test_run_on_singleton_matching_endpoint(self): + pass + + @run_on_singleton_matching_endpoint(has_cluster(Clusters.OnOff)) + async def test_run_on_singleton_matching_endpoint_failure(self): asserts.fail("Expected failure") + @run_on_singleton_matching_endpoint(has_attribute(Clusters.OnOff.Attributes.OffWaitTime)) + async def test_no_run_on_singleton_matching_endpoint(self): + pass + def main(): failures = [] @@ -258,82 +253,129 @@ def main(): if not ok: failures.append("Test case failure: test_endpoints") - test_name = 'test_whole_node_with_pics' - test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) - ok = test_runner.run_test_with_mock_read(read_resp, hooks) - if ok: - failures.append(f"Did not get expected test assertion on {test_name}") - - test_name = 'test_per_endpoint_with_pics' + test_name = 'test_endpoint_with_pics' test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) ok = test_runner.run_test_with_mock_read(read_resp, hooks) if ok: failures.append(f"Did not get expected test assertion on {test_name}") # Test should run once for the whole node, regardless of the number of endpoints - def run_check(test_name: str, read_response: Attribute.AsyncReadTransaction.ReadResponse, expected_runs: int, expect_skip: bool) -> None: + def run_check(test_name: str, read_response: Attribute.AsyncReadTransaction.ReadResponse, expect_skip: bool) -> None: nonlocal failures test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) hooks = DecoratorTestRunnerHooks() - ok = test_runner.run_test_with_mock_read(read_response, hooks) - started_ok = len(hooks.started) == expected_runs - skipped_ok = (hooks.skipped != []) == expect_skip - stopped_ok = hooks.stopped == expected_runs + num_endpoints = 2 + for e in [0, 1]: + test_runner.set_test_config(MatterTestConfig(endpoint=e)) + ok = test_runner.run_test_with_mock_read(read_response, hooks) + started_ok = len(hooks.started) == num_endpoints + expected_num_skips = 2 if expect_skip else 0 + skipped_ok = len(hooks.skipped) == expected_num_skips + stopped_ok = hooks.stopped == num_endpoints if not ok or not started_ok or not skipped_ok or not stopped_ok: failures.append( - f'Expected {expected_runs} run of {test_name}, skips expected: {expect_skip}. Runs: {hooks.started}, skips: {hooks.skipped} stops: {hooks.stopped}') - - def check_once_per_node(test_name: str): - run_check(test_name, get_clusters([0]), 1, False) - run_check(test_name, get_clusters([0, 1]), 1, False) + f'Expected {num_endpoints} run of {test_name}, skips expected: {expect_skip}. Runs: {hooks.started}, skips: {hooks.skipped} stops: {hooks.stopped}') def check_once_per_endpoint(test_name: str): - run_check(test_name, get_clusters([0]), 1, False) - run_check(test_name, get_clusters([0, 1]), 2, False) + run_check(test_name, get_clusters([0, 1]), False) - def check_skipped(test_name: str): - run_check(test_name, get_clusters([0]), 1, True) - run_check(test_name, get_clusters([0, 1]), 1, True) + def check_all_skipped(test_name: str): + run_check(test_name, get_clusters([0, 1]), True) - check_once_per_node('test_whole_node_ok') check_once_per_endpoint('test_endpoint_cluster_yes') - check_skipped('test_endpoint_cluster_no') + check_all_skipped('test_endpoint_cluster_no') check_once_per_endpoint('test_endpoint_attribute_yes') - check_skipped('test_endpoint_attribute_supported_cluster_no') - check_skipped('test_endpoint_attribute_unsupported_cluster_no') + check_all_skipped('test_endpoint_attribute_supported_cluster_no') + check_all_skipped('test_endpoint_attribute_unsupported_cluster_no') check_once_per_endpoint('test_endpoint_feature_yes') - check_skipped('test_endpoint_feature_unsupported_cluster_no') + check_all_skipped('test_endpoint_feature_unsupported_cluster_no') check_once_per_endpoint('test_endpoint_boolean_yes') - check_skipped('test_endpoint_boolean_no') + check_all_skipped('test_endpoint_boolean_no') test_name = 'test_fail_on_ep0' test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) read_resp = get_clusters([0, 1]) + # fail on EP0, pass on EP1 + test_runner.set_test_config(MatterTestConfig(endpoint=0)) ok = test_runner.run_test_with_mock_read(read_resp, hooks) if ok: failures.append(f"Did not get expected test assertion on {test_name}") - - test_name = 'test_fail_on_ep1' - test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) - read_resp = get_clusters([0, 1]) + test_runner.set_test_config(MatterTestConfig(endpoint=1)) ok = test_runner.run_test_with_mock_read(read_resp, hooks) - if ok: - failures.append(f"Did not get expected test assertion on {test_name}") + if not ok: + failures.append(f"Unexpected failure on {test_name}") test_name = 'test_fail_on_ep1' test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) - read_resp = get_clusters([0]) + read_resp = get_clusters([0, 1]) + # pass on EP0, fail on EP1 + test_runner.set_test_config(MatterTestConfig(endpoint=0)) ok = test_runner.run_test_with_mock_read(read_resp, hooks) if not ok: failures.append(f"Unexpected failure on {test_name}") - - test_name = 'test_fail_on_whole_node' - test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) - read_resp = get_clusters([0, 1]) + test_runner.set_test_config(MatterTestConfig(endpoint=1)) ok = test_runner.run_test_with_mock_read(read_resp, hooks) if ok: failures.append(f"Did not get expected test assertion on {test_name}") + def run_singleton_dynamic(test_name: str, cluster_list: list[int]) -> tuple[bool, DecoratorTestRunnerHooks]: + nonlocal failures + read_resp = get_clusters(cluster_list) + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + test_runner.set_test_config(MatterTestConfig(endpoint=2)) + hooks = DecoratorTestRunnerHooks() + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + # for all tests, we need to ensure the endpoint was set back to the prior values + if test_runner.config.endpoint != 2: + failures.append(f"Dynamic tests {test_name} with clusters {cluster_list} did not set endpoint back to prior") + # All tests should have a start and a stop + started_ok = len(hooks.started) == 1 + stopped_ok = hooks.stopped == 1 + if not started_ok or not stopped_ok: + failures.append( + f'Hooks failure on {test_name}, Runs: {hooks.started}, skips: {hooks.skipped} stops: {hooks.stopped}') + return ok, hooks + + def expect_success_dynamic(test_name: str, cluster_list: list[int]): + ok, hooks = run_singleton_dynamic(test_name, cluster_list) + if not ok: + failures.append(f"Unexpected failure on {test_name} with cluster list {cluster_list}") + if hooks.skipped: + failures.append(f'Unexpected skip call on {test_name} with cluster list {cluster_list}') + + def expect_failure_dynamic(test_name: str, cluster_list: list[int]): + ok, hooks = run_singleton_dynamic(test_name, cluster_list) + if ok: + failures.append(f"Unexpected success on {test_name} with cluster list {cluster_list}") + if hooks.skipped: + # We don't expect a skip call because the test actually failed. + failures.append(f'Skip called for {test_name} with cluster list {cluster_list}') + + def expect_skip_dynamic(test_name: str, cluster_list: list[int]): + ok, hooks = run_singleton_dynamic(test_name, cluster_list) + if not ok: + failures.append(f"Unexpected failure on {test_name} with cluster list {cluster_list}") + if not hooks.skipped: + # We don't expect a skip call because the test actually failed. + failures.append(f'Skip not called for {test_name} with cluster list {cluster_list}') + + test_name = 'test_run_on_singleton_matching_endpoint' + expect_success_dynamic(test_name, [0]) + expect_success_dynamic(test_name, [1]) + # expect failure because there is more than 1 endpoint + expect_failure_dynamic(test_name, [0, 1]) + + test_name = 'test_run_on_singleton_matching_endpoint_failure' + expect_failure_dynamic(test_name, [0]) + expect_failure_dynamic(test_name, [1]) + expect_failure_dynamic(test_name, [0, 1]) + + test_name = 'test_no_run_on_singleton_matching_endpoint' + # no failure, no matches, expect skips on all endpoints + expect_skip_dynamic(test_name, [0]) + expect_skip_dynamic(test_name, [1]) + expect_skip_dynamic(test_name, [0, 1]) + test_runner.Shutdown() print( f"Test of Decorators: test response incorrect: {len(failures)}") diff --git a/src/python_testing/test_testing/test_TC_CCNTL_2_2.py b/src/python_testing/test_testing/test_TC_CCNTL_2_2.py index 77971779fecbfc..d528b5652e1b45 100644 --- a/src/python_testing/test_testing/test_TC_CCNTL_2_2.py +++ b/src/python_testing/test_testing/test_TC_CCNTL_2_2.py @@ -178,7 +178,7 @@ def main(th_server_app: str): print(f'paa = {paa_path}') pics = {"PICS_SDK_CI_ONLY": True} - test_runner = MyMock('TC_CCTRL_2_2', 'TC_CCTRL_2_2', 'test_TC_CCTRL_2_2', 1, paa_trust_store_path=paa_path, pics=pics) + test_runner = MyMock('TC_CCTRL_2_2', 'TC_CCTRL_2_2', 'test_TC_CCTRL_2_2', paa_trust_store_path=paa_path, pics=pics) config = MatterTestConfig() config.global_test_params = {'th_server_app_path': th_server_app} test_runner.set_test_config(config) diff --git a/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py b/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py index ec91db72551523..5b2e29b71915b1 100644 --- a/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py +++ b/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py @@ -149,7 +149,7 @@ def main(th_server_app: str): print(f'paa = {paa_path}') pics = {"PICS_SDK_CI_ONLY": True} - test_runner = MyMock('TC_MCORE_FS_1_1', 'TC_MCORE_FS_1_1', 'test_TC_MCORE_FS_1_1', 1, paa_trust_store_path=paa_path, pics=pics) + test_runner = MyMock('TC_MCORE_FS_1_1', 'TC_MCORE_FS_1_1', 'test_TC_MCORE_FS_1_1', paa_trust_store_path=paa_path, pics=pics) config = MatterTestConfig() config.user_params = {'th_server_app_path': th_server_app} test_runner.set_test_config(config) From ee40a181d407cabe738b4e454ad55b8100cf42cc Mon Sep 17 00:00:00 2001 From: Saravana Perumal K <104007654+Saravana-kr22@users.noreply.github.com> Date: Wed, 4 Sep 2024 03:10:13 +0530 Subject: [PATCH 27/70] Updated yaml script as per the SQA issues (#35253) * Updated yaml script as the SQA issues * Restyled by whitespace * Restyled by prettier-yaml * Updated NumberOfHolidaySchedulesSupportedValue as per test plan * Restyled by whitespace * Updated DRLK-2.6 yaml * Updated DRlk Yaml as per the comments --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_DRLK_2_10.yaml | 333 +++++++--------- .../certification/Test_TC_DRLK_2_11.yaml | 76 ++-- .../certification/Test_TC_DRLK_2_6.yaml | 36 +- .../certification/Test_TC_DRLK_2_7.yaml | 113 ++---- .../certification/Test_TC_DRLK_2_8.yaml | 10 + .../suites/certification/Test_TC_IDM_3_2.yaml | 47 ++- .../suites/certification/Test_TC_IDM_5_2.yaml | 68 ++-- .../suites/certification/Test_TC_IDM_6_1.yaml | 3 +- .../suites/certification/Test_TC_LVL_8_1.yaml | 361 ++++++++++++++++++ .../suites/certification/Test_TC_LVL_9_1.yaml | 26 +- 10 files changed, 674 insertions(+), 399 deletions(-) create mode 100644 src/app/tests/suites/certification/Test_TC_LVL_8_1.yaml diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml index 321e04f55f3e2a..d608353dd5393b 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml @@ -34,24 +34,14 @@ tests: 2. Build respective app (lock-app) 3. Commission DUT to TH 4. Open 2nd terminal of DUT and provide the below command to obtain PID of DUT - ps -aef|grep lock-app + ps -aef|grep lock-app 5. Follow the Verification step below to generate the event in 2nd terminal of DUT - Pre-Conditions "1 TH is commissioned with the DUT 2 Lock device is the DUT - Before sending the Events proceed following steps: - - 1. Send Set User Command and Get User for setting User. - - 2. Send Set Credential Command and Get Credential Status for setting PIN code. - - After sending Events with all condition proceed following step - - 1. Send Clear Credential and Clear User Command." disabled: true - label: @@ -62,9 +52,10 @@ tests: To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in lock-app to generate the event, Vendor Dut should have capability to generate this event) echo '{"Cmd": "SendDoorLockAlarm", "Params": { "EndpointId": 1, "AlarmCode": 0 } }' > /tmp/chip_lock_app_fifo- (PID of lock-app) + For example : - echo '{"Cmd": "SendDoorLockAlarm", "Params": { "EndpointId": 1, "AlarmCode": 0 } }' > /tmp/chip_lock_app_fifo-3940 (PID may vary based on the actual DUT) + echo '{"Cmd": "SendDoorLockAlarm", "Params": { "EndpointId": 1, "AlarmCode": 0 } }' > /tmp/chip_lock_app_fifo-3940 (PID may vary based on the actual DUT) disabled: true - label: "Step 1b: TH reads the DoorLockAlarm event from DUT" @@ -82,6 +73,7 @@ tests: [1659521453.110507][4098:4103] CHIP:TOO: DoorLockAlarm: { [1659521453.110557][4098:4103] CHIP:TOO: AlarmCode: 0 [1659521453.110591][4098:4103] CHIP:TOO: } + disabled: true - label: "Step 2a: Trigger the DUT to generate DoorStateChange Event" @@ -109,16 +101,57 @@ tests: disabled: true - label: - "Step 3a: TH sends the Lock Door command (using Remote) to the DUT - with valid PINCode" - PICS: DRLK.S.C00.Rsp + "Step 2c: TH sends SetUser Command to DUT with the following values: + a) OperationType as 0, b)UserIndex as 1, c)UserName as xxx, + d)UserUniqueID as 6452, e)UserStatus as 1, f)UserType as 0, + g)CredentialRule as 0" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp verification: | ./chip-tool doorlock set-user 0 1 xxx 6452 1 0 0 1 1 --timedInteractionTimeoutMs 1000 Via the TH (chip-tool), verify the SUCCESS response for setting the Users details. - [1656497453.684077][25847:25853] CHIP:DMG: status = 0x00 (SUCCESS), + [1721036387.039] [100957:100959] [DMG] StatusIB = + [1721036387.039] [100957:100959] [DMG] { + [1721036387.039] [100957:100959] [DMG] status = 0x00 (SUCCESS), + [1721036387.040] [100957:100959] [DMG] }, + disabled: true + + - label: + "Step 2d: TH reads MinPINCodeLength attribute and saves the value as + min_pin_code_length." + PICS: DRLK.S.F08 && DRLK.S.F00 + verification: | + ./chip-tool doorlock read min-pincode-length 1 1 + + Via the TH (chip-tool), verify that the MinPINCodeLength attribute contains value in the range of 0 to 255. + + [1654680280.327488][3639:3644] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Attribute 0x0000_0018 DataVersion: 3738767914 + [1654680280.327558][3639:3644] CHIP:TOO: MinPINCodeLength: 6 + disabled: true + + - label: + "Step 2e: TH reads MaxPINCodeLength attribute and saves the value as + max_pin_code_length" + PICS: DRLK.S.F08 && DRLK.S.F00 + verification: | + ./chip-tool doorlock read max-pincode-length 1 1 + Via the TH (chip-tool), verify that the MaxPINCodeLength attribute contains value in the range of 0 to 255. + + [1654680165.815239][3630:3635] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Attribute 0x0000_0017 DataVersion: 3738767914 + [1654680165.815374][3630:3635] CHIP:TOO: MaxPINCodeLength: 8 + disabled: true + + - label: + "Step 2f: TH sends SetCredential Command to DUT with the following + fields and CredentialData Length is in an inclusive range of + min_pin_code_length to max_pin_code_length, CredentialData='123456' a) + OperationType as 0, b) Credential as 1 2, c) CredentialData as 123456, + d) UserIndex as 1, e) UserStatus as null f) UserType as null. Save + CredentialData as pin_code" + PICS: DRLK.S.F08 && DRLK.S.F00 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx + verification: | ./chip-tool doorlock set-credential 0 '{ "credentialType" : 1 , "credentialIndex" : 2 }' 123456 1 null null 1 1 --timedInteractionTimeoutMs 1000 Via the TH (chip-tool), verify the SUCCESS response for setting the credential details. @@ -127,7 +160,13 @@ tests: [1656497508.814257][25858:25863] CHIP:TOO: status: 0 [1656497508.814301][25858:25863] CHIP:TOO: userIndex: null [1656497508.814343][25858:25863] CHIP:TOO: nextCredentialIndex: 3 + disabled: true + - label: + "Step 3a: TH sends the Lock Door command (using Remote) to the DUT + with valid PINCode" + PICS: DRLK.S.C00.Rsp + verification: | ./chip-tool doorlock lock-door 1 1 --timedInteractionTimeoutMs 1000 --PINCode 123456 Via the TH (chip-tool), verify the SUCCESS response for door lock operation with valid PINCode. @@ -137,15 +176,6 @@ tests: [1654687870.020756][4246:4251] CHIP:DMG: { [1654687870.020797][4246:4251] CHIP:DMG: status = 0x00 (SUCCESS), [1654687870.020837][4246:4251] CHIP:DMG: }, - [1654687870.020879][4246:4251] CHIP:DMG: - [1654687870.020919][4246:4251] CHIP:DMG: }, - [1654687870.020963][4246:4251] CHIP:DMG: - [1654687870.020994][4246:4251] CHIP:DMG: }, - [1654687870.021033][4246:4251] CHIP:DMG: - [1654687870.021063][4246:4251] CHIP:DMG: ], - [1654687870.021100][4246:4251] CHIP:DMG: - [1654687870.021130][4246:4251] CHIP:DMG: InteractionModelRevision = 1 - [1654687870.021160][4246:4251] CHIP:DMG: }," disabled: true - label: "Step 3b: TH reads the LockOperation event from DUT" @@ -192,16 +222,6 @@ tests: [1659777464.384997][3157:3162] CHIP:DMG: { [1659777464.385032][3157:3162] CHIP:DMG: status = 0x00 (SUCCESS), [1659777464.385067][3157:3162] CHIP:DMG: }, - [1659777464.385099][3157:3162] CHIP:DMG: - [1659777464.385128][3157:3162] CHIP:DMG: }, - [1659777464.385162][3157:3162] CHIP:DMG: - [1659777464.385189][3157:3162] CHIP:DMG: }, - [1659777464.385221][3157:3162] CHIP:DMG: - [1659777464.385244][3157:3162] CHIP:DMG: ], - [1659777464.385272][3157:3162] CHIP:DMG: - [1659777464.385295][3157:3162] CHIP:DMG: InteractionModelRevision = 1 - [1659777464.385318][3157:3162] CHIP:DMG: }, - [1659777464.385375][3157:3162] CHIP:DMG: Received Command Response Status for Endpoint=1 Cluster=0x0000_0101 Command=0x0000_0001 Status=0x0 disabled: true - label: "Step 3d: TH reads the LockOperation event from DUT" @@ -338,17 +358,6 @@ tests: [1659777735.863849][3232:3237] CHIP:DMG: { [1659777735.863888][3232:3237] CHIP:DMG: status = 0x01 (FAILURE), [1659777735.863925][3232:3237] CHIP:DMG: }, - [1659777735.863962][3232:3237] CHIP:DMG: - [1659777735.863996][3232:3237] CHIP:DMG: }, - [1659777735.864038][3232:3237] CHIP:DMG: - [1659777735.864068][3232:3237] CHIP:DMG: }, - [1659777735.864104][3232:3237] CHIP:DMG: - [1659777735.864133][3232:3237] CHIP:DMG: ], - [1659777735.864166][3232:3237] CHIP:DMG: - [1659777735.864192][3232:3237] CHIP:DMG: InteractionModelRevision = 1 - [1659777735.864218][3232:3237] CHIP:DMG: }, - [1659777735.864281][3232:3237] CHIP:DMG: Received Command Response Status for Endpoint=1 Cluster=0x0000_0101 Command=0x0000_0000 Status=0x1 - [1659777735.864317][3232:3237] CHIP:TOO: Error: IM Error 0x00000501: General error: 0x01 (FAILURE) disabled: true - label: "Step 4b: TH reads the LockOperationError event from DUT" @@ -356,26 +365,26 @@ tests: verification: | ./chip-tool doorlock read-event lock-operation-error 1 1 - Via the TH (chip-tool), verify that the: - -LockOperationType value as 0(Lock). - -OperationSource value as 7(Remote). - -OperationError is set to 1(InvalidCredential). - -Priority is set to Critical. - - [1659777833.226970][3243:3248] CHIP:DMG: } - [1659777833.227194][3243:3248] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Event 0x0000_0003 - [1659777833.227221][3243:3248] CHIP:TOO: Event number: 8 - [1659777833.227243][3243:3248] CHIP:TOO: Priority: Critical - [1659777833.227264][3243:3248] CHIP:TOO: Timestamp: 3439177 - [1659777833.227367][3243:3248] CHIP:TOO: LockOperationError: { - [1659777833.227407][3243:3248] CHIP:TOO: LockOperationType: 0 - [1659777833.227431][3243:3248] CHIP:TOO: OperationSource: 7 - [1659777833.227453][3243:3248] CHIP:TOO: OperationError: 1 - [1659777833.227476][3243:3248] CHIP:TOO: UserIndex: null - [1659777833.227498][3243:3248] CHIP:TOO: FabricIndex: 1 - [1659777833.227523][3243:3248] CHIP:TOO: SourceNode: 112233 - [1659777833.227553][3243:3248] CHIP:TOO: Credentials: null - [1659777833.227696][3243:3248] CHIP:TOO: } + Via the TH (chip-tool), verify that the: + -LockOperationType value as 0(Lock). + -OperationSource value as 7(Remote). + -OperationError is set to 1(InvalidCredential). + -Priority is set to Critical. + + [1659777833.226970][3243:3248] CHIP:DMG: } + [1659777833.227194][3243:3248] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Event 0x0000_0003 + [1659777833.227221][3243:3248] CHIP:TOO: Event number: 8 + [1659777833.227243][3243:3248] CHIP:TOO: Priority: Critical + [1659777833.227264][3243:3248] CHIP:TOO: Timestamp: 3439177 + [1659777833.227367][3243:3248] CHIP:TOO: LockOperationError: { + [1659777833.227407][3243:3248] CHIP:TOO: LockOperationType: 0 + [1659777833.227431][3243:3248] CHIP:TOO: OperationSource: 7 + [1659777833.227453][3243:3248] CHIP:TOO: OperationError: 1 + [1659777833.227476][3243:3248] CHIP:TOO: UserIndex: null + [1659777833.227498][3243:3248] CHIP:TOO: FabricIndex: 1 + [1659777833.227523][3243:3248] CHIP:TOO: SourceNode: 112233 + [1659777833.227553][3243:3248] CHIP:TOO: Credentials: null + [1659777833.227696][3243:3248] CHIP:TOO: } disabled: true - label: @@ -384,23 +393,13 @@ tests: verification: | ./chip-tool doorlock unlock-door 1 1 --timedInteractionTimeoutMs 1000 --PINCode 12345678 - Via the TH (chip-tool), verify the FAILURE response for door unlock operation with invalid PINCode. + Via the TH (chip-tool), verify the FAILURE response for door unlock operation with invalid PINCode. - [1659777885.573854][3251:3256] CHIP:DMG: StatusIB = - [1659777885.573896][3251:3256] CHIP:DMG: { - [1659777885.573938][3251:3256] CHIP:DMG: status = 0x01 (FAILURE), - [1659777885.573981][3251:3256] CHIP:DMG: }, - [1659777885.574025][3251:3256] CHIP:DMG: - [1659777885.574064][3251:3256] CHIP:DMG: }, - [1659777885.574105][3251:3256] CHIP:DMG: - [1659777885.574138][3251:3256] CHIP:DMG: }, - [1659777885.574177][3251:3256] CHIP:DMG: - [1659777885.574205][3251:3256] CHIP:DMG: ], - [1659777885.574240][3251:3256] CHIP:DMG: - [1659777885.574268][3251:3256] CHIP:DMG: InteractionModelRevision = 1 - [1659777885.574296][3251:3256] CHIP:DMG: }, - [1659777885.574366][3251:3256] CHIP:DMG: Received Command Response Status for Endpoint=1 Cluster=0x0000_0101 Command=0x0000_0001 Status=0x1 - [1659777885.574405][3251:3256] CHIP:TOO: Error: IM Error 0x00000501: General error: 0x01 (FAILURE) + [1659777885.573854][3251:3256] CHIP:DMG: StatusIB = + [1659777885.573896][3251:3256] CHIP:DMG: { + [1659777885.573938][3251:3256] CHIP:DMG: status = 0x01 (FAILURE), + [1659777885.573981][3251:3256] CHIP:DMG: }, + [1659777885.574025][3251:3256] CHIP:DMG: disabled: true - label: "Step 4d: TH reads the LockOperationError event from DUT" @@ -464,7 +463,7 @@ tests: - label: "Step 5b: TH reads the LockUserChange event from DUT" PICS: DRLK.S.E04 verification: | - ./chip-tool doorlock read-event lock-user-change 1 1 + ./chip-tool doorlock read-event lock-user-change 1 1 Via the TH (chip-tool), verify that the: -LockDataType is set to 2 (UserIndex). @@ -474,44 +473,44 @@ tests: [1659778039.468487][3278:3283] CHIP:DMG: } [1659778039.468725][3278:3283] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Event 0x0000_0004 - [1659778039.468757][3278:3283] CHIP:TOO: Event number: 3 - [1659778039.468783][3278:3283] CHIP:TOO: Priority: Info - [1659778039.468808][3278:3283] CHIP:TOO: Timestamp: 3309634 - [1659778039.468915][3278:3283] CHIP:TOO: LockUserChange: { - [1659778039.468956][3278:3283] CHIP:TOO: LockDataType: 2 - [1659778039.468984][3278:3283] CHIP:TOO: DataOperationType: 0 - [1659778039.469010][3278:3283] CHIP:TOO: OperationSource: 7 - [1659778039.469036][3278:3283] CHIP:TOO: UserIndex: 1 - [1659778039.469061][3278:3283] CHIP:TOO: FabricIndex: 1 - [1659778039.469088][3278:3283] CHIP:TOO: SourceNode: 112233 - [1659778039.469114][3278:3283] CHIP:TOO: DataIndex: 1 - [1659778039.469137][3278:3283] CHIP:TOO: } + [1659778039.468757][3278:3283] CHIP:TOO: Event number: 3 + [1659778039.468783][3278:3283] CHIP:TOO: Priority: Info + [1659778039.468808][3278:3283] CHIP:TOO: Timestamp: 3309634 + [1659778039.468915][3278:3283] CHIP:TOO: LockUserChange: { + [1659778039.468956][3278:3283] CHIP:TOO: LockDataType: 2 + [1659778039.468984][3278:3283] CHIP:TOO: DataOperationType: 0 + [1659778039.469010][3278:3283] CHIP:TOO: OperationSource: 7 + [1659778039.469036][3278:3283] CHIP:TOO: UserIndex: 1 + [1659778039.469061][3278:3283] CHIP:TOO: FabricIndex: 1 + [1659778039.469088][3278:3283] CHIP:TOO: SourceNode: 112233 + [1659778039.469114][3278:3283] CHIP:TOO: DataIndex: 1 + [1659778039.469137][3278:3283] CHIP:TOO: } [1659778039.469250][3278:3283] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Event 0x0000_0004 - [1659778039.469320][3278:3283] CHIP:TOO: Event number: 4 - [1659778039.469344][3278:3283] CHIP:TOO: Priority: Info - [1659778039.469369][3278:3283] CHIP:TOO: Timestamp: 3318674 - [1659778039.469429][3278:3283] CHIP:TOO: LockUserChange: { - [1659778039.469457][3278:3283] CHIP:TOO: LockDataType: 6 - [1659778039.469483][3278:3283] CHIP:TOO: DataOperationType: 0 - [1659778039.469508][3278:3283] CHIP:TOO: OperationSource: 7 - [1659778039.469532][3278:3283] CHIP:TOO: UserIndex: 1 - [1659778039.469557][3278:3283] CHIP:TOO: FabricIndex: 1 - [1659778039.469582][3278:3283] CHIP:TOO: SourceNode: 112233 - [1659778039.469607][3278:3283] CHIP:TOO: DataIndex: 1 - [1659778039.469632][3278:3283] CHIP:TOO: } + [1659778039.469320][3278:3283] CHIP:TOO: Event number: 4 + [1659778039.469344][3278:3283] CHIP:TOO: Priority: Info + [1659778039.469369][3278:3283] CHIP:TOO: Timestamp: 3318674 + [1659778039.469429][3278:3283] CHIP:TOO: LockUserChange: { + [1659778039.469457][3278:3283] CHIP:TOO: LockDataType: 6 + [1659778039.469483][3278:3283] CHIP:TOO: DataOperationType: 0 + [1659778039.469508][3278:3283] CHIP:TOO: OperationSource: 7 + [1659778039.469532][3278:3283] CHIP:TOO: UserIndex: 1 + [1659778039.469557][3278:3283] CHIP:TOO: FabricIndex: 1 + [1659778039.469582][3278:3283] CHIP:TOO: SourceNode: 112233 + [1659778039.469607][3278:3283] CHIP:TOO: DataIndex: 1 + [1659778039.469632][3278:3283] CHIP:TOO: } [1659778039.469739][3278:3283] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Event 0x0000_0004 - [1659778039.469765][3278:3283] CHIP:TOO: Event number: 10 - [1659778039.469790][3278:3283] CHIP:TOO: Priority: Info - [1659778039.469815][3278:3283] CHIP:TOO: Timestamp: 3692303 - [1659778039.469851][3278:3283] CHIP:TOO: LockUserChange: { - [1659778039.469878][3278:3283] CHIP:TOO: LockDataType: 2 - [1659778039.469903][3278:3283] CHIP:TOO: DataOperationType: 0 - [1659778039.469981][3278:3283] CHIP:TOO: OperationSource: 7 - [1659778039.470006][3278:3283] CHIP:TOO: UserIndex: 2 - [1659778039.470031][3278:3283] CHIP:TOO: FabricIndex: 1 - [1659778039.470056][3278:3283] CHIP:TOO: SourceNode: 112233 - [1659778039.470081][3278:3283] CHIP:TOO: DataIndex: 4 - [1659778039.470104][3278:3283] CHIP:TOO: } + [1659778039.469765][3278:3283] CHIP:TOO: Event number: 10 + [1659778039.469790][3278:3283] CHIP:TOO: Priority: Info + [1659778039.469815][3278:3283] CHIP:TOO: Timestamp: 3692303 + [1659778039.469851][3278:3283] CHIP:TOO: LockUserChange: { + [1659778039.469878][3278:3283] CHIP:TOO: LockDataType: 2 + [1659778039.469903][3278:3283] CHIP:TOO: DataOperationType: 0 + [1659778039.469981][3278:3283] CHIP:TOO: OperationSource: 7 + [1659778039.470006][3278:3283] CHIP:TOO: UserIndex: 2 + [1659778039.470031][3278:3283] CHIP:TOO: FabricIndex: 1 + [1659778039.470056][3278:3283] CHIP:TOO: SourceNode: 112233 + [1659778039.470081][3278:3283] CHIP:TOO: DataIndex: 4 + [1659778039.470104][3278:3283] CHIP:TOO: } disabled: true - label: @@ -528,15 +527,6 @@ tests: [1658142169.347900][2900:2905] CHIP:DMG: { [1658142169.347945][2900:2905] CHIP:DMG: status = 0x00 (SUCCESS), [1658142169.347986][2900:2905] CHIP:DMG: }, - [1658142169.348030][2900:2905] CHIP:DMG: - [1658142169.348066][2900:2905] CHIP:DMG: }, - [1658142169.348112][2900:2905] CHIP:DMG: - [1658142169.348146][2900:2905] CHIP:DMG: }, - [1658142169.348195][2900:2905] CHIP:DMG: - [1658142169.348227][2900:2905] CHIP:DMG: ], - [1658142169.348267][2900:2905] CHIP:DMG: - [1658142169.348300][2900:2905] CHIP:DMG: InteractionModelRevision = 1 - [1658142169.348331][2900:2905] CHIP:DMG: }, disabled: true - label: "Step 5d: TH reads the LockUserChange event from DUT" @@ -606,11 +596,9 @@ tests: disabled: true - label: - "Step 5e: TH sends Set Credential Command to DUT with the following - fields: 1.OperationType as 0-Add 2.Credential as 1 1- PIN, Index - 3.CredentialData as 123456 4.UserIndex as 1 5.UserStatus as null - 6.UserType as null" - PICS: DRLK.S.F08 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx + "Step 5e: TH sends ClearCredential Command to DUT with the following + fields: a) CredentialType as 1, b) CredentialIndex as 2" + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C26.Tx verification: | ./chip-tool doorlock clear-credential '{ "credentialType" : 1 , "credentialIndex" : 2 }' 1 1 --timedInteractionTimeoutMs 1000 @@ -621,8 +609,15 @@ tests: [1658995364.178088][4383:4388] CHIP:DMG: { [1658995364.178137][4383:4388] CHIP:DMG: status = 0x00 (SUCCESS), [1658995364.178185][4383:4388] CHIP:DMG: }, + disabled: true - + - label: + "Step 5f: TH sends Set Credential Command to DUT with the following + fields: 1.OperationType as 0-Add 2.Credential as 1 1- PIN, Index + 3.CredentialData as 123456 4.UserIndex as 1 5.UserStatus as null + 6.UserType as null" + PICS: DRLK.S.F08 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx + verification: | ./chip-tool doorlock set-user 0 1 xxx 6452 1 0 0 1 1 --timedInteractionTimeoutMs 1000 Via the TH (chip-tool), verify the SUCCESS response for setting the users details. @@ -631,17 +626,12 @@ tests: [1659778601.601636][3414:3419] CHIP:DMG: { [1659778601.601671][3414:3419] CHIP:DMG: status = 0x00 (SUCCESS), [1659778601.601713][3414:3419] CHIP:DMG: }, - [1659778601.601746][3414:3419] CHIP:DMG: - [1659778601.601785][3414:3419] CHIP:DMG: }, - [1659778601.601823][3414:3419] CHIP:DMG: + ./chip-tool doorlock set-credential 0 '{ "credentialType" : 1 , "credentialIndex" : 1 }' 123456 1 null null 1 1 --timedInteractionTimeoutMs 1000 Via the TH (chip-tool), verify the SUCCESS response for setting the credential details. - - [1658142472.351596][2966:2971] CHIP:DMG: }, - [1658142472.351698][2966:2971] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0101 Command=0x0000_0023 [1658142472.351773][2966:2971] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0101 Command 0x0000_0023 [1658142472.351853][2966:2971] CHIP:TOO: SetCredentialResponse: { [1658142472.351910][2966:2971] CHIP:TOO: status: 0 @@ -650,7 +640,7 @@ tests: [1658142472.352012][2966:2971] CHIP:TOO: } disabled: true - - label: "Step 5f: TH reads the LockUserChange event from DUT" + - label: "Step 5g: TH reads the LockUserChange event from DUT" PICS: DRLK.S.E04 verification: | ./chip-tool doorlock read-event lock-user-change 1 1 @@ -690,34 +680,9 @@ tests: disabled: true - label: - "Step 5g: TH sends Clear User Command to DUT for user created in Step - 5a" - PICS: DRLK.S.C1d.Rsp - verification: | - ./chip-tool doorlock clear-user 2 1 1 --timedInteractionTimeoutMs 1000 - - Via the TH (chip-tool), verify the SUCCESS response for clearing the users details. - - [1658142762.492854][2993:2998] CHIP:DMG: - [1658142762.492888][2993:2998] CHIP:DMG: StatusIB = - [1658142762.492920][2993:2998] CHIP:DMG: { - [1658142762.492957][2993:2998] CHIP:DMG: status = 0x00 (SUCCESS), - [1658142762.492994][2993:2998] CHIP:DMG: }, - [1658142762.493026][2993:2998] CHIP:DMG: - [1658142762.493060][2993:2998] CHIP:DMG: }, - [1658142762.493097][2993:2998] CHIP:DMG: - [1658142762.493125][2993:2998] CHIP:DMG: }, - [1658142762.493158][2993:2998] CHIP:DMG: - [1658142762.493182][2993:2998] CHIP:DMG: ], - [1658142762.493211][2993:2998] CHIP:DMG: - [1658142762.493235][2993:2998] CHIP:DMG: InteractionModelRevision = 1 - [1658142762.493258][2993:2998] CHIP:DMG: }, - disabled: true - - - label: - "Step 6a: TH sends Clear Credential Command to DUT for Credential - created in Preconditions" - PICS: DRLK.S.C26.Rsp + "Step 6a: TH sends ClearCredential Command to DUT with the following + fields: a) CredentialType as 1, b) CredentialIndex as 1" + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C26.Rsp verification: | ./chip-tool doorlock clear-credential '{ "credentialType" : 1 , "credentialIndex" : 1 }' 1 1 --timedInteractionTimeoutMs 1000 @@ -727,40 +692,16 @@ tests: [1658142697.890058][2985:2990] CHIP:DMG: { [1658142697.890103][2985:2990] CHIP:DMG: status = 0x00 (SUCCESS), [1658142697.890147][2985:2990] CHIP:DMG: }, - [1658142697.890190][2985:2990] CHIP:DMG: - [1658142697.890229][2985:2990] CHIP:DMG: }, - [1658142697.890275][2985:2990] CHIP:DMG: - [1658142697.890312][2985:2990] CHIP:DMG: }, - [1658142697.890353][2985:2990] CHIP:DMG: - [1658142697.890385][2985:2990] CHIP:DMG: ], - [1658142697.890423][2985:2990] CHIP:DMG: - [1658142697.890455][2985:2990] CHIP:DMG: InteractionModelRevision = 1 - [1658142697.890486][2985:2990] CHIP:DMG: }, - [1658142697.890563][2985:2990] CHIP:DMG: Received Command Response Status for Endpoint=1 Cluster=0x0000_0101 Command=0x0000_0026 Status=0x0 - [1658142697.890616][2985:2990] CHIP:DMG: ICR moving to [AwaitingDe] disabled: true - label: "Step 6b: TH sends Clear User Command to DUT for user created in Preconditions" - PICS: DRLK.S.C1d.Rsp + PICS: DRLK.S.F08 && DRLK.S.C1d.Rsp verification: | - ./chip-tool doorlock clear-user 1 1 1 --timedInteractionTimeoutMs 1000 + ./chip-tool doorlock clear-user 0xFFFE 1 1 --timedInteractionTimeoutMs 1000 Via the TH (chip-tool), verify the SUCCESS response for clearing the users details. - [1658142762.492854][2993:2998] CHIP:DMG: - [1658142762.492888][2993:2998] CHIP:DMG: StatusIB = - [1658142762.492920][2993:2998] CHIP:DMG: { - [1658142762.492957][2993:2998] CHIP:DMG: status = 0x00 (SUCCESS), - [1658142762.492994][2993:2998] CHIP:DMG: }, - [1658142762.493026][2993:2998] CHIP:DMG: - [1658142762.493060][2993:2998] CHIP:DMG: }, - [1658142762.493097][2993:2998] CHIP:DMG: - [1658142762.493125][2993:2998] CHIP:DMG: }, - [1658142762.493158][2993:2998] CHIP:DMG: - [1658142762.493182][2993:2998] CHIP:DMG: ], - [1658142762.493211][2993:2998] CHIP:DMG: - [1658142762.493235][2993:2998] CHIP:DMG: InteractionModelRevision = 1 - [1658142762.493258][2993:2998] CHIP:DMG: }, + [1657631472.017012][2661:2666] CHIP:DMG: status = 0x00 (SUCCESS), disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_11.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_11.yaml index de3a170c4f29fb..d159e70858ceb5 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_11.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_11.yaml @@ -26,7 +26,7 @@ config: nodeId: 0x12344321 cluster: "Door Lock" endpoint: 1 - PINCredentialData: + CredentialData: type: octet_string defaultValue: "123456" RFIDCredentialData: @@ -45,55 +45,6 @@ tests: - name: "nodeId" value: nodeId - - label: "Precondition: Create new user with default parameters" - command: "SetUser" - timedInteractionTimeoutMs: 10000 - arguments: - values: - - name: "OperationType" - value: 0 - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - - label: "Precondition: Read the user back and verify its fields" - command: "GetUser" - arguments: - values: - - name: "UserIndex" - value: 1 - response: - values: - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - name: "Credentials" - value: [] - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextUserIndex" - value: null - - label: "Step 1a: TH reads NumberOfTotalUsersSupported and saves for future use." @@ -141,7 +92,28 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 2a: TH sends Set Credential Command to DUT with type PIN" + - label: "Step 2a: TH sends SetUser Command to DUT" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp + command: "SetUser" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "OperationType" + value: 0 + - name: "UserIndex" + value: 1 + - name: "UserName" + value: "xxx" + - name: "UserUniqueID" + value: 6452 + - name: "UserStatus" + value: 1 + - name: "UserType" + value: 0 + - name: "CredentialRule" + value: 0 + + - label: "Step 2b: TH sends Set Credential Command to DUT with type PIN" PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx command: "SetCredential" timedInteractionTimeoutMs: 10000 @@ -152,7 +124,7 @@ tests: - name: "Credential" value: { CredentialType: 1, CredentialIndex: 1 } - name: "CredentialData" - value: PINCredentialData + value: CredentialData - name: "UserIndex" value: 1 - name: "UserStatus" diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_6.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_6.yaml index ba265fa99075de..7d3466aec33c91 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_6.yaml @@ -107,40 +107,38 @@ tests: error: INVALID_COMMAND - label: - "Step 5: TH sends Get Holiday Schedule Command to DUT with Invalid - HolidayIndex as 15" + "Step 5: TH sends GetHolidaySchedule Command to DUT with Invalid + HolidayIndex > number_holiday_sch_supported ." PICS: DRLK.S.F0b && DRLK.S.C12.Rsp && DRLK.S.C12.Tx command: "GetHolidaySchedule" arguments: values: - name: "HolidayIndex" - value: 15 + value: NumberOfHolidaySchedulesSupportedValue + 1 response: values: - - name: "HolidayIndex" - value: 15 - name: "Status" - value: 133 + value: 0x85 - label: - "Step 6: TH sends Get Holiday Schedule Command to DUT with the - HolidayIndex as 10 (value is in the the range of step 1 but Holiday - Schedule entry not available)" + "Step 6: TH sends GetHolidaySchedule Command to DUT with the + HolidayIndex as any value that is different from 1 and value <= + number_holiday_sch_supported" PICS: DRLK.S.F0b && DRLK.S.C12.Rsp && DRLK.S.C12.Tx command: "GetHolidaySchedule" arguments: values: - name: "HolidayIndex" - value: 10 + value: NumberOfHolidaySchedulesSupportedValue response: values: - name: "HolidayIndex" - value: 10 + value: NumberOfHolidaySchedulesSupportedValue - name: "Status" - value: 139 + value: 0x8B - label: - "Step 7: TH send Clear Holiday Schedule Command to DUT with + "Step 7a: TH send Clear Holiday Schedule Command to DUT with HolidayIndex as 1" PICS: DRLK.S.F0b && DRLK.S.C13.Rsp command: "ClearHolidaySchedule" @@ -149,6 +147,18 @@ tests: - name: "HolidayIndex" value: 1 + - label: + "Step 7b: TH send Clear Holiday Schedule Command to DUT with + HolidayIndex as 0" + PICS: DRLK.S.F0b && DRLK.S.C13.Rsp + command: "ClearHolidaySchedule" + arguments: + values: + - name: "HolidayIndex" + value: 0 + response: + error: INVALID_COMMAND + - label: "Step 8: TH sends Get Holiday Schedule Command to DUT with HolidayIndex as 1" diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_7.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_7.yaml index 3cd01cdde0ecf8..892c4ae86ac1c3 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_7.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_7.yaml @@ -35,55 +35,6 @@ tests: - name: "nodeId" value: nodeId - - label: "Precondition: Create new user" - command: "SetUser" - timedInteractionTimeoutMs: 10000 - arguments: - values: - - name: "OperationType" - value: 0 - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - - label: "Precondition: Read the user back and verify its fields" - command: "GetUser" - arguments: - values: - - name: "UserIndex" - value: 1 - response: - values: - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - name: "Credentials" - value: [] - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextUserIndex" - value: null - - label: "Step 1: TH reads NumberOfYearDay SchedulesSupportedPerUser attribute and saves for future use" @@ -109,9 +60,34 @@ tests: maxValue: 65534 - label: - "Step 3: TH sends Set Year Day Schedule Command to DUT with the - following values: a)YearDayIndex as 1 b)UserIndex as 1 - c)LocalStartTime as 960 Seconds d)LocalEndTime as 1980 Seconds" + "Step 3a: TH sends SetUser Command to DUT with the following values: + a)OperationType as 0, b)UserIndex as 1, c)UserName as xxx, + c)UserUniqueID as 6452, d)UserStatus as 1, e)UserType as 0, + f)CredentialRule as 0" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp + command: "SetUser" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "OperationType" + value: 0 + - name: "UserIndex" + value: 1 + - name: "UserName" + value: "xxx" + - name: "UserUniqueID" + value: 6452 + - name: "UserStatus" + value: 1 + - name: "UserType" + value: 0 + - name: "CredentialRule" + value: 0 + + - label: + "Step 3b: TH sends SetYearDaySchedule Command to DUT with the + following values: a)YearDayIndex as 1, b)UserIndex as 1, + c)LocalStartTime as 960 Seconds, d)LocalEndTime as 1980 Seconds" PICS: DRLK.S.F0a && DRLK.S.C0e.Rsp command: "SetYearDaySchedule" arguments: @@ -196,9 +172,8 @@ tests: constraints: hasValue: false - - label: - "Step 7a: Create a new user with UserIndex as 5 then TH sends Get Year - Day Schedule Command to DUT with" + - label: "Step 7a: Create a new user with UserIndex as 5" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp command: "SetUser" timedInteractionTimeoutMs: 10000 arguments: @@ -219,8 +194,9 @@ tests: value: 0 - label: - "Step 7b: YearDayIndex as 10 (value is in the the range of step 1 but - YearDay Schedule entry not available) : UserIndex as 5" + "Step 7b: TH sends Get Year Day Schedule Command to DUT with + YearDayIndex as 10 (value is in the the range of step 1 but YearDay + Schedule entry not available) : UserIndex as 5" PICS: DRLK.S.F0a && DRLK.S.C0f.Rsp && DRLK.S.C0f.Tx command: "GetYearDaySchedule" arguments: @@ -367,28 +343,11 @@ tests: response: error: INVALID_COMMAND - - label: "Clear a year day schedule for the first user" - PICS: DRLK.S.F0a && DRLK.S.C10.Rsp - command: "ClearYearDaySchedule" - arguments: - values: - - name: "YearDayIndex" - value: 1 - - name: "UserIndex" - value: 1 - - - label: "Cleanup the created user with UserIndex 1" - command: "ClearUser" + - label: "Step 14:TH sends ClearUser Command to DUT with the UserIndex as 1" + PICS: DRLK.S.F08 && DRLK.S.C1d.Rsp timedInteractionTimeoutMs: 10000 - arguments: - values: - - name: "UserIndex" - value: 1 - - - label: "Cleanup the created user with UserIndex 5" command: "ClearUser" - timedInteractionTimeoutMs: 10000 arguments: values: - name: "UserIndex" - value: 5 + value: 0xFFFE diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_8.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_8.yaml index 0204f30727a028..baece9a4d0aa95 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_8.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_8.yaml @@ -206,6 +206,16 @@ tests: - name: "NextUserIndex" value: null + - label: "Step 6c: TH sends Get User Command to DUT with UserIndex as 0" + PICS: DRLK.S.C1a.Rsp && DRLK.S.C1b.Rsp && DRLK.S.C1c.Tx + command: "GetUser" + arguments: + values: + - name: "UserIndex" + value: 0 + response: + error: INVALID_COMMAND + - label: "Step 7: TH sends Set User Command to DUT with the following values: OperationType as 2 UserIndex as 2 UserName as NULL UserUniqueID as diff --git a/src/app/tests/suites/certification/Test_TC_IDM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_IDM_3_2.yaml index 09982f6851b245..d9b37498847ce7 100644 --- a/src/app/tests/suites/certification/Test_TC_IDM_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_IDM_3_2.yaml @@ -24,6 +24,13 @@ config: endpoint: 0 tests: + - label: "Note" + verification: | + 1. The Cluster and Commands should be based on the cluster implementation on the DUT. + 2. The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. + 3. Test Steps 2, 13, 20, 21, 22 and 23 cannot be executed with V1.0 SDK + disabled: true + - label: "Step 1: TH sends the WriteRequestMessage to the DUT to write one attribute on a given cluster and endpoint. On receipt of this message, @@ -93,7 +100,6 @@ tests: ./chip-tool basicinformation write local-config-disabled 1 1 0 - On TH(chip-tool), verify that DUT sends a WriteResponseMessage with the status set to Success for the data sent in the above command and verify by sending a ReadRequestMessage to read the value that was modified. [1686227392.013866][93552:93554] CHIP:DMG: WriteClient moving to [ResponseRe] [1686227392.013876][93552:93554] CHIP:DMG: WriteResponseMessage = @@ -144,7 +150,6 @@ tests: verification: | The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. - ./chip-tool basicinformation write node-label new 1 0 On TH(chip-tool), verify that DUT sends a WriteResponseMessage with the status set to Success for the data sent in the above command and veriffy by sending a ReadRequestMessage to read the value that was modified. @@ -195,7 +200,6 @@ tests: verification: | The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. - ./chip-tool any write-by-id 0x0008 0x0010 1 1 1 On TH(chip-tool), verify that DUT sends a WriteResponseMessage with the status set to Success for the data sent in the above command and verify by sending a ReadRequestMessage to read the value that was modified @@ -252,7 +256,7 @@ tests: verification: | DUT implementation required to verify write an attribute of data type signed integer. - If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "\Not Applicable\" + If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "Not Applicable" disabled: true - label: @@ -262,7 +266,7 @@ tests: verification: | DUT implementation required to verify write an attribute of data type float - If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "\Not Applicable\" + If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "Not Applicable" disabled: true - label: @@ -272,7 +276,7 @@ tests: verification: | DUT implementation required to verify write an attribute of data type Octet String - If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "\Not Applicable\" + If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "Not Applicable" disabled: true - label: @@ -282,7 +286,7 @@ tests: verification: | DUT implementation required to verify write an attribute ofdata type Struct - If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "\Not Applicable\" + If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "Not Applicable" disabled: true - label: @@ -292,7 +296,7 @@ tests: verification: | DUT implementation required to verify write an attribute of data type List - If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "\Not Applicable\" + If the Vendor DUT doesn't implement/supported this attribute, Please mark the test step as "Not Applicable" disabled: true - label: @@ -301,6 +305,7 @@ tests: PICS: MCORE.IDM.S.Attribute_W.DataType_Enum verification: | The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. + ./chip-tool any write-by-id 0x0204 0 1 1 1 On TH(chip-tool), verify that DUT sends a WriteResponseMessage with the status set to Success for the data sent in the above command and verify by sending a ReadRequestMessage to read the value that was modified. @@ -339,9 +344,7 @@ tests: ./chip-tool any read-by-id 0x0204 0 1 1 On TH(chip-tool), verify the attribute value that was modified in above step - [1686227658.643633][93610:93612] CHIP:DMG: SuppressResponse = true, - [1686227658.643643][93610:93612] CHIP:DMG: InteractionModelRevision = 1 - [1686227658.643651][93610:93612] CHIP:DMG: } + [1686227658.643729][93610:93612] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0204 Attribute 0x0000_0000 DataVersion: 1939013916 [1686227658.643765][93610:93612] CHIP:TOO: TemperatureDisplayMode: 1 [1686227658.643826][93610:93612] CHIP:EM: <<< [E:7325i S:64158 M:55416058 (Ack:52160854)] (S) Msg TX to 1:0000000000000001 [58B9] --- Type 0000:10 (SecureChannel:StandaloneAck) @@ -392,14 +395,10 @@ tests: [1686227690.827552][93615:93617] CHIP:EM: Flushed pending ack for MessageCounter:75613172 on exchange 7166i - ./chip-tool colorcontrol read-by-id 0x000f 1 1 On TH(chip-tool), verify the attribute value that was modified in above step - [1686227710.429709][93622:93624] CHIP:DMG: SuppressResponse = true, - [1686227710.429715][93622:93624] CHIP:DMG: InteractionModelRevision = 1 - [1686227710.429720][93622:93624] CHIP:DMG: } [1686227710.429791][93622:93624] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0300 Attribute 0x0000_000F DataVersion: 861636757 [1686227710.429832][93622:93624] CHIP:TOO: Options: 1 [1686227710.429882][93622:93624] CHIP:EM: <<< [E:4989i S:43440 M:30144210 (Ack:113240090)] (S) Msg TX to 1:0000000000000001 [58B9] --- Type 0000:10 (SecureChannel:StandaloneAck) @@ -468,7 +467,6 @@ tests: On TH(chip-tool), Verify that the DUT sends the status code UNSUPPORTED_CLUSTER for the data sent in the above command - [1686229393.093998][94065:94067] CHIP:EM: Rxd Ack; Removing MessageCounter:56487501 from Retrans Table on exchange 60736i [1686229393.094012][94065:94067] CHIP:DMG: WriteClient moving to [ResponseRe] [1686229393.094033][94065:94067] CHIP:DMG: WriteResponseMessage = @@ -591,11 +589,11 @@ tests: verification: | The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. - To Setup the TH such that it should not have the privilege for the cluster in the path. , 1st we need to send below mentioned ACL command Here by sending below mentioned ACL command giving only access for ACL cluster(31), So except identify cluster command if try to send any other command will get status as unsupported access. ./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects":[112233], "targets": [{ "cluster":31, "endpoint":0, "deviceType":null }]}]' 1 0 + On TH(chip-tool), Verify that the DUT sends the status code SUCCESS for the data sent in the above command [1686228784.940429][93932:93934] CHIP:EM: Rxd Ack; Removing MessageCounter:76693936 from Retrans Table on exchange 64135i @@ -696,6 +694,7 @@ tests: The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. ./chip-tool levelcontrol write on-level 2 1 1 + On TH(chip-tool), verify that DUT sends a Write Response message with a success [1686229097.486513][93998:94000] CHIP:DMG: WriteClient moving to [ResponseRe] [1686229097.486533][93998:94000] CHIP:DMG: WriteResponseMessage = @@ -731,8 +730,9 @@ tests: ./chip-tool levelcontrol read on-level 1 1 + On TH(chip-tool), verify the attribute value that was modified in above step. - [1686229128.655083][94004:94006] CHIP:DMG: } + [1686229128.655203][94004:94006] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0008 Attribute 0x0000_0011 DataVersion: 2737039619 [1686229128.655240][94004:94006] CHIP:TOO: OnLevel: 2 [1686229128.655340][94004:94006] CHIP:EM: <<< [E:43327i S:11132 M:58615041 (Ack:232232518)] (S) Msg TX to 1:0000000000000001 [58B9] --- Type 0000:10 (SecureChannel:StandaloneAck) @@ -741,7 +741,9 @@ tests: ./chip-tool levelcontrol write on-level 3 1 1 + Verify on TH(chip-tool) receives WriteResponseMessage with the status set to Success for the data sent in the above command and verify by sending a ReadRequestMessage to read the value that was modified. + [1686229150.157900][94008:94010] CHIP:DMG: WriteClient moving to [ResponseRe] [1686229150.157919][94008:94010] CHIP:DMG: WriteResponseMessage = [1686229150.157927][94008:94010] CHIP:DMG: { @@ -776,6 +778,7 @@ tests: ./chip-tool levelcontrol read on-level 1 1 On TH(chip-tool), verify the attribute value that was modified in above step + [1686229175.161437][94014:94016] CHIP:DMG: InteractionModelRevision = 1 [1686229175.161442][94014:94016] CHIP:DMG: } [1686229175.161512][94014:94016] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0008 Attribute 0x0000_0011 DataVersion: 2737039620 @@ -788,6 +791,7 @@ tests: ./chip-tool levelcontrol write on-level 1 1 1 Verify on TH(chip-tool) receives WriteResponseMessage with the status set to Success for the data sent in the above command and verify by sending a ReadRequestMessage to read the value that was modified + [1686229199.082595][94020:94022] CHIP:EM: Rxd Ack; Removing MessageCounter:90418515 from Retrans Table on exchange 55893i [1686229199.082606][94020:94022] CHIP:DMG: WriteClient moving to [ResponseRe] [1686229199.082625][94020:94022] CHIP:DMG: WriteResponseMessage = @@ -823,6 +827,7 @@ tests: ./chip-tool levelcontrol read on-level 1 1 On TH(chip-tool), verify the attribute value that was modified in above step + [1686229224.244504][94026:94028] CHIP:DMG: } [1686229224.244574][94026:94028] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0008 Attribute 0x0000_0011 DataVersion: 2737039621 [1686229224.244614][94026:94028] CHIP:TOO: OnLevel: 1 @@ -893,6 +898,7 @@ tests: ./chip-tool levelcontrol write on-level 3 1 1 --data-version 0xc4c9d7ae On TH(chip-tool), verify that DUT sends a Write Response message with a success + [1686229590.858793][94124:94126] CHIP:DMG: WriteClient moving to [ResponseRe] [1686229590.858813][94124:94126] CHIP:DMG: WriteResponseMessage = [1686229590.858821][94124:94126] CHIP:DMG: { @@ -926,6 +932,7 @@ tests: ./chip-tool levelcontrol read on-level 1 1 On TH(chip-tool), verify that TH receives the WriteResponseMessage with the status set to Success for the data sent in the above command and veriy by sending a ReadRequestMessage to read the value that was modified. + [1686229613.307472][94130:94132] CHIP:DMG: } [1686229613.307596][94130:94132] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0008 Attribute 0x0000_0011 DataVersion: 2737039622 [1686229613.307632][94130:94132] CHIP:TOO: OnLevel: 3 @@ -945,8 +952,6 @@ tests: verification: | The cluster used in the below command is an example, User can use any supported chip cluster/attribute/command. - - ./chip-tool levelcontrol read on-level 1 1 On TH(chip-tool), Verify that DUT is responds with attribute value @@ -962,7 +967,9 @@ tests: ./chip-tool levelcontrol write on-level 4 1 1 + On TH(chip-tool), DUT send a Write Response message with status code as success + [1686229675.214378][94147:94149] CHIP:DMG: WriteResponseMessage = [1686229675.214386][94147:94149] CHIP:DMG: { [1686229675.214393][94147:94149] CHIP:DMG: AttributeStatusIBs = diff --git a/src/app/tests/suites/certification/Test_TC_IDM_5_2.yaml b/src/app/tests/suites/certification/Test_TC_IDM_5_2.yaml index 534154cb6d7e3c..3a7e8f9360df56 100644 --- a/src/app/tests/suites/certification/Test_TC_IDM_5_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_IDM_5_2.yaml @@ -80,7 +80,9 @@ tests: By sending a ReadRequest that the Write action was performed correctly. + ./chip-tool levelcontrol read on-level 1 1 + [1655799013.466144][7075:7080] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0008 Attribute 0x0000_0011 DataVersion: 737039642 [1655799013.466237][7075:7080] CHIP:TOO: on level: 1 [1655799013.466336][7075:7080] CHIP:EM: Sending Standalone Ack for MessageCounter:202402347 on exchange 58038i @@ -92,21 +94,27 @@ tests: status response message to be received. Wait for 5 seconds(Timer has expired) and then send the Invoke Request Message to the DUT." verification: | - ./chip-tool onoff on 1 1 --repeat-delay-ms 5000 --timedInteractionTimeoutMs 200 - - If the device being certified is Matter release 1.4 or later, verify DUT sends back a Status response with the TIMEOUT status code. - If the device being certified is Matter release 1.3 or earlier, verify the DUT sends back a Status response with either TIMEOUT or UNSUPPORTED_ACCESS status code. - - [1718641649.158222][1587554:1587556] CHIP:EM: Rxd Ack; Removing MessageCounter:70404585 from Retrans Table on exchange 44026i - [1718641649.158241][1587554:1587556] CHIP:DMG: ICR moving to [ResponseRe] - [1718641649.158261][1587554:1587556] CHIP:DMG: StatusResponseMessage = - [1718641649.158276][1587554:1587556] CHIP:DMG: { - [1718641649.158290][1587554:1587556] CHIP:DMG: Status = 0x94 (TIMEOUT), - [1718641649.158304][1587554:1587556] CHIP:DMG: InteractionModelRevision = 11 - [1718641649.158318][1587554:1587556] CHIP:DMG: } - [1718641649.158332][1587554:1587556] CHIP:IM: Received status response, status is 0x94 (TIMEOUT) - [1718641649.158355][1587554:1587556] CHIP:TOO: Error: IM Error 0x00000594: General error: 0x94 (TIMEOUT) - + On TH(chip-tool), Verify the DUT's response based on Matter release versions: + + For Matter release 1.4 or later, verify that the DUT responds with a status of TIMEOUT (0x94). + For Matter release 1.3 or earlier, verify that the DUT sends back a Status response with either TIMEOUT (0x94) or UNSUPPORTED_ACCESS (0x7e). + + ./chip-tool onoff on 1 1 --repeat-delay-ms 1000 --timedInteractionTimeoutMs 500 + + [1720440076.857] [11806:11808] [EM] Found matching exchange: 17395i, Delegate: 0xffff7c008198 + [1720440076.857] [11806:11808] [EM] CHIP MessageCounter:107413542 not in RetransTable on exchange 17395i + [1720440076.858] [11806:11808] [EM] >>> [E:17395i S:706 M:204574784 (Ack:107413543)] (S) Msg RX from 1:0000000000000001 [67EF] --- Type 0001:01 (IM:StatusResponse) + [1720440076.858] [11806:11808] [EM] Found matching exchange: 17395i, Delegate: 0xffff7c008198 + [1720440076.858] [11806:11808] [EM] Rxd Ack; Removing MessageCounter:107413543 from Retrans Table on exchange 17395i + [1720440076.858] [11806:11808] [DMG] ICR moving to [ResponseRe] + [1720440076.858] [11806:11808] [DMG] StatusResponseMessage = + [1720440076.858] [11806:11808] [DMG] { + [1720440076.858] [11806:11808] [DMG] Status = 0x94 (TIMEOUT), + [1720440076.858] [11806:11808] [DMG] InteractionModelRevision = 11 + [1720440076.858] [11806:11808] [DMG] } + [1720440076.858] [11806:11808] [IM] Received status response, status is 0x94 (TIMEOUT) + [1720440076.858] [11806:11808] [TOO] Error: IM Error 0x00000594: General error: 0x94 (TIMEOUT) + [1720440076.858] [11806:11808] [EM] <<< [E:17395i S:706 M:107413546 (Ack:204574784)] (S) Msg TX to 1:0000000000000001 [67EF] [UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:5540] --- Type 0001:01 (IM:StatusResponse) disabled: true - label: @@ -115,18 +123,26 @@ tests: status response message to be received. Wait for 5 seconds(Timer has expired) and then send the Write Request Message to the DUT." verification: | - ./chip-tool modeselect write on-mode 0 1 1 --repeat-delay-ms 1000 --timedInteractionTimeoutMs 500 + On TH(chip-tool), Verify the DUT's response based on Matter release versions: - If the device being certified is Matter release 1.4 or later, verify DUT sends back a Status response with the TIMEOUT status code. - If the device being certified is Matter release 1.3 or earlier, verify the DUT sends back a Status response with either TIMEOUT or UNSUPPORTED_ACCESS status code. + For Matter release 1.4 or later, verify that the DUT responds with a status of TIMEOUT (0x94). + For Matter release 1.3 or earlier, verify that the DUT sends back a Status response with either TIMEOUT (0x94) or UNSUPPORTED_ACCESS (0x7e). - [1720104134.620521][3325282:3325284] CHIP:DMG: WriteClient moving to [ResponseRe] - [1720104134.620540][3325282:3325284] CHIP:DMG: StatusResponseMessage = - [1720104134.620555][3325282:3325284] CHIP:DMG: { - [1720104134.620569][3325282:3325284] CHIP:DMG: Status = 0x94 (TIMEOUT), - [1720104134.620583][3325282:3325284] CHIP:DMG: InteractionModelRevision = 11 - [1720104134.620596][3325282:3325284] CHIP:DMG: } - [1720104134.620611][3325282:3325284] CHIP:IM: Received status response, status is 0x94 (TIMEOUT) - [1720104134.620689][3325282:3325284] CHIP:TOO: Error: IM Error 0x00000594: General error: 0x94 (TIMEOUT) + ./chip-tool modeselect write on-mode 0 1 1 --repeat-delay-ms 1000 --timedInteractionTimeoutMs 500 + On TH(chip-tool), Verify we are getting status response and UNSUPPORTED_ACCESS from DUT to TH for above command + + + [1720440084.666] [11810:11812] [EM] Found matching exchange: 22607i, Delegate: 0xffff9000a040 + [1720440084.666] [11810:11812] [EM] Rxd Ack; Removing MessageCounter:200551619 from Retrans Table on exchange 22607i + [1720440084.667] [11810:11812] [DMG] WriteClient moving to [ResponseRe] + [1720440084.667] [11810:11812] [DMG] StatusResponseMessage = + [1720440084.667] [11810:11812] [DMG] { + [1720440084.667] [11810:11812] [DMG] Status = 0x94 (TIMEOUT), + [1720440084.667] [11810:11812] [DMG] InteractionModelRevision = 11 + [1720440084.667] [11810:11812] [DMG] } + [1720440084.667] [11810:11812] [IM] Received status response, status is 0x94 (TIMEOUT) + [1720440084.667] [11810:11812] [TOO] Error: IM Error 0x00000594: General error: 0x94 (TIMEOUT) + [1720440084.667] [11810:11812] [EM] <<< [E:22607i S:23365 M:200551622 (Ack:3244934)] (S) Msg TX to 1:0000000000000001 [67EF] [UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:5540] --- Type 0001:01 (IM:StatusResponse) + [1720440084.668] [11810:11812] [DMG] WriteClient moving to [AwaitingDe] disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_IDM_6_1.yaml b/src/app/tests/suites/certification/Test_TC_IDM_6_1.yaml index 31339d68e30856..b9ade1e9e42e05 100644 --- a/src/app/tests/suites/certification/Test_TC_IDM_6_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_IDM_6_1.yaml @@ -523,7 +523,6 @@ tests: verification: | ./chip-tool any read-event-by-id 0xFFFFFFFF 0xFFFFFFFF 1 0xFFFF - On TH(chip-tool) verify that the DUT sends Report Data Message with EventReports [1655986008.400642][4813:4818] CHIP:DMG: } @@ -609,7 +608,7 @@ tests: large event data. For every chunked data message received, DUT sends a status response." verification: | - Try to verify this step in doorlock app, below mentioned wildcard command to read-event from TH to DUT. + Try to verify this step in doorlock app, below mentioned wildcard command to read-event from TH to DUT.(Log may vary based on the reference app) ./chip-tool any read-event-by-id 0xFFFFFFFF 0xFFFFFFFF 1 0xFFFF The message flow can expect as mentioned below diff --git a/src/app/tests/suites/certification/Test_TC_LVL_8_1.yaml b/src/app/tests/suites/certification/Test_TC_LVL_8_1.yaml new file mode 100644 index 00000000000000..20fad8de4c7dfc --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_LVL_8_1.yaml @@ -0,0 +1,361 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default + +name: 32.1.9 [TC-LVL-8.1] Verification of commands (DUT as Client)" + +PICS: + - LVL.C + +config: + nodeId: 0x12344321 + cluster: "Basic Information" + endpoint: 0 + +tests: + - label: + "Step 1: TH prompts the operator to make the DUT send one or more + supported commands from the Level Control cluster" + verification: | + The product maker needs to provide instructions on how to trigger the command on the DUT. For comparison, the DUT behavior for this test step can be simulated using chip-tool (when the DUT is a commissioner/Client). + + The DUT should transmit correctly formed commands in any order, with application achievable values that are within the limits allowed by the specification and consistent with the attribute values reported by the TH. Verify this using the TH log of these messages. + + Please send the below command and validate the conditions mentioned above: + + ./chip-tool levelcontrol move-to-level 125 10 0 0 1 1 + on TH (all-clusters-app) log. Verify the move-to-level command is received successfully. + + + [1721131579.026] [3188:3188] [DL] HandlePlatformSpecificBLEEvent 32792 + [1721131579.028] [3188:3188] [EM] >>> [E:39794r S:12010 M:201578598] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131579.028] [3188:3188] [EM] Handling via exchange: 39794r, Delegate: 0xaaaac95ff3b0 + [1721131579.028] [3188:3188] [DMG] InvokeRequestMessage = + [1721131579.028] [3188:3188] [DMG] { + [1721131579.029] [3188:3188] [DMG] suppressResponse = false, + [1721131579.029] [3188:3188] [DMG] timedRequest = false, + [1721131579.029] [3188:3188] [DMG] InvokeRequests = + [1721131579.029] [3188:3188] [DMG] [ + [1721131579.029] [3188:3188] [DMG] CommandDataIB = + [1721131579.029] [3188:3188] [DMG] { + [1721131579.029] [3188:3188] [DMG] CommandPathIB = + [1721131579.029] [3188:3188] [DMG] { + [1721131579.029] [3188:3188] [DMG] EndpointId = 0x1, + [1721131579.029] [3188:3188] [DMG] ClusterId = 0x8, + [1721131579.029] [3188:3188] [DMG] CommandId = 0x0, + [1721131579.029] [3188:3188] [DMG] }, + [1721131579.029] [3188:3188] [DMG] + [1721131579.029] [3188:3188] [DMG] CommandFields = + [1721131579.029] [3188:3188] [DMG] { + [1721131579.029] [3188:3188] [DMG] 0x0 = 125 (unsigned), + [1721131579.029] [3188:3188] [DMG] 0x1 = 10 (unsigned), + [1721131579.029] [3188:3188] [DMG] 0x2 = 0 (unsigned), + [1721131579.029] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131579.029] [3188:3188] [DMG] }, + [1721131579.029] [3188:3188] [DMG] }, + [1721131579.029] [3188:3188] [DMG] + [1721131579.029] [3188:3188] [DMG] ], + [1721131579.029] [3188:3188] [DMG] + [1721131579.029] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131579.029] [3188:3188] [DMG] }, + [1721131579.029] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131579.029] [3188:3188] [DMG] AccessControl: allowed + [1721131579.030] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0000 + [1721131579.030] [3188:3188] [ZCL] RX level-control: MOVE_TO_LEVEL 7d a 0 0 + [1721131579.030] [3188:3188] [DMG] Command handler moving to [NewRespons] + + + + ./chip-tool levelcontrol move 1 5 0 0 1 1 + on TH (all-clusters-app) log. Verify the move command is received successfully. + + + [1721131607.050] [3188:3188] [EM] Handling via exchange: 48182r, Delegate: 0xaaaac95ff3b0 + [1721131607.050] [3188:3188] [DMG] InvokeRequestMessage = + [1721131607.050] [3188:3188] [DMG] { + [1721131607.050] [3188:3188] [DMG] suppressResponse = false, + [1721131607.050] [3188:3188] [DMG] timedRequest = false, + [1721131607.050] [3188:3188] [DMG] InvokeRequests = + [1721131607.050] [3188:3188] [DMG] [ + [1721131607.050] [3188:3188] [DMG] CommandDataIB = + [1721131607.050] [3188:3188] [DMG] { + [1721131607.050] [3188:3188] [DMG] CommandPathIB = + [1721131607.050] [3188:3188] [DMG] { + [1721131607.050] [3188:3188] [DMG] EndpointId = 0x1, + [1721131607.050] [3188:3188] [DMG] ClusterId = 0x8, + [1721131607.050] [3188:3188] [DMG] CommandId = 0x1, + [1721131607.050] [3188:3188] [DMG] }, + [1721131607.050] [3188:3188] [DMG] + [1721131607.050] [3188:3188] [DMG] CommandFields = + [1721131607.050] [3188:3188] [DMG] { + [1721131607.050] [3188:3188] [DMG] 0x0 = 1 (unsigned), + [1721131607.050] [3188:3188] [DMG] 0x1 = 5 (unsigned), + [1721131607.050] [3188:3188] [DMG] 0x2 = 0 (unsigned), + [1721131607.050] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131607.050] [3188:3188] [DMG] }, + [1721131607.050] [3188:3188] [DMG] }, + [1721131607.050] [3188:3188] [DMG] + [1721131607.050] [3188:3188] [DMG] ], + [1721131607.050] [3188:3188] [DMG] + [1721131607.050] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131607.050] [3188:3188] [DMG] }, + [1721131607.051] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131607.051] [3188:3188] [DMG] AccessControl: allowed + [1721131607.051] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0001 + + + + ./chip-tool levelcontrol step 1 10 0 0 0 1 1 + on TH (all-clusters-app) log. Verify the step command is received successfully. + + [1721131622.700] [3188:3188] [EM] Handling via exchange: 33066r, Delegate: 0xaaaac95ff3b0 + [1721131622.700] [3188:3188] [DMG] InvokeRequestMessage = + [1721131622.700] [3188:3188] [DMG] { + [1721131622.700] [3188:3188] [DMG] suppressResponse = false, + [1721131622.700] [3188:3188] [DMG] timedRequest = false, + [1721131622.700] [3188:3188] [DMG] InvokeRequests = + [1721131622.700] [3188:3188] [DMG] [ + [1721131622.700] [3188:3188] [DMG] CommandDataIB = + [1721131622.700] [3188:3188] [DMG] { + [1721131622.700] [3188:3188] [DMG] CommandPathIB = + [1721131622.700] [3188:3188] [DMG] { + [1721131622.700] [3188:3188] [DMG] EndpointId = 0x1, + [1721131622.700] [3188:3188] [DMG] ClusterId = 0x8, + [1721131622.700] [3188:3188] [DMG] CommandId = 0x2, + [1721131622.700] [3188:3188] [DMG] }, + [1721131622.700] [3188:3188] [DMG] + [1721131622.701] [3188:3188] [DMG] CommandFields = + [1721131622.701] [3188:3188] [DMG] { + [1721131622.701] [3188:3188] [DMG] 0x0 = 1 (unsigned), + [1721131622.701] [3188:3188] [DMG] 0x1 = 10 (unsigned), + [1721131622.701] [3188:3188] [DMG] 0x2 = 0 (unsigned), + [1721131622.701] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131622.701] [3188:3188] [DMG] 0x4 = 0 (unsigned), + [1721131622.701] [3188:3188] [DMG] }, + [1721131622.701] [3188:3188] [DMG] }, + [1721131622.701] [3188:3188] [DMG] + [1721131622.701] [3188:3188] [DMG] ], + [1721131622.701] [3188:3188] [DMG] + [1721131622.701] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131622.701] [3188:3188] [DMG] }, + [1721131622.701] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131622.701] [3188:3188] [DMG] AccessControl: allowed + + + + + ./chip-tool levelcontrol stop 0 0 1 1 + on TH (all-clusters-app) log. Verify the stop command is received successfully. + + [1721131637.910] [3188:3188] [EM] >>> [E:64966r S:12013 M:241263255] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131637.910] [3188:3188] [EM] Handling via exchange: 64966r, Delegate: 0xaaaac95ff3b0 + [1721131637.910] [3188:3188] [DMG] InvokeRequestMessage = + [1721131637.910] [3188:3188] [DMG] { + [1721131637.910] [3188:3188] [DMG] suppressResponse = false, + [1721131637.910] [3188:3188] [DMG] timedRequest = false, + [1721131637.910] [3188:3188] [DMG] InvokeRequests = + [1721131637.910] [3188:3188] [DMG] [ + [1721131637.910] [3188:3188] [DMG] CommandDataIB = + [1721131637.910] [3188:3188] [DMG] { + [1721131637.910] [3188:3188] [DMG] CommandPathIB = + [1721131637.910] [3188:3188] [DMG] { + [1721131637.910] [3188:3188] [DMG] EndpointId = 0x1, + [1721131637.910] [3188:3188] [DMG] ClusterId = 0x8, + [1721131637.910] [3188:3188] [DMG] CommandId = 0x3, + [1721131637.910] [3188:3188] [DMG] }, + [1721131637.910] [3188:3188] [DMG] + [1721131637.910] [3188:3188] [DMG] CommandFields = + [1721131637.910] [3188:3188] [DMG] { + [1721131637.910] [3188:3188] [DMG] 0x0 = 0 (unsigned), + [1721131637.910] [3188:3188] [DMG] 0x1 = 0 (unsigned), + [1721131637.910] [3188:3188] [DMG] }, + [1721131637.910] [3188:3188] [DMG] }, + [1721131637.910] [3188:3188] [DMG] + [1721131637.911] [3188:3188] [DMG] ], + [1721131637.911] [3188:3188] [DMG] + [1721131637.911] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131637.911] [3188:3188] [DMG] }, + [1721131637.911] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131637.911] [3188:3188] [DMG] AccessControl: allowed + [1721131637.911] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0003 + + + + ./chip-tool levelcontrol move-to-level-with-on-off 1 0 0 0 1 1 + on TH (all-clusters-app) log. Verify the move-to-level-with-on-off command is received successfully. + + [1721131651.510] [3188:3188] [EM] >>> [E:42083r S:12014 M:199867058] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131651.510] [3188:3188] [EM] Handling via exchange: 42083r, Delegate: 0xaaaac95ff3b0 + [1721131651.510] [3188:3188] [DMG] InvokeRequestMessage = + [1721131651.510] [3188:3188] [DMG] { + [1721131651.510] [3188:3188] [DMG] suppressResponse = false, + [1721131651.510] [3188:3188] [DMG] timedRequest = false, + [1721131651.510] [3188:3188] [DMG] InvokeRequests = + [1721131651.510] [3188:3188] [DMG] [ + [1721131651.510] [3188:3188] [DMG] CommandDataIB = + [1721131651.510] [3188:3188] [DMG] { + [1721131651.511] [3188:3188] [DMG] CommandPathIB = + [1721131651.511] [3188:3188] [DMG] { + [1721131651.511] [3188:3188] [DMG] EndpointId = 0x1, + [1721131651.511] [3188:3188] [DMG] ClusterId = 0x8, + [1721131651.511] [3188:3188] [DMG] CommandId = 0x4, + [1721131651.511] [3188:3188] [DMG] }, + [1721131651.511] [3188:3188] [DMG] + [1721131651.511] [3188:3188] [DMG] CommandFields = + [1721131651.511] [3188:3188] [DMG] { + [1721131651.511] [3188:3188] [DMG] 0x0 = 1 (unsigned), + [1721131651.511] [3188:3188] [DMG] 0x1 = 0 (unsigned), + [1721131651.511] [3188:3188] [DMG] 0x2 = 0 (unsigned), + [1721131651.511] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131651.511] [3188:3188] [DMG] }, + [1721131651.511] [3188:3188] [DMG] }, + [1721131651.511] [3188:3188] [DMG] + [1721131651.511] [3188:3188] [DMG] ], + [1721131651.511] [3188:3188] [DMG] + [1721131651.511] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131651.511] [3188:3188] [DMG] }, + [1721131651.512] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131651.512] [3188:3188] [DMG] AccessControl: allowed + [1721131651.512] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0004 + + + + + ./chip-tool levelcontrol move-with-on-off 1 5 0 0 1 1 + on TH (all-clusters-app) log. Verify the move-with-on-off command is received successfully. + + + [1721131674.036] [3188:3188] [DL] HandlePlatformSpecificBLEEvent 32792 + [1721131674.039] [3188:3188] [EM] >>> [E:21646r S:12015 M:111324533] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131674.039] [3188:3188] [EM] Handling via exchange: 21646r, Delegate: 0xaaaac95ff3b0 + [1721131674.039] [3188:3188] [DMG] InvokeRequestMessage = + [1721131674.039] [3188:3188] [DMG] { + [1721131674.039] [3188:3188] [DMG] suppressResponse = false, + [1721131674.039] [3188:3188] [DMG] timedRequest = false, + [1721131674.039] [3188:3188] [DMG] InvokeRequests = + [1721131674.039] [3188:3188] [DMG] [ + [1721131674.039] [3188:3188] [DMG] CommandDataIB = + [1721131674.039] [3188:3188] [DMG] { + [1721131674.039] [3188:3188] [DMG] CommandPathIB = + [1721131674.039] [3188:3188] [DMG] { + [1721131674.039] [3188:3188] [DMG] EndpointId = 0x1, + [1721131674.039] [3188:3188] [DMG] ClusterId = 0x8, + [1721131674.039] [3188:3188] [DMG] CommandId = 0x5, + [1721131674.039] [3188:3188] [DMG] }, + [1721131674.039] [3188:3188] [DMG] + [1721131674.039] [3188:3188] [DMG] CommandFields = + [1721131674.039] [3188:3188] [DMG] { + [1721131674.039] [3188:3188] [DMG] 0x0 = 1 (unsigned), + [1721131674.039] [3188:3188] [DMG] 0x1 = 5 (unsigned), + [1721131674.039] [3188:3188] [DMG] 0x2 = 0 (unsigned), + [1721131674.039] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131674.040] [3188:3188] [DMG] }, + [1721131674.040] [3188:3188] [DMG] }, + [1721131674.040] [3188:3188] [DMG] + [1721131674.040] [3188:3188] [DMG] ], + [1721131674.040] [3188:3188] [DMG] + [1721131674.040] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131674.040] [3188:3188] [DMG] }, + [1721131674.040] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131674.040] [3188:3188] [DMG] AccessControl: allowed + [1721131674.040] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0005 + [1721131674.040] [3188:3188] [ZCL] RX level-control: MOVE_WITH_ON_OFF 1 5 0 0 + [1721131674.040] [3188:3188] [ZCL] Setting on/off to OFF due to level change + [1721131674.040] [3188:3188] [ZCL] Endpoint 1 On/off already set to new value + + + + + ./chip-tool levelcontrol step-with-on-off 1 15 123 0 0 1 1 + on TH (all-clusters-app) log. Verify the step-with-on-off command is received successfully. + + + [1721131696.543] [3188:3188] [EM] >>> [E:11849r S:12016 M:155492710] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131696.543] [3188:3188] [EM] Handling via exchange: 11849r, Delegate: 0xaaaac95ff3b0 + [1721131696.543] [3188:3188] [DMG] InvokeRequestMessage = + [1721131696.543] [3188:3188] [DMG] { + [1721131696.543] [3188:3188] [DMG] suppressResponse = false, + [1721131696.543] [3188:3188] [DMG] timedRequest = false, + [1721131696.543] [3188:3188] [DMG] InvokeRequests = + [1721131696.543] [3188:3188] [DMG] [ + [1721131696.543] [3188:3188] [DMG] CommandDataIB = + [1721131696.543] [3188:3188] [DMG] { + [1721131696.543] [3188:3188] [DMG] CommandPathIB = + [1721131696.543] [3188:3188] [DMG] { + [1721131696.543] [3188:3188] [DMG] EndpointId = 0x1, + [1721131696.543] [3188:3188] [DMG] ClusterId = 0x8, + [1721131696.543] [3188:3188] [DMG] CommandId = 0x6, + [1721131696.543] [3188:3188] [DMG] }, + [1721131696.544] [3188:3188] [DMG] + [1721131696.544] [3188:3188] [DMG] CommandFields = + [1721131696.544] [3188:3188] [DMG] { + [1721131696.544] [3188:3188] [DMG] 0x0 = 1 (unsigned), + [1721131696.544] [3188:3188] [DMG] 0x1 = 15 (unsigned), + [1721131696.544] [3188:3188] [DMG] 0x2 = 123 (unsigned), + [1721131696.544] [3188:3188] [DMG] 0x3 = 0 (unsigned), + [1721131696.544] [3188:3188] [DMG] 0x4 = 0 (unsigned), + [1721131696.544] [3188:3188] [DMG] }, + [1721131696.544] [3188:3188] [DMG] }, + [1721131696.544] [3188:3188] [DMG] + [1721131696.544] [3188:3188] [DMG] ], + [1721131696.544] [3188:3188] [DMG] + [1721131696.544] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131696.544] [3188:3188] [DMG] }, + [1721131696.544] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131696.544] [3188:3188] [DMG] AccessControl: allowed + [1721131696.544] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0006 + [1721131696.544] [3188:3188] [ZCL] RX level-control: STEP_WITH_ON_OFF 1 f 7b 0 0 + [1721131696.544] [3188:3188] [ZCL] Setting on/off to OFF due to level change + [1721131696.544] [3188:3188] [ZCL] Endpoint 1 On/off already set to new value + [1721131696.544] [3188:3188] [DMG] Command handler moving to [NewRespons] + + + ./chip-tool levelcontrol stop-with-on-off 0 0 1 1 + on TH (all-clusters-app) log. Verify the stop-with-on-off command is received successfully. + + [1721131714.456] [3188:3188] [EM] >>> [E:55346r S:12017 M:234822330] (S) Msg RX from 1:000000000001B669 [AD70] --- Type 0001:08 (IM:InvokeCommandRequest) + [1721131714.456] [3188:3188] [EM] Handling via exchange: 55346r, Delegate: 0xaaaac95ff3b0 + [1721131714.457] [3188:3188] [DMG] InvokeRequestMessage = + [1721131714.457] [3188:3188] [DMG] { + [1721131714.457] [3188:3188] [DMG] suppressResponse = false, + [1721131714.457] [3188:3188] [DMG] timedRequest = false, + [1721131714.457] [3188:3188] [DMG] InvokeRequests = + [1721131714.457] [3188:3188] [DMG] [ + [1721131714.457] [3188:3188] [DMG] CommandDataIB = + [1721131714.457] [3188:3188] [DMG] { + [1721131714.457] [3188:3188] [DMG] CommandPathIB = + [1721131714.457] [3188:3188] [DMG] { + [1721131714.457] [3188:3188] [DMG] EndpointId = 0x1, + [1721131714.457] [3188:3188] [DMG] ClusterId = 0x8, + [1721131714.457] [3188:3188] [DMG] CommandId = 0x7, + [1721131714.457] [3188:3188] [DMG] }, + [1721131714.457] [3188:3188] [DMG] + [1721131714.457] [3188:3188] [DMG] CommandFields = + [1721131714.457] [3188:3188] [DMG] { + [1721131714.457] [3188:3188] [DMG] 0x0 = 0 (unsigned), + [1721131714.457] [3188:3188] [DMG] 0x1 = 0 (unsigned), + [1721131714.457] [3188:3188] [DMG] }, + [1721131714.457] [3188:3188] [DMG] }, + [1721131714.457] [3188:3188] [DMG] + [1721131714.457] [3188:3188] [DMG] ], + [1721131714.457] [3188:3188] [DMG] + [1721131714.457] [3188:3188] [DMG] InteractionModelRevision = 11 + [1721131714.457] [3188:3188] [DMG] }, + [1721131714.457] [3188:3188] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0008 e=1 p=o + [1721131714.457] [3188:3188] [DMG] AccessControl: allowed + [1721131714.457] [3188:3188] [DMG] Received command for Endpoint=1 Cluster=0x0000_0008 Command=0x0000_0007 + [1721131714.457] [3188:3188] [ZCL] RX level-control: STOP_WITH_ON_OFF + [1721131714.457] [3188:3188] [DMG] Command handler moving to [NewRespons] + [1721131714.458] [3188:3188] [DMG] Command handler moving to [ Preparing] + disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml b/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml index f341f9e1dc1087..6e63953d262143 100644 --- a/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml @@ -58,9 +58,9 @@ tests: } - label: - "Step 0b: TH binds GroupIds 0x0001 and 0x0002 with GroupKeySetID - 0x01a1 in the GroupKeyMap attribute list on GroupKeyManagement cluster - by writing the GroupKeyMap attribute with two entries as follows:" + "Step 0b: TH binds GroupIds 0x0001 with GroupKeySetID 0x01a1 in the + GroupKeyMap attribute list on GroupKeyManagement cluster by writing + the GroupKeyMap attribute with two entries as follows:" cluster: "Group Key Management" endpoint: 0 command: "writeAttribute" @@ -122,8 +122,17 @@ tests: - name: "SceneList" value: [] + - label: "Step 2a: TH reads the MinLevel attribute from the DUT" + cluster: "Level Control" + command: "readAttribute" + attribute: "MinLevel" + response: + saveAs: MinLevelValue + constraints: + type: int8u + - label: - "Step 2a: TH sends a MoveToLevel command to DUT, with Level =0 and + "Step 2b: TH sends a MoveToLevel command to DUT, with Level =0 and TransitionTime =0 (immediate)" cluster: "Level Control" command: "MoveToLevel" @@ -138,15 +147,6 @@ tests: - name: "OptionsOverride" value: 1 - - label: "Step 2b: TH reads the MinLevel attribute from the DUT" - cluster: "Level Control" - command: "readAttribute" - attribute: "MinLevel" - response: - saveAs: MinLevelValue - constraints: - type: int8u - - label: "Step 2c: TH reads the CurrentLevel attribute from DUT" cluster: "Level Control" command: "readAttribute" From 3b83878fc839320a97460a722138068bd18c9225 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 3 Sep 2024 18:43:17 -0400 Subject: [PATCH 28/70] Update Quiet reporting conditions for LVL and CC remaining time attribute (#35224) * Update Quiet reporting conditions for LVL and CC remaining time attribute * Restyled by clang-format * Fix/cleaup of startUpColorTempCommand * Add missing SetQuietReportRemainingTime for moveToColorTemp command. Add remainingTime Report condition on command invoke. Fix clang-tidy * Update src/app/clusters/color-control-server/color-control-server.cpp Co-authored-by: Boris Zbarsky --------- Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- .../color-control-server.cpp | 153 ++++++++++-------- .../color-control-server.h | 20 +-- .../clusters/level-control/level-control.cpp | 70 ++++---- 3 files changed, 130 insertions(+), 113 deletions(-) diff --git a/src/app/clusters/color-control-server/color-control-server.cpp b/src/app/clusters/color-control-server/color-control-server.cpp index 05553525258d23..2a858884220fc9 100644 --- a/src/app/clusters/color-control-server/color-control-server.cpp +++ b/src/app/clusters/color-control-server/color-control-server.cpp @@ -1040,7 +1040,7 @@ void ColorControlServer::startColorLoop(EndpointId endpoint, uint8_t startFromSt colorHueTransitionState->transitionTime = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; - SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE, true /* isNewTransition */); scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } @@ -1091,7 +1091,10 @@ void ColorControlServer::SetHSVRemainingTime(chip::EndpointId endpoint) // When the hue transition is loop, RemainingTime stays at MAX_INT16 if (hueTransitionState->repeat == false) { - SetQuietReportRemainingTime(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); + bool hsvTransitionStart = (hueTransitionState->stepsRemaining == hueTransitionState->stepsTotal) || + (saturationTransitionState->stepsRemaining == saturationTransitionState->stepsTotal); + SetQuietReportRemainingTime(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining), + hsvTransitionStart); } } @@ -1484,7 +1487,7 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->repeat = true; // hue movement can last forever. Indicate this with a remaining time of maxint - SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE, true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2052,7 +2055,7 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons uint16_t storedEnhancedHue = 0; Attributes::ColorLoopStoredEnhancedHue::Get(endpoint, &storedEnhancedHue); MarkAttributeDirty markDirty = - SetQuietReportAttribute(quietEnhancedHue[epIndex], storedEnhancedHue, true /*isStartOrEndOfTransition*/, 0); + SetQuietReportAttribute(quietEnhancedHue[epIndex], storedEnhancedHue, true /*isEndOfTransition*/, 0); Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); } else @@ -2094,10 +2097,6 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) uint16_t previousSaturation = colorSaturationTransitionState->currentValue; uint16_t previousEnhancedhue = colorHueTransitionState->currentEnhancedHue; - bool isHueTansitionStart = (colorHueTransitionState->stepsRemaining == colorHueTransitionState->stepsTotal); - bool isSaturationTransitionStart = - (colorSaturationTransitionState->stepsRemaining == colorSaturationTransitionState->stepsTotal); - bool isHueTansitionDone = computeNewHueValue(colorHueTransitionState); bool isSaturationTransitionDone = computeNewColor16uValue(colorSaturationTransitionState); @@ -2117,7 +2116,7 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) if (colorHueTransitionState->isEnhancedHue) { markDirty = SetQuietReportAttribute(quietEnhancedHue[epIndex], colorHueTransitionState->currentEnhancedHue, - (isHueTansitionStart || isHueTansitionDone), colorHueTransitionState->transitionTime); + isHueTansitionDone, colorHueTransitionState->transitionTime); Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); currentHue = static_cast(colorHueTransitionState->currentEnhancedHue >> 8); @@ -2135,8 +2134,7 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) } } - markDirty = SetQuietReportAttribute(quietHue[epIndex], currentHue, (isHueTansitionStart || isHueTansitionDone), - colorHueTransitionState->transitionTime); + markDirty = SetQuietReportAttribute(quietHue[epIndex], currentHue, isHueTansitionDone, colorHueTransitionState->transitionTime); Attributes::CurrentHue::Set(endpoint, quietHue[epIndex].value().Value(), markDirty); if (previousSaturation != colorSaturationTransitionState->currentValue) @@ -2145,8 +2143,7 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) } markDirty = SetQuietReportAttribute(quietSaturation[epIndex], colorSaturationTransitionState->currentValue, - (isSaturationTransitionStart || isSaturationTransitionDone), - colorSaturationTransitionState->transitionTime); + isSaturationTransitionDone, colorSaturationTransitionState->transitionTime); Attributes::CurrentSaturation::Set(endpoint, quietSaturation[epIndex].value().Value(), markDirty); computePwmFromHsv(endpoint); @@ -2298,7 +2295,7 @@ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_ colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - SetQuietReportRemainingTime(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime, true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2405,7 +2402,7 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - SetQuietReportRemainingTime(endpoint, max(transitionTimeX, transitionTimeY)); + SetQuietReportRemainingTime(endpoint, max(transitionTimeX, transitionTimeY), true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2485,7 +2482,7 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - SetQuietReportRemainingTime(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime, true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2521,15 +2518,10 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } - bool isXTransitionStart = (colorXTransitionState->stepsRemaining == colorXTransitionState->stepsTotal); - bool isYTransitionStart = (colorYTransitionState->stepsRemaining == colorYTransitionState->stepsTotal); - - MarkAttributeDirty markXDirty = - SetQuietReportAttribute(quietColorX[epIndex], colorXTransitionState->currentValue, - (isXTransitionStart || isXTransitionDone), colorXTransitionState->transitionTime); - MarkAttributeDirty markYDirty = - SetQuietReportAttribute(quietColorY[epIndex], colorYTransitionState->currentValue, - (isYTransitionStart || isYTransitionDone), colorYTransitionState->transitionTime); + MarkAttributeDirty markXDirty = SetQuietReportAttribute(quietColorX[epIndex], colorXTransitionState->currentValue, + isXTransitionDone, colorXTransitionState->transitionTime); + MarkAttributeDirty markYDirty = SetQuietReportAttribute(quietColorY[epIndex], colorYTransitionState->currentValue, + isYTransitionDone, colorYTransitionState->transitionTime); Attributes::CurrentX::Set(endpoint, quietColorX[epIndex].value().Value(), markXDirty); Attributes::CurrentY::Set(endpoint, quietColorY[epIndex].value().Value(), markYDirty); @@ -2623,6 +2615,8 @@ Status ColorControlServer::moveToColorTemp(EndpointId aEndpoint, uint16_t colorT colorTempTransitionState->lowLimit = temperatureMin; colorTempTransitionState->highLimit = temperatureMax; + SetQuietReportRemainingTime(endpoint, transitionTime, true /* isNewTransition */); + // kick off the state machine scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); return Status::Success; @@ -2687,36 +2681,32 @@ void ColorControlServer::startUpColorTempCommand(EndpointId endpoint) if (status == Status::Success && !startUpColorTemp.IsNull()) { - uint16_t updatedColorTemp = MAX_TEMPERATURE_VALUE; - status = Attributes::ColorTemperatureMireds::Get(endpoint, &updatedColorTemp); + uint16_t tempPhysicalMin = MIN_TEMPERATURE_VALUE; + Attributes::ColorTempPhysicalMinMireds::Get(endpoint, &tempPhysicalMin); + // Avoid potential divide-by-zero in future Kelvin conversions. + tempPhysicalMin = std::max(static_cast(1u), tempPhysicalMin); - if (status == Status::Success) - { - uint16_t tempPhysicalMin = MIN_TEMPERATURE_VALUE; - Attributes::ColorTempPhysicalMinMireds::Get(endpoint, &tempPhysicalMin); - // Avoid potential divide-by-zero in future Kelvin conversions. - tempPhysicalMin = std::max(static_cast(1u), tempPhysicalMin); + uint16_t tempPhysicalMax = MAX_TEMPERATURE_VALUE; + Attributes::ColorTempPhysicalMaxMireds::Get(endpoint, &tempPhysicalMax); - uint16_t tempPhysicalMax = MAX_TEMPERATURE_VALUE; - Attributes::ColorTempPhysicalMaxMireds::Get(endpoint, &tempPhysicalMax); + if (tempPhysicalMin <= startUpColorTemp.Value() && startUpColorTemp.Value() <= tempPhysicalMax) + { + // Apply valid startup color temp value that is within physical limits of device. + // Otherwise, the startup value is outside the device's supported range, and the + // existing setting of ColorTemp attribute will be left unchanged (i.e., treated as + // if startup color temp was set to null). + uint16_t epIndex = getEndpointIndex(endpoint); + MarkAttributeDirty markDirty = SetQuietReportAttribute(quietTemperatureMireds[epIndex], startUpColorTemp.Value(), + false /* isEndOfTransition */, 0); + status = Attributes::ColorTemperatureMireds::Set(endpoint, quietTemperatureMireds[epIndex].value().Value(), markDirty); - if (tempPhysicalMin <= startUpColorTemp.Value() && startUpColorTemp.Value() <= tempPhysicalMax) + if (status == Status::Success) { - // Apply valid startup color temp value that is within physical limits of device. - // Otherwise, the startup value is outside the device's supported range, and the - // existing setting of ColorTemp attribute will be left unchanged (i.e., treated as - // if startup color temp was set to null). - updatedColorTemp = startUpColorTemp.Value(); - status = Attributes::ColorTemperatureMireds::Set(endpoint, updatedColorTemp); - - if (status == Status::Success) - { - // Set ColorMode attributes to reflect ColorTemperature. - auto updateColorMode = ColorModeEnum::kColorTemperatureMireds; - Attributes::ColorMode::Set(endpoint, updateColorMode); + // Set ColorMode attributes to reflect ColorTemperature. + auto updateColorMode = ColorModeEnum::kColorTemperatureMireds; + Attributes::ColorMode::Set(endpoint, updateColorMode); - Attributes::EnhancedColorMode::Set(endpoint, static_cast(updateColorMode)); - } + Attributes::EnhancedColorMode::Set(endpoint, static_cast(updateColorMode)); } } } @@ -2729,7 +2719,8 @@ void ColorControlServer::startUpColorTempCommand(EndpointId endpoint) */ void ColorControlServer::updateTempCommand(EndpointId endpoint) { - Color16uTransitionState * colorTempTransitionState = getTempTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorTempTransitionState = getTempTransitionStateByIndex(epIndex); bool isColorTempTransitionDone; isColorTempTransitionDone = computeNewColor16uValue(colorTempTransitionState); @@ -2763,7 +2754,9 @@ void ColorControlServer::updateTempCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureTempEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } - Attributes::ColorTemperatureMireds::Set(endpoint, colorTempTransitionState->currentValue); + MarkAttributeDirty markDirty = SetQuietReportAttribute(quietTemperatureMireds[epIndex], colorTempTransitionState->currentValue, + isColorTempTransitionDone, colorTempTransitionState->timeRemaining); + Attributes::ColorTemperatureMireds::Set(endpoint, quietTemperatureMireds[epIndex].value().Value(), markDirty); ChipLogProgress(Zcl, "Color Temperature %d", colorTempTransitionState->currentValue); @@ -2882,7 +2875,7 @@ bool ColorControlServer::moveColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - SetQuietReportRemainingTime(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime, true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -3005,7 +2998,7 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - SetQuietReportRemainingTime(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime, true /* isNewTransition */); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -3103,7 +3096,6 @@ void ColorControlServer::levelControlColorTempChangeCommand(EndpointId endpoint) * Utility function used to update a color control attribute which has the quiet reporting quality. * matching the following report conditions: * - At most once per second, or - * - At the start of the movement/transition, or * - At the end of the movement/transition, or * - When it changes from null to any other value and vice versa. (Implicit to the QuieterReportingAttribute class) * @@ -3114,20 +3106,20 @@ void ColorControlServer::levelControlColorTempChangeCommand(EndpointId endpoint) * * @param quietReporter: The QuieterReportingAttribute object for the attribute to update. * @param newValue: Value to update the attribute with - * @param isStartOrEndOfTransition: Boolean that indicatse whether the update is occurring at the start or end of a level transition + * @param isEndOfTransition: Boolean that indicates whether the update is occurring at the end of a color transition * @return MarkAttributeDirty::kYes when the attribute must be marked dirty and be reported. MarkAttributeDirty::kNo when * no report is needed. */ template MarkAttributeDirty ColorControlServer::SetQuietReportAttribute(QuieterReportingAttribute & quietReporter, V newValue, - bool isStartOrEndOfTransition, uint16_t transitionTime) + bool isEndOfTransition, uint16_t transitionTime) { AttributeDirtyState dirtyState; auto now = System::SystemClock().GetMonotonicTimestamp(); - if (isStartOrEndOfTransition) + if (isEndOfTransition) { - // At the start or end of the movement/transition we must report if the value changed + // At the end of the movement/transition we must report if the value changed auto predicate = [](const typename QuieterReportingAttribute::SufficientChangePredicateCandidate &) -> bool { return true; }; @@ -3157,23 +3149,42 @@ MarkAttributeDirty ColorControlServer::SetQuietReportAttribute(QuieterReportingA * @brief * Function used to set the remaining time based on quiet reporting conditions. * It will update the attribute storage and report the attribute if it is determined dirty. - * The condition on which the attribute must be reported are defined by the set QuieterReportingPolicyFlags - * of the quietRemainingTime object and the implicit conditions of the QuieterReportingAttribute class + * The conditions on which the attribute must be reported are: + * - When it changes from 0 to any value higher than 10, or + * - When it changes, with a delta larger than 10, caused by the invoke of a command, or + * - When it changes to 0. * * @param endpoint: Endpoint of the RemainingTime attribute to set * @param newRemainingTime: Value to update the RemainingTime attribute with * @return Success in setting the attribute value or the IM error code for the failure. */ -Status ColorControlServer::SetQuietReportRemainingTime(EndpointId endpoint, uint16_t newRemainingTime) -{ - uint16_t epIndex = getEndpointIndex(endpoint); - auto markDirty = MarkAttributeDirty::kNo; - auto now = System::SystemClock().GetMonotonicTimestamp(); - // Establish the quiet report condition for the RemainingTime Attribute - // The quiet report is by the previously set policies : - // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or - // - kMarkDirtyOnIncrement : When the value increases. - if (quietRemainingTime[epIndex].SetValue(newRemainingTime, now) == AttributeDirtyState::kMustReport) +Status ColorControlServer::SetQuietReportRemainingTime(EndpointId endpoint, uint16_t newRemainingTime, bool isNewTransition) +{ + uint16_t epIndex = getEndpointIndex(endpoint); + uint16_t lastRemainingTime = quietRemainingTime[epIndex].value().ValueOr(0); + auto markDirty = MarkAttributeDirty::kNo; + auto now = System::SystemClock().GetMonotonicTimestamp(); + + auto predicate = + [isNewTransition, lastRemainingTime]( + const typename QuieterReportingAttribute::SufficientChangePredicateCandidate & candidate) -> bool { + constexpr uint16_t reportDelta = 10; + bool isDirty = false; + if (candidate.newValue.Value() == 0 || (candidate.lastDirtyValue.Value() == 0 && candidate.newValue.Value() > reportDelta)) + { + isDirty = true; + } + else if (isNewTransition && + (candidate.newValue.Value() > static_cast(lastRemainingTime + reportDelta) || + static_cast(candidate.newValue.Value() + reportDelta) < lastRemainingTime || + candidate.newValue.Value() > static_cast(candidate.lastDirtyValue.Value() + reportDelta))) + { + isDirty = true; + } + return isDirty; + }; + + if (quietRemainingTime[epIndex].SetValue(newRemainingTime, now, predicate) == AttributeDirtyState::kMustReport) { markDirty = MarkAttributeDirty::kYes; } diff --git a/src/app/clusters/color-control-server/color-control-server.h b/src/app/clusters/color-control-server/color-control-server.h index 88343e7cb0f4af..422c7f592f8b33 100644 --- a/src/app/clusters/color-control-server/color-control-server.h +++ b/src/app/clusters/color-control-server/color-control-server.h @@ -203,27 +203,16 @@ class ColorControlServer template chip::app::MarkAttributeDirty SetQuietReportAttribute(chip::app::QuieterReportingAttribute & quietReporter, V newValue, - bool isStartOrEndOfTransition, uint16_t transitionTime); - chip::Protocols::InteractionModel::Status SetQuietReportRemainingTime(chip::EndpointId endpoint, uint16_t newRemainingTime); + bool isEndOfTransition, uint16_t transitionTime); + chip::Protocols::InteractionModel::Status SetQuietReportRemainingTime(chip::EndpointId endpoint, uint16_t newRemainingTime, + bool isNewTransition = false); private: /********************************************************** * Functions Definitions *********************************************************/ - ColorControlServer() - { - for (size_t i = 0; i < kColorControlClusterServerMaxEndpointCount; i++) - { - // Set the quiet report policies for the RemaininTime Attribute on all endpoint - // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or - // - kMarkDirtyOnIncrement : When the value increases. - quietRemainingTime[i] - .policy() - .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) - .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); - } - } + ColorControlServer() {} bool shouldExecuteIfOff(chip::EndpointId endpoint, chip::BitMask optionMask, chip::BitMask optionOverride); @@ -312,6 +301,7 @@ class ColorControlServer #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP Color16uTransitionState colorTempTransitionStates[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietTemperatureMireds[kColorControlClusterServerMaxEndpointCount]; #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP EmberEventControl eventControls[kColorControlClusterServerMaxEndpointCount]; diff --git a/src/app/clusters/level-control/level-control.cpp b/src/app/clusters/level-control/level-control.cpp index 231a542c2ef1b4..c176d6f6b17bbb 100644 --- a/src/app/clusters/level-control/level-control.cpp +++ b/src/app/clusters/level-control/level-control.cpp @@ -121,12 +121,12 @@ static void stopHandler(CommandHandler * commandObj, const ConcreteCommandPath & chip::Optional> optionsMask, chip::Optional> optionsOverride); static void setOnOffValue(EndpointId endpoint, bool onOff); -static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs); +static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs, bool isNewTransition = false); static bool shouldExecuteIfOff(EndpointId endpoint, CommandId commandId, chip::Optional> optionsMask, chip::Optional> optionsOverride); static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelControlState * state, - DataModel::Nullable newValue, bool isStartOrEndOfTransition); + DataModel::Nullable newValue, bool isEndOfTransition); #if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl @@ -372,23 +372,22 @@ static void reallyUpdateCoupledColorTemp(EndpointId endpoint) * while respecting its defined quiet reporting quality: * The attribute will be reported: * - At most once per second, or - * - At the start of the movement/transition, or * - At the end of the movement/transition, or * - When it changes from null to any other value and vice versa. * * @param endpoint: endpoint on which the currentLevel attribute must be updated. * @param state: LevelControlState struct of this given endpoint. * @param newValue: Value to update the attribute with - * @param isStartOrEndOfTransition: Boolean that indicate whether the update is occuring at the start or end of a level transition + * @param isEndOfTransition: Boolean that indicate whether the update is occuring at the end of a level transition * @return Success in setting the attribute value or the IM error code for the failure. */ static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelControlState * state, - DataModel::Nullable newValue, bool isStartOrEndOfTransition) + DataModel::Nullable newValue, bool isEndOfTransition) { AttributeDirtyState dirtyState; auto now = System::SystemClock().GetMonotonicTimestamp(); - if (isStartOrEndOfTransition) + if (isEndOfTransition) { // At the start or end of the movement/transition we must report auto predicate = [](const decltype(state->quietCurrentLevel)::SufficientChangePredicateCandidate &) -> bool { @@ -467,7 +466,7 @@ void emberAfLevelControlClusterServerTickCallback(EndpointId endpoint) // Are we at the requested level? isTransitionEnd = (currentLevel.Value() == state->moveToLevel); - status = SetCurrentLevelQuietReport(endpoint, state, currentLevel, (isTransitionStart || isTransitionEnd)); + status = SetCurrentLevelQuietReport(endpoint, state, currentLevel, isTransitionEnd); if (status != Status::Success) { ChipLogProgress(Zcl, "ERR: writing current level %x", to_underlying(status)); @@ -506,12 +505,12 @@ void emberAfLevelControlClusterServerTickCallback(EndpointId endpoint) else { state->callbackSchedule.runTime = System::SystemClock().GetMonotonicTimestamp() - callbackStartTimestamp; - writeRemainingTime(endpoint, static_cast(state->transitionTimeMs - state->elapsedTimeMs)); + writeRemainingTime(endpoint, static_cast(state->transitionTimeMs - state->elapsedTimeMs), isTransitionStart); scheduleTimerCallbackMs(endpoint, computeCallbackWaitTimeMs(state->callbackSchedule, state->eventDurationMs)); } } -static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs) +static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs, bool isNewTransition) { #ifndef IGNORE_LEVEL_CONTROL_CLUSTER_LEVEL_CONTROL_REMAINING_TIME if (emberAfContainsAttribute(endpoint, LevelControl::Id, LevelControl::Attributes::RemainingTime::Id)) @@ -531,16 +530,36 @@ static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs) // // This is done to ensure that the attribute, in tenths of a second, only // goes to zero when the remaining time in milliseconds is actually zero. - uint16_t remainingTimeDs = static_cast((remainingTimeMs + 99) / 100); - auto markDirty = MarkAttributeDirty::kNo; - auto state = getState(endpoint); - auto now = System::SystemClock().GetMonotonicTimestamp(); - - // Establish the quiet report condition for the RemainingTime Attribute - // The quiet report is determined by the previously set policies: - // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or - // - kMarkDirtyOnIncrement : When the value increases. - if (state->quietRemainingTime.SetValue(remainingTimeDs, now) == AttributeDirtyState::kMustReport) + auto markDirty = MarkAttributeDirty::kNo; + auto state = getState(endpoint); + auto now = System::SystemClock().GetMonotonicTimestamp(); + uint16_t remainingTimeDs = static_cast((remainingTimeMs + 99) / 100); + uint16_t lastRemainingTime = state->quietRemainingTime.value().ValueOr(0); + + // RemainingTime Quiet report conditions: + // - When it changes to 0, or + // - When it changes from 0 to any value higher than 10, or + // - When it changes, with a delta larger than 10, caused by the invoke of a command. + auto predicate = [isNewTransition, lastRemainingTime]( + const decltype(state->quietRemainingTime)::SufficientChangePredicateCandidate & candidate) -> bool { + constexpr uint16_t reportDelta = 10; + bool isDirty = false; + if (candidate.newValue.Value() == 0 || + (candidate.lastDirtyValue.Value() == 0 && candidate.newValue.Value() > reportDelta)) + { + isDirty = true; + } + else if (isNewTransition && + (candidate.newValue.Value() > static_cast(lastRemainingTime + reportDelta) || + static_cast(candidate.newValue.Value() + reportDelta) < lastRemainingTime || + candidate.newValue.Value() > static_cast(candidate.lastDirtyValue.Value() + reportDelta))) + { + isDirty = true; + } + return isDirty; + }; + + if (state->quietRemainingTime.SetValue(remainingTimeDs, now, predicate) == AttributeDirtyState::kMustReport) { markDirty = MarkAttributeDirty::kYes; } @@ -1316,7 +1335,7 @@ static void stopHandler(CommandHandler * commandObj, const ConcreteCommandPath & // Cancel any currently active command. cancelEndpointTimerCallback(endpoint); - SetCurrentLevelQuietReport(endpoint, state, state->quietCurrentLevel.value(), true /*isStartOrEndOfTransition*/); + SetCurrentLevelQuietReport(endpoint, state, state->quietCurrentLevel.value(), true /*isEndOfTransition*/); writeRemainingTime(endpoint, 0); send_default_response: @@ -1410,7 +1429,7 @@ void emberAfOnOffClusterLevelControlEffectCallback(EndpointId endpoint, bool new { // If newValue is OnOff::Commands::On::Id... // "Set CurrentLevel to minimum level allowed for the device." - status = SetCurrentLevelQuietReport(endpoint, state, minimumLevelAllowedForTheDevice, true /*isStartOrEndOfTransition*/); + status = SetCurrentLevelQuietReport(endpoint, state, minimumLevelAllowedForTheDevice, false /*isEndOfTransition*/); if (status != Status::Success) { ChipLogProgress(Zcl, "ERR: reading current level %x", to_underlying(status)); @@ -1453,9 +1472,6 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) return; } - state->quietRemainingTime.policy() - .Set(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) - .Set(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); state->minLevel = MATTER_DM_PLUGIN_LEVEL_CONTROL_MINIMUM_LEVEL; state->maxLevel = MATTER_DM_PLUGIN_LEVEL_CONTROL_MAXIMUM_LEVEL; @@ -1528,18 +1544,18 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) } } // Otherwise Set the CurrentLevel attribute to its previous value which was already fetch above - SetCurrentLevelQuietReport(endpoint, state, currentLevel, true /*isStartOrEndOfTransition*/); + SetCurrentLevelQuietReport(endpoint, state, currentLevel, false /*isEndOfTransition*/); } } #endif // IGNORE_LEVEL_CONTROL_CLUSTER_START_UP_CURRENT_LEVEL // In any case, we make sure that the respects min/max if (currentLevel.IsNull() || currentLevel.Value() < state->minLevel) { - SetCurrentLevelQuietReport(endpoint, state, state->minLevel, true /*isStartOrEndOfTransition*/); + SetCurrentLevelQuietReport(endpoint, state, state->minLevel, false /*isEndOfTransition*/); } else if (currentLevel.Value() > state->maxLevel) { - SetCurrentLevelQuietReport(endpoint, state, state->maxLevel, true /*isStartOrEndOfTransition*/); + SetCurrentLevelQuietReport(endpoint, state, state->maxLevel, false /*isEndOfTransition*/); } } From 3de6f0478cd267b6aa71beebb1f8734c5d571f7e Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Tue, 3 Sep 2024 16:01:37 -0700 Subject: [PATCH 29/70] [ICD] refreshKey needs to be set with length (#35379) * refreshKey needs to be set with length * address comments --- src/app/icd/client/DefaultCheckInDelegate.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/icd/client/DefaultCheckInDelegate.cpp b/src/app/icd/client/DefaultCheckInDelegate.cpp index 2d4624b7837470..081b4be7bb7395 100644 --- a/src/app/icd/client/DefaultCheckInDelegate.cpp +++ b/src/app/icd/client/DefaultCheckInDelegate.cpp @@ -41,7 +41,8 @@ void DefaultCheckInDelegate::OnCheckInComplete(const ICDClientInfo & clientInfo) CHIP_ERROR DefaultCheckInDelegate::GenerateRefreshKey(RefreshKeySender::RefreshKeyBuffer & newKey) { - return Crypto::DRBG_get_bytes(newKey.Bytes(), newKey.Capacity()); + ReturnErrorOnFailure(Crypto::DRBG_get_bytes(newKey.Bytes(), newKey.Capacity())); + return newKey.SetLength(newKey.Capacity()); } RefreshKeySender * DefaultCheckInDelegate::OnKeyRefreshNeeded(ICDClientInfo & clientInfo, ICDClientStorage * clientStorage) From cacf69fca8024ed19245647ece4b1d87c8993368 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Tue, 3 Sep 2024 19:46:30 -0400 Subject: [PATCH 30/70] fabric-admin add ability to grab uid from remote fabric sync device (#35377) --- examples/fabric-admin/BUILD.gn | 2 + .../device_manager/DeviceManager.h | 6 +- .../device_manager/DeviceSubscription.cpp | 11 +- .../device_manager/DeviceSynchronization.cpp | 120 +++++++++++--- .../device_manager/DeviceSynchronization.h | 23 ++- .../fabric-admin/device_manager/UidGetter.cpp | 146 ++++++++++++++++++ .../fabric-admin/device_manager/UidGetter.h | 64 ++++++++ 7 files changed, 343 insertions(+), 29 deletions(-) create mode 100644 examples/fabric-admin/device_manager/UidGetter.cpp create mode 100644 examples/fabric-admin/device_manager/UidGetter.h diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index 805fda1cb500c7..36ba7ec4e15d51 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -88,6 +88,8 @@ static_library("fabric-admin-utils") { "device_manager/DeviceSubscriptionManager.h", "device_manager/DeviceSynchronization.cpp", "device_manager/DeviceSynchronization.h", + "device_manager/UidGetter.cpp", + "device_manager/UidGetter.h", ] deps = [ "${chip_root}/src/app:events" ] diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 22a3004aa1642b..5f617845f7dc76 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -171,6 +171,9 @@ class DeviceManager : public PairingDelegate void HandleCommandResponse(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader & data); + Device * FindDeviceByEndpoint(chip::EndpointId endpointId); + Device * FindDeviceByNode(chip::NodeId nodeId); + private: friend DeviceManager & DeviceMgr(); @@ -206,9 +209,6 @@ class DeviceManager : public PairingDelegate bool mAutoSyncEnabled = false; bool mInitialized = false; uint64_t mRequestId = 0; - - Device * FindDeviceByEndpoint(chip::EndpointId endpointId); - Device * FindDeviceByNode(chip::NodeId nodeId); }; /** diff --git a/examples/fabric-admin/device_manager/DeviceSubscription.cpp b/examples/fabric-admin/device_manager/DeviceSubscription.cpp index eabbdda15dea15..dddb4f9f758291 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscription.cpp +++ b/examples/fabric-admin/device_manager/DeviceSubscription.cpp @@ -207,10 +207,15 @@ CHIP_ERROR DeviceSubscription::StartSubscription(OnDoneCallback onDoneCallback, mCurrentAdministratorCommissioningAttributes.node_id = nodeId; mCurrentAdministratorCommissioningAttributes.window_status = static_cast(Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen); - mState = State::Connecting; - mOnDoneCallback = onDoneCallback; - return controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + mOnDoneCallback = onDoneCallback; + MoveToState(State::Connecting); + CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + MoveToState(State::Idle); + } + return err; } void DeviceSubscription::StopSubscription() diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index 0ca2e270826c9e..bc3e9b31fe6b1b 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -128,35 +128,35 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, void DeviceSynchronizer::OnReportEnd() { // Report end is at the end of all attributes (success) + MoveToState(State::ReceivedResponse); +} + +void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) +{ #if defined(PW_RPC_ENABLED) - if (!DeviceMgr().IsCurrentBridgeDevice(mCurrentDeviceData.node_id)) + if (mState == State::ReceivedResponse && !DeviceMgr().IsCurrentBridgeDevice(mCurrentDeviceData.node_id)) { - AddSynchronizedDevice(mCurrentDeviceData); - // TODO(#35077) Figure out how we should reflect CADMIN values of ICD. - if (!mCurrentDeviceData.is_icd) + auto * device = DeviceMgr().FindDeviceByNode(mCurrentDeviceData.node_id); + if (!mCurrentDeviceData.has_unique_id && device) { - VerifyOrDie(mController); - // TODO(#35333) Figure out how we should recover in this circumstance. - CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, mCurrentDeviceData.node_id); - if (err != CHIP_NO_ERROR) + GetUid(device->GetEndpointId()); + if (mState == State::GettingUid) { - ChipLogError(NotSpecified, "Failed start subscription to "); + // GetUid was successful and we rely on callback to call SynchronizationCompleteAddDevice. + return; } } + SynchronizationCompleteAddDevice(); } #else ChipLogError(NotSpecified, "Cannot synchronize device with fabric bridge: RPC not enabled"); #endif -} - -void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) -{ - // Nothing to do: error reported on OnError or report ended called. - mDeviceSyncInProcess = false; + MoveToState(State::Idle); } void DeviceSynchronizer::OnError(CHIP_ERROR error) { + MoveToState(State::ReceivedError); ChipLogProgress(NotSpecified, "Error fetching device data: %" CHIP_ERROR_FORMAT, error.Format()); } @@ -180,21 +180,22 @@ void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & ex if (err != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed to issue read for BasicInformation data"); - mDeviceSyncInProcess = false; + MoveToState(State::Idle); } + MoveToState(State::AwaitingResponse); } void DeviceSynchronizer::OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error) { ChipLogError(NotSpecified, "Device Sync failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); - mDeviceSyncInProcess = false; + MoveToState(State::Idle); } void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController * controller, chip::NodeId nodeId, bool deviceIsIcd) { VerifyOrDie(controller); - if (mDeviceSyncInProcess) + if (mState != State::Idle) { ChipLogError(NotSpecified, "Device Sync NOT POSSIBLE: another sync is in progress"); return; @@ -205,8 +206,85 @@ void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceCont mCurrentDeviceData.has_is_icd = true; mCurrentDeviceData.is_icd = deviceIsIcd; - mDeviceSyncInProcess = true; - + ReturnOnFailure(controller->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback)); mController = controller; - controller->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + MoveToState(State::Connecting); +} + +void DeviceSynchronizer::GetUid(EndpointId remoteEndpointIdOfInterest) +{ + VerifyOrDie(mState == State::ReceivedResponse); + VerifyOrDie(mController); + VerifyOrDie(DeviceMgr().IsFabricSyncReady()); + auto remoteBridgeNodeId = DeviceMgr().GetRemoteBridgeNodeId(); + + CHIP_ERROR err = mUidGetter.GetUid( + [this](std::optional aUniqueId) { + if (aUniqueId.has_value()) + { + this->mCurrentDeviceData.has_unique_id = true; + memcpy(this->mCurrentDeviceData.unique_id, aUniqueId.value().data(), aUniqueId.value().size()); + } + else + { + ChipLogError(NotSpecified, "We expected to get UniqueId from remote fabric sync bridge"); + } + this->SynchronizationCompleteAddDevice(); + }, + *mController, remoteBridgeNodeId, remoteEndpointIdOfInterest); + + if (err == CHIP_NO_ERROR) + { + MoveToState(State::GettingUid); + } +} + +void DeviceSynchronizer::SynchronizationCompleteAddDevice() +{ + VerifyOrDie(mState == State::ReceivedResponse || mState == State::GettingUid); + AddSynchronizedDevice(mCurrentDeviceData); + // TODO(#35077) Figure out how we should reflect CADMIN values of ICD. + if (!mCurrentDeviceData.is_icd) + { + VerifyOrDie(mController); + // TODO(#35333) Figure out how we should recover in this circumstance. + CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, mCurrentDeviceData.node_id); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed start subscription to NodeId:" ChipLogFormatX64, + ChipLogValueX64(mCurrentDeviceData.node_id)); + } + } + MoveToState(State::Idle); +} + +void DeviceSynchronizer::MoveToState(const State targetState) +{ + mState = targetState; + ChipLogDetail(NotSpecified, "DeviceSynchronizer moving to [%10.10s]", GetStateStr()); +} + +const char * DeviceSynchronizer::GetStateStr() const +{ + switch (mState) + { + case State::Idle: + return "Idle"; + + case State::Connecting: + return "Connecting"; + + case State::AwaitingResponse: + return "AwaitingResponse"; + + case State::ReceivedResponse: + return "ReceivedResponse"; + + case State::ReceivedError: + return "ReceivedError"; + + case State::GettingUid: + return "GettingUid"; + } + return "N/A"; } diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.h b/examples/fabric-admin/device_manager/DeviceSynchronization.h index c5a42378b8be9d..495fecd60bd4b5 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.h +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.h @@ -17,6 +17,8 @@ */ #pragma once +#include "UidGetter.h" + #include #include #include @@ -65,14 +67,31 @@ class DeviceSynchronizer : public chip::app::ReadClient::Callback static DeviceSynchronizer & Instance(); private: + enum class State : uint8_t + { + Idle, ///< Default state that the object starts out in, where no work has commenced + Connecting, ///< We are waiting for OnDeviceConnected or OnDeviceConnectionFailure callbacks to be called + AwaitingResponse, ///< We have started reading BasicInformation cluster attributes + ReceivedResponse, ///< We have received a ReportEnd from reading BasicInformation cluster attributes + ReceivedError, ///< We recieved an error while reading of BasicInformation cluster attributes + GettingUid, ///< We are getting UniqueId from the remote fabric sync bridge. + }; + + void GetUid(chip::EndpointId endpointId); + void SynchronizationCompleteAddDevice(); + + void MoveToState(const State targetState); + const char * GetStateStr() const; + std::unique_ptr mClient; chip::Callback::Callback mOnDeviceConnectedCallback; chip::Callback::Callback mOnDeviceConnectionFailureCallback; + State mState = State::Idle; // mController is expected to remain valid throughout the entire device synchronization process (i.e. when - // mDeviceSyncInProcess is true). + // mState != Idle). chip::Controller::DeviceController * mController = nullptr; - bool mDeviceSyncInProcess = false; chip_rpc_SynchronizedDevice mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; + UidGetter mUidGetter; }; diff --git a/examples/fabric-admin/device_manager/UidGetter.cpp b/examples/fabric-admin/device_manager/UidGetter.cpp new file mode 100644 index 00000000000000..baeaba6a02498c --- /dev/null +++ b/examples/fabric-admin/device_manager/UidGetter.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "UidGetter.h" + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace { + +void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + reinterpret_cast(context)->OnDeviceConnected(exchangeMgr, sessionHandle); +} + +void OnDeviceConnectionFailureWrapper(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +{ + reinterpret_cast(context)->OnDeviceConnectionFailure(peerId, error); +} + +bool SuccessOrLog(CHIP_ERROR err, const char * name) +{ + if (err == CHIP_NO_ERROR) + { + return true; + } + + ChipLogError(NotSpecified, "Failed to read %s: %" CHIP_ERROR_FORMAT, name, err.Format()); + + return false; +} + +} // namespace + +UidGetter::UidGetter() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR UidGetter::GetUid(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, chip::NodeId nodeId, + chip::EndpointId endpointId) +{ + assertChipStackLockedByCurrentThread(); + VerifyOrDie(!mCurrentlyGettingUid); + + mEndpointId = endpointId; + mOnDoneCallback = onDoneCallback; + mUniqueIdHasValue = false; + memset(mUniqueId, 0, sizeof(mUniqueId)); + mCurrentlyGettingUid = true; + + CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to connect to remote fabric sync bridge %" CHIP_ERROR_FORMAT, err.Format()); + mCurrentlyGettingUid = false; + } + return err; +} + +void UidGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + VerifyOrDie(path.mClusterId == Clusters::BridgedDeviceBasicInformation::Id); + + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + + switch (path.mAttributeId) + { + case Clusters::BridgedDeviceBasicInformation::Attributes::UniqueID::Id: { + mUniqueIdHasValue = SuccessOrLog(data->GetString(mUniqueId, sizeof(mUniqueId)), "UniqueId"); + break; + } + default: + break; + } +} + +void UidGetter::OnReportEnd() +{ + // We will call mOnDoneCallback in OnDone. +} + +void UidGetter::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error Getting UID: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void UidGetter::OnDone(ReadClient * apReadClient) +{ + mCurrentlyGettingUid = false; + mOnDoneCallback(mUniqueIdHasValue ? std::make_optional(mUniqueId) : std::nullopt); +} + +void UidGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + VerifyOrDie(mCurrentlyGettingUid); + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr, *this /* callback */, + ReadClient::InteractionType::Read); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(mEndpointId, Clusters::BridgedDeviceBasicInformation::Id, + Clusters::BridgedDeviceBasicInformation::Attributes::UniqueID::Id); + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to issue subscription to AdministratorCommissioning data"); + OnDone(nullptr); + return; + } +} + +void UidGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + VerifyOrDie(mCurrentlyGettingUid); + ChipLogError(NotSpecified, "DeviceSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + + OnDone(nullptr); +} diff --git a/examples/fabric-admin/device_manager/UidGetter.h b/examples/fabric-admin/device_manager/UidGetter.h new file mode 100644 index 00000000000000..5f99c75198c5dc --- /dev/null +++ b/examples/fabric-admin/device_manager/UidGetter.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include + +#include +#include + +class UidGetter : public chip::app::ReadClient::Callback +{ +public: + using OnDoneCallback = std::function)>; + + UidGetter(); + + CHIP_ERROR GetUid(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, chip::NodeId nodeId, + chip::EndpointId endpointId); + + /////////////////////////////////////////////////////////////// + // ReadClient::Callback implementation + /////////////////////////////////////////////////////////////// + void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, + const chip::app::StatusIB & status) override; + void OnReportEnd() override; + void OnError(CHIP_ERROR error) override; + void OnDone(chip::app::ReadClient * apReadClient) override; + + /////////////////////////////////////////////////////////////// + // callbacks for CASE session establishment + /////////////////////////////////////////////////////////////// + void OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle); + void OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error); + +private: + std::unique_ptr mClient; + + OnDoneCallback mOnDoneCallback; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + + bool mCurrentlyGettingUid = false; + bool mUniqueIdHasValue = false; + char mUniqueId[33]; + chip::EndpointId mEndpointId; +}; From f95c8e78380bc9d0bdb1d5e9099c8099aef0e4db Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:09:44 -0700 Subject: [PATCH 31/70] Fix typo (#35375) --- .../tests/suites/certification/Test_TC_CNET_4_13.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_CNET_4_13.yaml b/src/app/tests/suites/certification/Test_TC_CNET_4_13.yaml index d2dbeb418f9f25..8acd24628c910e 100644 --- a/src/app/tests/suites/certification/Test_TC_CNET_4_13.yaml +++ b/src/app/tests/suites/certification/Test_TC_CNET_4_13.yaml @@ -54,7 +54,7 @@ tests: entries as 'NumNetworks'" PICS: CNET.S.A0001 verification: | - ./chip-tool network-commissioning read networks 1 0 + ./chip-tool networkcommissioning read networks 1 0 The test case is not verifiable in RPI platform. As MaxNetworks value is 1 but expected is 4 ( Pre-Condition) @@ -128,7 +128,7 @@ tests: NT_SSID 2. NetworkIn dex is 'MaxNetwo rksValue' 3. Breadcrum b is 2" PICS: CNET.S.C08.Rsp && CNET.S.C05.Tx verification: | - ./chip-tool network-commissioning read networks 1 0 + ./chip-tool networkcommissioning read networks 1 0 The test case is not verifiable in RPI platform. As MaxNetworks value is 1 but expected is 4 ( Pre-Condition) @@ -189,7 +189,7 @@ tests: - label: "Step 13: TH readsNetworksattribute list fromthe DUT" PICS: CNET.S.A0001 verification: | - ./chip-tool network-commissioning read networks 1 0 + ./chip-tool networkcommissioning read networks 1 0 The test case is not verifiable in RPI platform. As MaxNetworks value is 1 but expected is 4 ( Pre-Condition) @@ -208,7 +208,7 @@ tests: - label: "Step 15: TH readsNetworksattribute list fromthe DUT" PICS: CNET.S.A0001 verification: | - ./chip-tool network-commissioning read networks 1 0 + ./chip-tool networkcommissioning read networks 1 0 The test case is not verifiable in RPI platform. As MaxNetworks value is 1 but expected is 4 ( Pre-Condition) @@ -268,7 +268,7 @@ tests: - label: "Step 21: TH readsNetworksattribute list fromthe DUT" PICS: CNET.S.A0001 verification: | - ./chip-tool network-commissioning read networks 1 0 + ./chip-tool networkcommissioning read networks 1 0 The test case is not verifiable in RPI platform. As MaxNetworks value is 1 but expected is 4 ( Pre-Condition) From f8504382b574417db73a602a9bedc47a2a957103 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:25:45 -0400 Subject: [PATCH 32/70] Fix mismatch in gn argument name between its declaration and usage. (#35384) --- third_party/silabs/efr32_sdk.gni | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index ce7b09e3e012ac..c75f67694e8d5c 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -61,7 +61,7 @@ declare_args() { sl_active_mode_duration_ms = 1000 # 1s Active Mode Duration sl_active_mode_threshold_ms = 500 # 500ms Active Mode Threshold sl_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric - sl_use_subscription_synching = false + sl_use_subscription_syncing = false silabs_log_enabled = true @@ -658,7 +658,7 @@ template("efr32_sdk") { ] } - if (sl_use_subscription_synching) { + if (sl_use_subscription_syncing) { defines += [ "CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED=1" ] } From cddc8ca7f51fe756ba047fd46baa72443e75e68c Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Tue, 3 Sep 2024 17:47:13 -0700 Subject: [PATCH 33/70] [ICD] Set client_type when refreshing token for LIT ICD (#35383) * set client_type when refresh key for ICD * Update RefreshKeySender.cpp --- src/app/icd/client/RefreshKeySender.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/icd/client/RefreshKeySender.cpp b/src/app/icd/client/RefreshKeySender.cpp index 8b6122d0228f95..c49bf79f30a17c 100644 --- a/src/app/icd/client/RefreshKeySender.cpp +++ b/src/app/icd/client/RefreshKeySender.cpp @@ -80,6 +80,7 @@ CHIP_ERROR RefreshKeySender::RegisterClientWithNewKey(Messaging::ExchangeManager registerClientCommand.checkInNodeID = mICDClientInfo.check_in_node.GetNodeId(); registerClientCommand.monitoredSubject = mICDClientInfo.monitored_subject; registerClientCommand.key = mNewKey.Span(); + registerClientCommand.clientType = mICDClientInfo.client_type; return Controller::InvokeCommandRequest(&exchangeMgr, sessionHandle, endpointId, registerClientCommand, onSuccess, onFailure); } From 5d3147c43bf961ad3c40541a9cf08b84f85803d7 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 3 Sep 2024 22:01:34 -0400 Subject: [PATCH 34/70] Start a few more helper apps as part of MTRCommissionableBrowserTests. (#35386) Lets us test that we properly see more than one thing that's commissionable. --- .../CHIPTests/MTRCommissionableBrowserTests.m | 33 ++++++++---- .../Framework/CHIPTests/MTRPairingTests.m | 2 - .../CHIPTests/TestHelpers/MTRTestCase.h | 6 +++ .../CHIPTests/TestHelpers/MTRTestCase.mm | 50 ++++++++++++++++--- .../TestHelpers/MTRTestServerAppRunner.h | 6 +++ .../TestHelpers/MTRTestServerAppRunner.m | 20 +++++++- 6 files changed, 97 insertions(+), 20 deletions(-) diff --git a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m index 6a85bfec431d7f..31ca37ffd4bc94 100644 --- a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m @@ -17,23 +17,21 @@ #import -// system dependencies -#import - +#import "MTRTestCase.h" #import "MTRTestKeys.h" +#import "MTRTestServerAppRunner.h" #import "MTRTestStorage.h" // Fixture 1: chip-all-clusters-app --KVS "$(mktemp -t chip-test-kvs)" --interface-id -1 -// Fixture 2: chip-all-clusters-app --KVS "$(mktemp -t chip-test-kvs)" --interface-id -1 \ - --dac_provider credentials/development/commissioner_dut/struct_cd_origin_pid_vid_correct/test_case_vector.json \ - --product-id 32768 --discriminator 3839 static const uint16_t kLocalPort = 5541; static const uint16_t kTestVendorId = 0xFFF1u; -static const __auto_type kTestProductIds = @[ @(0x8001u) ]; -static const __auto_type kTestDiscriminators = @[ @(3840u) ]; +static const __auto_type kTestProductIds = @[ @(0x8000u), @(0x8001u) ]; +static const __auto_type kTestDiscriminators = @[ @(2000), @(3839u), @(3840u) ]; static const uint16_t kDiscoverDeviceTimeoutInSeconds = 10; -static const uint16_t kExpectedDiscoveredDevicesCount = 1; +static const uint16_t kExpectedDiscoveredDevicesCount = 3; + +static bool sHelperAppsStarted = false; // Singleton controller we use. static MTRDeviceController * sController = nil; @@ -113,7 +111,7 @@ - (void)controller:(MTRDeviceController *)controller didRemoveCommissionableDevi } @end -@interface MTRCommissionableBrowserTests : XCTestCase +@interface MTRCommissionableBrowserTests : MTRTestCase @end @implementation MTRCommissionableBrowserTests @@ -159,6 +157,21 @@ + (void)tearDown - (void)setUp { [super setUp]; + + if (!sHelperAppsStarted) { + for (NSString * payload in @[ + @"MT:Y.K90SO527JA0648G00", + @"MT:-24J0AFN00I40648G00", + ]) { + __auto_type * appRunner = [[MTRTestServerAppRunner alloc] initCrossTestWithAppName:@"all-clusters" + arguments:@[] + payload:payload + testcase:self]; + XCTAssertNotNil(appRunner); + } + sHelperAppsStarted = true; + } + [self setContinueAfterFailure:NO]; } diff --git a/src/darwin/Framework/CHIPTests/MTRPairingTests.m b/src/darwin/Framework/CHIPTests/MTRPairingTests.m index 125c5a8253fc2e..38f7667590bca7 100644 --- a/src/darwin/Framework/CHIPTests/MTRPairingTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPairingTests.m @@ -190,8 +190,6 @@ - (void)startServerApp arguments:@[ @"--dac_provider", [self absolutePathFor:@"credentials/development/commissioner_dut/struct_cd_origin_pid_vid_correct/test_case_vector.json"], - @"--product-id", - @"32768", ] payload:kOnboardingPayload testcase:self]; diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.h index c9f20e174d5816..e3668bb90e1fca 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.h @@ -47,6 +47,12 @@ NS_ASSUME_NONNULL_BEGIN * tearDown happens. */ - (void)launchTask:(NSTask *)task; + +/** + * Launch a cross-test task. The task will be automatically terminated when the testsuite + * tearDown happens. + */ +- (void)launchCrossTestTask:(NSTask *)task; #endif // HAVE_NSTASK /** diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.mm b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.mm index e8f317eae9e1c4..fc615cc927d06b 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.mm +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.mm @@ -19,12 +19,42 @@ #import "MTRTestCase.h" +#if HAVE_NSTASK +// Tasks that are not scoped to a specific test, but rather to a specific test suite. +static NSMutableSet * runningCrossTestTasks; + +static void ClearTaskSet(NSMutableSet * __strong & tasks) +{ + for (NSTask * task in tasks) { + NSLog(@"Terminating task %@", task); + [task terminate]; + } + tasks = nil; +} +#endif // HAVE_NSTASK + @implementation MTRTestCase { #if HAVE_NSTASK NSMutableSet * _runningTasks; #endif // NSTask } ++ (void)setUp +{ + [super setUp]; + +#if HAVE_NSTASK + runningCrossTestTasks = [[NSMutableSet alloc] init]; +#endif // HAVE_NSTASK +} + ++ (void)tearDown +{ +#if HAVE_NSTASK + ClearTaskSet(runningCrossTestTasks); +#endif // HAVE_NSTASK +} + - (void)setUp { #if HAVE_NSTASK @@ -48,11 +78,7 @@ - (void)tearDown #endif #if HAVE_NSTASK - for (NSTask * task in _runningTasks) { - NSLog(@"Terminating task %@", task); - [task terminate]; - } - _runningTasks = nil; + ClearTaskSet(_runningTasks); #endif // HAVE_NSTASK [super tearDown]; @@ -76,14 +102,26 @@ - (void)runTask:(NSTask *)task XCTAssertEqual([task terminationStatus], 0); } -- (void)launchTask:(NSTask *)task +- (void)doLaunchTask:(NSTask *)task { NSError * launchError; [task launchAndReturnError:&launchError]; XCTAssertNil(launchError); +} + +- (void)launchTask:(NSTask *)task +{ + [self doLaunchTask:task]; [_runningTasks addObject:task]; } + +- (void)launchCrossTestTask:(NSTask *)task +{ + [self doLaunchTask:task]; + + [runningCrossTestTasks addObject:task]; +} #endif // HAVE_NSTASK - (NSString *)absolutePathFor:(NSString *)matterRootRelativePath diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.h index 9297b76c6fcb66..b54b7dbd78cfce 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.h @@ -45,6 +45,12 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase; +/** + * Same thing, but initialize as a "cross test" helper, which is not killed at + * the end of the current test (but is killed at the end of the current suite). + */ +- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase; + /** * Get the unique index that will be used for the next initialization. This * allows including that index in the arguments provided. diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m index 9bc9e8e168dcda..cc64d62e71d516 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m @@ -36,7 +36,7 @@ @implementation MTRTestServerAppRunner { #endif } -- (instancetype)initWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase +- (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase isCrossTest:(BOOL)isCrossTest { #if !HAVE_NSTASK XCTFail("Unable to start server app when we do not have NSTask"); @@ -75,6 +75,8 @@ - (instancetype)initWithAppName:(NSString *)name arguments:(NSArray [NSString stringWithFormat:@"%llu", passcode.unsignedLongLongValue], @"--KVS", [NSString stringWithFormat:@"/tmp/chip-%@-kvs%u", name, _uniqueIndex], + @"--product-id", + [NSString stringWithFormat:@"%u", parsedPayload.productID.unsignedShortValue], ]; __auto_type * allArguments = [forcedArguments arrayByAddingObjectsFromArray:arguments]; @@ -90,7 +92,11 @@ - (instancetype)initWithAppName:(NSString *)name arguments:(NSArray _appTask.standardOutput = [NSFileHandle fileHandleForWritingAtPath:outFile]; _appTask.standardError = [NSFileHandle fileHandleForWritingAtPath:errorFile]; - [testcase launchTask:_appTask]; + if (isCrossTest) { + [testcase launchCrossTestTask:_appTask]; + } else { + [testcase launchTask:_appTask]; + } NSLog(@"Started chip-%@-app (%@) with arguments %@ stdout=%@ and stderr=%@", name, _appTask, allArguments, outFile, errorFile); @@ -98,6 +104,16 @@ - (instancetype)initWithAppName:(NSString *)name arguments:(NSArray #endif // HAVE_NSTASK } +- (instancetype)initWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase +{ + return [self initInternalWithAppName:name arguments:arguments payload:payload testcase:testcase isCrossTest:NO]; +} + +- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase +{ + return [self initInternalWithAppName:name arguments:arguments payload:payload testcase:testcase isCrossTest:YES]; +} + + (unsigned)nextUniqueIndex { return sAppRunnerIndex; From 7ad6aa8baa4105a28a44dbc7a15fc9b35675ea8b Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Wed, 4 Sep 2024 08:01:31 +0530 Subject: [PATCH 35/70] [ESP32] Option to configure the pool allocation from heap (#30764) * [ESP32] Option to configure the system buffer pool allocation from heap * address reviews * minor adjustment to help text * some minor adjustments * Add notes regarding expected failures --- config/esp32/components/chip/Kconfig | 20 ++++++++++++++++++++ src/platform/ESP32/CHIPPlatformConfig.h | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index d3f621f98f4024..147bb97af25278 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -163,6 +163,26 @@ menu "CHIP Core" help Option to enable/disable CHIP data model. + config CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + bool "Use heap memory to allocate object pools" + default n + help + This option enables the use of heap memory to allocate object pools. + When enabled, object pools are not pre-allocated. + Additionally, the maximum number of entries that can be allocated is + only limited by the available heap memory. + + This option can be useful if you encounter static DRAM overflow. + + NOTE: Since there is no cap on pool sizes, this may lead to issues + where embedded code assumes the pool size is limited, and no other + mechanisms are in place to restrict the size of allocations. + + NOTE: If enabled and the free heap is exhausted, this may result in + undefined behavior, potential non-compliance with specifications, + or failure during certification tests. Even if it passes, it may fail + to function properly with actual controllers. + endmenu # "General Options" menu "Networking Options" diff --git a/src/platform/ESP32/CHIPPlatformConfig.h b/src/platform/ESP32/CHIPPlatformConfig.h index 82b6a6262a1e1b..24fbf7c4f1b809 100644 --- a/src/platform/ESP32/CHIPPlatformConfig.h +++ b/src/platform/ESP32/CHIPPlatformConfig.h @@ -146,3 +146,9 @@ #ifndef CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS #define CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS CONFIG_MRP_MAX_RETRANS #endif // CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS + +#ifdef CONFIG_CHIP_SYSTEM_CONFIG_POOL_USE_HEAP +#define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 1 +#else +#define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 0 +#endif From 30cff8e6e1be3be65bd3901c09f6089d4159c40a Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:28:13 -0400 Subject: [PATCH 36/70] Use persistent and subscription resumption implementation of ShouldCheckInMsgsBeSentAtActiveModeFunction by setting chip_subscription_timeout_resumption=true for Linux reference lit-icd-app (#35376) --- examples/lit-icd-app/linux/args.gni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lit-icd-app/linux/args.gni b/examples/lit-icd-app/linux/args.gni index 09ea58ef2a51d5..b1567dd6284893 100644 --- a/examples/lit-icd-app/linux/args.gni +++ b/examples/lit-icd-app/linux/args.gni @@ -28,6 +28,6 @@ matter_enable_tracing_support = true # ICD configurations chip_enable_icd_server = true -chip_subscription_timeout_resumption = false +chip_subscription_timeout_resumption = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true From 1e1fe1e62c499e348c9eda90107c9bd6e61b24f9 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:10:19 +0200 Subject: [PATCH 37/70] Integration of pw_fuzzer using FuzzTest (#34274) * latest trial to build pw_fuzz * migrating FuzzPayloadDecoder FuzzTest * fix error related to latomic * adding template for pw_fuzz_tests * fix for linux_sysroot issue * adding FuzzTests * fixing warning issue * adding support to build pw-fuzztests with build_examples.py * Restyled by whitespace * Restyled by clang-format * adding pw_fuzz_tests to default target * fixing build_examples test golden standard * Adding Fuzzing Targets * Adding Documentation * cleaning-up tests * spelling mistakes * integrating comments --------- Co-authored-by: Restyled.io --- .github/.wordlist.txt | 3 + .gitmodules | 16 ++ BUILD.gn | 16 ++ build/chip/fuzz_test.gni | 59 +++++++ build/toolchain/pw_fuzzer/BUILD.gn | 70 ++++++++ docs/guides/BUILDING.md | 20 +++ docs/testing/fuzz_testing.md | 157 ++++++++++++++++++ scripts/build/build/targets.py | 4 + scripts/build/builders/host.py | 6 + .../build/testdata/all_targets_linux_x64.txt | 4 +- src/credentials/tests/BUILD.gn | 10 ++ src/credentials/tests/FuzzChipCertPW.cpp | 95 +++++++++++ src/lib/core/tests/BUILD.gn | 10 ++ src/lib/core/tests/FuzzTlvReaderPW.cpp | 35 ++++ src/lib/dnssd/minimal_mdns/tests/BUILD.gn | 10 ++ .../tests/FuzzPacketParsingPW.cpp | 132 +++++++++++++++ src/lib/format/tests/BUILD.gn | 15 ++ src/lib/format/tests/FuzzPayloadDecoderPW.cpp | 73 ++++++++ src/setup_payload/tests/BUILD.gn | 10 ++ src/setup_payload/tests/FuzzBase38PW.cpp | 77 +++++++++ third_party/abseil-cpp/src | 1 + third_party/fuzztest | 1 + third_party/googletest | 1 + third_party/re2/src | 1 + 24 files changed, 824 insertions(+), 2 deletions(-) create mode 100644 build/toolchain/pw_fuzzer/BUILD.gn create mode 100644 docs/testing/fuzz_testing.md create mode 100644 src/credentials/tests/FuzzChipCertPW.cpp create mode 100644 src/lib/core/tests/FuzzTlvReaderPW.cpp create mode 100644 src/lib/dnssd/minimal_mdns/tests/FuzzPacketParsingPW.cpp create mode 100644 src/lib/format/tests/FuzzPayloadDecoderPW.cpp create mode 100644 src/setup_payload/tests/FuzzBase38PW.cpp create mode 160000 third_party/abseil-cpp/src create mode 160000 third_party/fuzztest create mode 160000 third_party/googletest create mode 160000 third_party/re2/src diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 153345827ee086..4444d8299d26cb 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -37,6 +37,7 @@ AdvSendAdvert AE aef AES +AFL AIDL algs alloc @@ -570,6 +571,7 @@ fsync ftd fullclean fuzzer +fuzztest FW gbl gcloud @@ -1008,6 +1010,7 @@ optionOverride optionsMask optionsOverride orgs +OSS OTA OTADownloader otaDownloadPath diff --git a/.gitmodules b/.gitmodules index 78a6cabb940d05..40801ec9742517 100644 --- a/.gitmodules +++ b/.gitmodules @@ -329,3 +329,19 @@ path = third_party/infineon/psoc6/psoc6_sdk/libs/lwip-network-interface-integration url = https://github.com/Infineon/lwip-network-interface-integration.git platforms = infineon +[submodule "third_party/abseil-cpp/src"] + path = third_party/abseil-cpp/src + url = https://github.com/abseil/abseil-cpp.git + platforms = linux,darwin +[submodule "third_party/fuzztest"] + path = third_party/fuzztest + url = https://github.com/google/fuzztest.git + platforms = linux,darwin +[submodule "third_party/googletest"] + path = third_party/googletest + url = https://github.com/google/googletest + platforms = linux,darwin +[submodule "third_party/re2/src"] + path = third_party/re2/src + url = https://github.com/google/re2.git + platforms = linux,darwin diff --git a/BUILD.gn b/BUILD.gn index c8e41976599173..4efa25007aa523 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -62,6 +62,18 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { } } + if (pw_enable_fuzz_test_targets) { + group("pw_fuzz_tests") { + deps = [ + "${chip_root}/src/credentials/tests:fuzz-chip-cert-pw(//build/toolchain/pw_fuzzer:chip_pw_fuzztest)", + "${chip_root}/src/lib/core/tests:fuzz-tlv-reader-pw(//build/toolchain/pw_fuzzer:chip_pw_fuzztest)", + "${chip_root}/src/lib/dnssd/minimal_mdns/tests:fuzz-minmdns-packet-parsing-pw(//build/toolchain/pw_fuzzer:chip_pw_fuzztest)", + "${chip_root}/src/lib/format/tests:fuzz-payload-decoder-pw(//build/toolchain/pw_fuzzer:chip_pw_fuzztest)", + "${chip_root}/src/setup_payload/tests:fuzz-setup-payload-base38-pw(//build/toolchain/pw_fuzzer:chip_pw_fuzztest)", + ] + } + } + # Matter's in-tree pw_python_package or pw_python_distribution targets. _matter_python_packages = [ "//examples/chef", @@ -140,6 +152,10 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { deps += [ "//:fuzz_tests" ] } + if (pw_enable_fuzz_test_targets) { + deps += [ "//:pw_fuzz_tests" ] + } + if (chip_device_platform != "none") { deps += [ "${chip_root}/src/app/server" ] } diff --git a/build/chip/fuzz_test.gni b/build/chip/fuzz_test.gni index 784ed60273b02a..98def1dab0463d 100644 --- a/build/chip/fuzz_test.gni +++ b/build/chip/fuzz_test.gni @@ -14,12 +14,17 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + import("${build_root}/config/compiler/compiler.gni") import("${chip_root}/build/chip/tests.gni") +import("${dir_pw_unit_test}/test.gni") declare_args() { enable_fuzz_test_targets = is_clang && chip_build_tests && (current_os == "linux" || current_os == "mac") + + pw_enable_fuzz_test_targets = false } # Define a fuzz target for chip. @@ -66,3 +71,57 @@ template("chip_fuzz_target") { } } } + +# Define a fuzz target for Matter using pw_fuzzer and Google FuzzTest Framework. +# +# Google FuzzTest is only supported on Linux and MacOS using Clang: +# +# Sample usage +# +# chip_pw_fuzz_target("fuzz-target-name") { +# test_source = [ +# "FuzzTarget.cpp", # Fuzz target +# ] +# +# public_deps = [ +# "${chip_root}/src/lib/foo", # add dependencies here +# ] +# } +# +# +template("chip_pw_fuzz_target") { + if (defined(invoker.test_source)) { + _test_output_dir = "${root_out_dir}/tests" + + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } + + pw_test(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + "remove_configs", + ]) + + # TODO: remove this after pw_fuzzer's integration with OSS-Fuzz is complete. + #just a test for running FuzzTest with libfuzzer-compatibility mode, since this is the mode supported by OSS-fuzz + # defines = [ + # "FUZZTEST_COMPATIBILITY_MODE=libfuzzer", + # "MAKE_BUILD_TYPE=RelWithDebug", + # ] + + sources = invoker.test_source + output_dir = _test_output_dir + + deps = [ "$dir_pw_fuzzer:fuzztest" ] + + # this is necessary so FuzzTest is compiled into an executable in third_party/pigweed/repo/pw_unit_test/test.gni + # otherwise it will be built successfully but with FuzzTarget.DISABLED.ninja and no executable. + enable_if = true + } + } +} diff --git a/build/toolchain/pw_fuzzer/BUILD.gn b/build/toolchain/pw_fuzzer/BUILD.gn new file mode 100644 index 00000000000000..385e57cc81be39 --- /dev/null +++ b/build/toolchain/pw_fuzzer/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/pigweed.gni") + +import("$dir_pigweed/targets/host/target_toolchains.gni") +import("${build_root}/toolchain/gcc_toolchain.gni") + +# creating a secondary toolchain to be used with pw_fuzzer FuzzTests +# This toolchain is downstreamed from pigweed's pw_target_toolchain_host.clang_fuzz +# it allows us to specifically use googletest for fuzzing (instead of the lighter version of googletest used for unit testing) + +gcc_toolchain("chip_pw_fuzztest") { + forward_variables_from(pw_target_toolchain_host.clang_fuzz, "*", [ "name" ]) + + toolchain_args = { + # This is needed to have the defaults passed from pw_target_toolchain_host.clang_fuzz to the current scope + forward_variables_from(defaults, "*") + + pw_unit_test_MAIN = "$dir_pw_fuzzer:fuzztest_main" + pw_unit_test_BACKEND = "$dir_pw_fuzzer:gtest" + + # The next three lines are needed by the gcc_toolchain template + current_os = host_os + current_cpu = host_cpu + is_clang = true + + # the upstream pigweed host_clang toolchain defines a default sysroot, which results in build errors + # since it does not include SSL lib and is supposed to be minimal by design. + # by removing this default config, we will use the system's libs. Otherwise we can define our own sysroot. + # discussion on: https://discord.com/channels/691686718377558037/1275092695764959232 + remove_default_configs = [ "$dir_pw_toolchain/host_clang:linux_sysroot" ] + + # when is_debug = true, we pass -O0 to cflags and ldflags, while upstream pw_fuzzer toolchain defines "optimize_speed" config that passes -O2. + # This condition was added to prevent mixing the flags + if (is_debug) { + remove_default_configs += [ "$dir_pw_build:optimize_speed" ] + } + + # removing pigweed downstreamed configs related to warnings + # These are triggering an error related to -Wcast-qual in third_party/nlio + remove_default_configs += [ + "$dir_pw_build:strict_warnings", + "$dir_pw_build:extra_strict_warnings", + ] + + # the third_party abseil-cpp triggers warnings related to [-Wformat-nonliteral] + treat_warnings_as_errors = false + + dir_pw_third_party_abseil_cpp = "//third_party/abseil-cpp/src" + dir_pw_third_party_fuzztest = "//third_party/fuzztest" + dir_pw_third_party_googletest = "//third_party/googletest" + + # TODO: Seems that re2 support within FuzzTest was deprecated, keeping it defined is triggering warning + # Remove if re2 is indeed not needed + # dir_pw_third_party_re2 = "//third_party/re2/src" + } +} diff --git a/docs/guides/BUILDING.md b/docs/guides/BUILDING.md index 7cd660227ed165..941b5328887e31 100644 --- a/docs/guides/BUILDING.md +++ b/docs/guides/BUILDING.md @@ -382,6 +382,26 @@ They pick up environment variables such as `$CFLAGS`, `$CXXFLAGS` and You likely want `libfuzzer` + `asan` builds instead for local testing. +### `pw_fuzzer` `FuzzTests` + +An Alternative way for writing and running Fuzz Tests is Google's `FuzzTest` +framework, integrated through `pw_fuzzer`. The Tests will have to be built and +executed manually. + +``` +./scripts/build/build_examples.py --target linux-x64-tests-clang-pw-fuzztest build +``` + +NOTE: `asan` is enabled by default in FuzzTest, so please do not add it in +build_examples.py invocation. + +Tests will be located in: +`out/linux-x64-tests-clang-pw-fuzztest/chip_pw_fuzztest/tests/` where +`chip_pw_fuzztest` is the name of the toolchain used. + +- Details on How To Run Fuzz Tests in + [Running FuzzTests](https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/fuzz_testing.md) + ## Build custom configuration The build is configured by setting build arguments. These you can set in one of diff --git a/docs/testing/fuzz_testing.md b/docs/testing/fuzz_testing.md new file mode 100644 index 00000000000000..b7faeae463a10e --- /dev/null +++ b/docs/testing/fuzz_testing.md @@ -0,0 +1,157 @@ +# Fuzz testing + +- Fuzz Testing involves providing random and unexpected data as input to + functions and methods to uncover bugs, security vulnerabilities, or to + determine if the software crashes. +- it is often continuous; the function under test is called in iteration with + thousands of different inputs. +- Fuzz testing is often done with sanitizers enabled; to catch memory errors + and undefined behavior. +- The most commonly used fuzz testing frameworks for C/C++ are LibFuzzer and + AFL. +- [Google's FuzzTest](https://github.com/google/fuzztest) is a newer framework + that simplifies writing fuzz tests with user-friendly APIs and offers more + control over input generation. It also integrates seamlessly with Google + Test (GTest). + +## `Google's FuzzTest` + +- Google FuzzTest is integrated through Pigweed + [pw_fuzzer](https://pigweed.dev/pw_fuzzer/concepts.html). + +### Use cases + +1. Finding Undefined Behavior with Sanitizers: + + - Running fuzz tests while checking if a crash or other sanitizer-detected + error occurs, allowing detection of subtle memory issues like buffer + overflows and use-after-free errors. + +2. Find Correctness Bugs using Assertions: + - For example, in Round trip Fuzzing, fuzzed input is encoded, decoded, and + then verified to match the original input. An example of this can be found + in src/setup_payload/tests/FuzzBase38PW.cpp. + +- More information can be found in the + [FuzzTest Use Cases](https://github.com/google/fuzztest/blob/main/doc/use-cases.md) + documentation. + +### Writing FuzzTests + +Keywords: Property Function, Input Domain + +- FuzzTests are instantiated through the macro call of `FUZZ_TEST`: + +```cpp +FUZZ_TEST(TLVReader, FuzzTlvReader).WithDomains(fuzztest::Arbitrary>()); +``` + +- The Macro invocation calls the **Property Function**, which is + `FuzzTlvReader` above. + +- The **input domains** define the range and type of inputs that the + **property function** will receive during fuzzing, specified using the + `.WithDomains()` clause. +- In the macro above, FuzzTest will generate a wide range of possible byte + vectors to thoroughly test the `FuzzTlvReader` function. + +#### The Property Function + +```cpp +// The Property Function +void FuzzTlvRead(const std::vector & bytes) +{ + TLVReader reader; + reader.Init(bytes.data(), bytes.size()); + chip::TLV::Utilities::Iterate(reader, FuzzIterator, nullptr); +} +``` + +- The Property Functions must return a `void` +- The function will be run with many different inputs in the same process, + trying to trigger a crash. +- It is possible to include Assertions such as during Round-Trip Fuzzing + +- More Information: + https://github.com/google/fuzztest/blob/main/doc/fuzz-test-macro.md#the-property-function + +#### Input Domains + +- FuzzTest Offers many Input Domains, all of which are part of the + `fuzztest::` namespace. +- All native C++ types can be used through `Arbitrary()`: + +```cpp +FUZZ_TEST(Base38Decoder, FuzzQRCodeSetupPayloadParser).WithDomains(Arbitrary()); +``` + +- using vector domains is one of the most common. It is possible to limit the + size of the input vectors (or any container domain) using `.WithMaxSize()` + or `.WithMinSize()`, as shown below: + +```cpp +FUZZ_TEST(MinimalmDNS, TxtResponderFuzz).WithDomains(Arbitrary>().WithMaxSize(254)); +``` + +- `ElementOf` is particularly useful as it allows us to define a domain by + explicitly enumerating the set of values in it and passing it to FuzzTest + invocation. Example: + +```cpp +auto AnyProtocolID() +{ + return ElementOf({ chip::Protocols::SecureChannel::Id, chip::Protocols::InteractionModel::Id, chip::Protocols::BDX::Id, + chip::Protocols::UserDirectedCommissioning::Id }); +} + +FUZZ_TEST(PayloadDecoder, RunDecodeFuzz).WithDomains(Arbitrary>(), AnyProtocolID(), Arbitrary()); +``` + +- A detailed reference for input domains can be found here: + [FuzzTest Domain Reference](https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#elementof-domains-element-of). + +### Running FuzzTests + +There are several ways to run the tests: + +1. Unit-test mode (where the inputs are only fuzzed for a second): + +```bash +./fuzz-chip-cert-pw +``` + +2. Continuous fuzzing mode; we need to first list the tests, then specify the + FuzzTestCase to run: + +```bash +$ ./fuzz-chip-cert-pw --list_fuzz_tests +[.] Sanitizer coverage enabled. Counter map size: 11134, Cmp map size: 262144 +[*] Fuzz test: ChipCert.ChipCertFuzzer +[*] Fuzz test: ChipCert.DecodeChipCertFuzzer + +$ ./fuzz-chip-cert-pw --fuzz=ChipCert.DecodeChipCertFuzzer +``` + +3. Running all Tests in a TestSuite for a specific time, e.g for 10 minutes + +```bash +#both Fuzz Tests will be run for 10 minutes each +./fuzz-chip-cert-pw --fuzz_for=10m +``` + +4. For Help + +```bash +# FuzzTest related help +./fuzz-chip-cert-pw --helpfull + +# gtest related help +./fuzz-chip-cert-pw --help + +``` + +#### TO ADD: + +- More Information on Test Fixtures (After issues are resolved) +- How to add FuzzTests to the Build System +- More Information on OSS-FUZZ diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index efb66120ebd97b..378a286f5bf5a4 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -77,6 +77,8 @@ def BuildHostFakeTarget(): "-clang").ExceptIfRe('-ossfuzz') target.AppendModifier("ossfuzz", fuzzing_type=HostFuzzingType.OSS_FUZZ).OnlyIfRe( "-clang").ExceptIfRe('-libfuzzer') + target.AppendModifier("pw-fuzztest", fuzzing_type=HostFuzzingType.PW_FUZZTEST).OnlyIfRe( + "-clang").ExceptIfRe('-(libfuzzer|ossfuzz|asan)') target.AppendModifier('coverage', use_coverage=True).OnlyIfRe( '-(chip-tool|all-clusters)') target.AppendModifier('dmalloc', use_dmalloc=True) @@ -178,6 +180,8 @@ def BuildHostTarget(): "-clang").ExceptIfRe('-ossfuzz') target.AppendModifier("ossfuzz", fuzzing_type=HostFuzzingType.OSS_FUZZ).OnlyIfRe( "-clang").ExceptIfRe('-libfuzzer') + target.AppendModifier("pw-fuzztest", fuzzing_type=HostFuzzingType.PW_FUZZTEST).OnlyIfRe( + "-clang").ExceptIfRe('-(libfuzzer|ossfuzz|asan)') target.AppendModifier('coverage', use_coverage=True).OnlyIfRe( '-(chip-tool|all-clusters|tests)') target.AppendModifier('dmalloc', use_dmalloc=True) diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index c51a8ee88cb0ee..b69421a782e948 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -42,6 +42,7 @@ class HostFuzzingType(Enum): NONE = auto() LIB_FUZZER = auto() OSS_FUZZ = auto() + PW_FUZZTEST = auto() class HostApp(Enum): @@ -379,6 +380,8 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, self.extra_gn_options.append('is_libfuzzer=true') elif fuzzing_type == HostFuzzingType.OSS_FUZZ: self.extra_gn_options.append('oss_fuzz=true') + elif fuzzing_type == HostFuzzingType.PW_FUZZTEST: + self.extra_gn_options.append('pw_enable_fuzz_test_targets=true') if imgui_ui: self.extra_gn_options.append('chip_examples_enable_imgui_ui=true') @@ -468,6 +471,9 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, if self.app == HostApp.TESTS and fuzzing_type != HostFuzzingType.NONE: self.build_command = 'fuzz_tests' + if self.app == HostApp.TESTS and fuzzing_type == HostFuzzingType.PW_FUZZTEST: + self.build_command = 'pw_fuzz_tests' + def GnBuildArgs(self): if self.board == HostBoard.NATIVE: return self.extra_gn_options diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 3c5b29050621fe..07b409c75b3b53 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -8,8 +8,8 @@ cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw9307 efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,brd4187c,brd4186c,brd2703a,brd4338a}-{window-covering,switch,unit-test,light,lock,thermostat,pump}[-rpc][-with-ota-requestor][-icd][-low-power][-shell][-no-logging][-openthread-mtd][-heap-monitoring][-no-openthread-cli][-show-qr-code][-wifi][-rs9116][-wf200][-siwx917][-ipv4][-additional-data-advertising][-use-ot-lib][-use-ot-coap-lib][-no-version][-skip-rps-generation] esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing] genio-lighting-app -linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang] -linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled] +linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang] +linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 393b246ef20ee3..46e1f724349102 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -84,3 +84,13 @@ if (enable_fuzz_test_targets) { ] } } + +if (pw_enable_fuzz_test_targets) { + chip_pw_fuzz_target("fuzz-chip-cert-pw") { + test_source = [ "FuzzChipCertPW.cpp" ] + public_deps = [ + "${chip_root}/src/credentials", + "${chip_root}/src/platform/logging:default", + ] + } +} diff --git a/src/credentials/tests/FuzzChipCertPW.cpp b/src/credentials/tests/FuzzChipCertPW.cpp new file mode 100644 index 00000000000000..bb929b392500d7 --- /dev/null +++ b/src/credentials/tests/FuzzChipCertPW.cpp @@ -0,0 +1,95 @@ +#include +#include + +#include +#include + +#include "credentials/CHIPCert.h" + +namespace { + +using namespace chip; +using namespace chip::Credentials; + +using namespace fuzztest; + +void ChipCertFuzzer(const std::vector & bytes) +{ + ByteSpan span(bytes.data(), bytes.size()); + + { + NodeId nodeId; + FabricId fabricId; + (void) ExtractFabricIdFromCert(span, &fabricId); + (void) ExtractNodeIdFabricIdFromOpCert(span, &nodeId, &fabricId); + } + + { + CATValues cats; + (void) ExtractCATsFromOpCert(span, cats); + } + + { + Credentials::P256PublicKeySpan key; + (void) ExtractPublicKeyFromChipCert(span, key); + } + + { + chip::System::Clock::Seconds32 rcacNotBefore; + (void) ExtractNotBeforeFromChipCert(span, rcacNotBefore); + } + + { + Credentials::CertificateKeyId skid; + (void) ExtractSKIDFromChipCert(span, skid); + } + + { + ChipDN subjectDN; + (void) ExtractSubjectDNFromChipCert(span, subjectDN); + } + + { + uint8_t outCertBuf[kMaxDERCertLength]; + MutableByteSpan outCert(outCertBuf); + (void) ConvertChipCertToX509Cert(span, outCert); + } + + { + // TODO: #35369 Move this to a Fixture once Errors related to FuzzTest Fixtures are resolved + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + ValidateChipRCAC(span); + chip::Platform::MemoryShutdown(); + } +} + +FUZZ_TEST(FuzzChipCert, ChipCertFuzzer).WithDomains(Arbitrary>()); + +// The Property function for DecodeChipCertFuzzer, The FUZZ_TEST Macro will call this function. +void DecodeChipCertFuzzer(const std::vector & bytes, BitFlags aDecodeFlag) +{ + ByteSpan span(bytes.data(), bytes.size()); + + // TODO: #34352 To Move this to a Fixture once Errors related to FuzzTest Fixtures are resolved + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + + ChipCertificateData certData; + (void) DecodeChipCert(span, certData, aDecodeFlag); + + chip::Platform::MemoryShutdown(); +} + +// This function allows us to fuzz using one of three CertDecodeFlags flags; by using FuzzTests's `ElementOf` API, we define an +// input domain by explicitly enumerating the set of values in it More Info: +// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#elementof-domains-element-of +auto AnyCertDecodeFlag() +{ + constexpr BitFlags NullDecodeFlag; + constexpr BitFlags GenTBSHashFlag(CertDecodeFlags::kGenerateTBSHash); + constexpr BitFlags TrustAnchorFlag(CertDecodeFlags::kIsTrustAnchor); + + return ElementOf({ NullDecodeFlag, GenTBSHashFlag, TrustAnchorFlag }); +} + +FUZZ_TEST(FuzzChipCert, DecodeChipCertFuzzer).WithDomains(Arbitrary>(), AnyCertDecodeFlag()); +} // namespace diff --git a/src/lib/core/tests/BUILD.gn b/src/lib/core/tests/BUILD.gn index eb17707dec1755..264de2c8aafe6b 100644 --- a/src/lib/core/tests/BUILD.gn +++ b/src/lib/core/tests/BUILD.gn @@ -59,3 +59,13 @@ if (enable_fuzz_test_targets) { ] } } + +if (pw_enable_fuzz_test_targets) { + chip_pw_fuzz_target("fuzz-tlv-reader-pw") { + test_source = [ "FuzzTlvReaderPW.cpp" ] + public_deps = [ + "${chip_root}/src/lib/core", + "${chip_root}/src/platform/logging:default", + ] + } +} diff --git a/src/lib/core/tests/FuzzTlvReaderPW.cpp b/src/lib/core/tests/FuzzTlvReaderPW.cpp new file mode 100644 index 00000000000000..4296cac3cffb02 --- /dev/null +++ b/src/lib/core/tests/FuzzTlvReaderPW.cpp @@ -0,0 +1,35 @@ + +#include +#include + +#include +#include + +#include "lib/core/TLV.h" +#include "lib/core/TLVUtilities.h" + +namespace { + +using chip::TLV::TLVReader; + +using namespace fuzztest; + +static CHIP_ERROR FuzzIterator(const TLVReader & aReader, size_t aDepth, void * aContext) +{ + aReader.GetLength(); + aReader.GetTag(); + aReader.GetType(); + return CHIP_NO_ERROR; +} + +// The Property Function +void FuzzTlvReader(const std::vector & bytes) +{ + TLVReader reader; + reader.Init(bytes.data(), bytes.size()); + chip::TLV::Utilities::Iterate(reader, FuzzIterator, nullptr); +} +// Fuzz tests are instantiated with the FUZZ_TEST macro +FUZZ_TEST(TLVReader, FuzzTlvReader).WithDomains(Arbitrary>()); + +} // namespace diff --git a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn index 47e83650d41acc..457c11ee688b94 100644 --- a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn @@ -53,3 +53,13 @@ if (enable_fuzz_test_targets) { ] } } + +if (pw_enable_fuzz_test_targets) { + chip_pw_fuzz_target("fuzz-minmdns-packet-parsing-pw") { + test_source = [ "FuzzPacketParsingPW.cpp" ] + public_deps = [ + "${chip_root}/src/lib/dnssd/minimal_mdns", + "${chip_root}/src/platform/logging:default", + ] + } +} diff --git a/src/lib/dnssd/minimal_mdns/tests/FuzzPacketParsingPW.cpp b/src/lib/dnssd/minimal_mdns/tests/FuzzPacketParsingPW.cpp new file mode 100644 index 00000000000000..aec550b26e026a --- /dev/null +++ b/src/lib/dnssd/minimal_mdns/tests/FuzzPacketParsingPW.cpp @@ -0,0 +1,132 @@ +#include +#include + +#include +#include + +#include +#include + +namespace { + +using namespace fuzztest; +using namespace std; + +using namespace chip; +using namespace mdns::Minimal; + +class FuzzDelegate : public ParserDelegate +{ +public: + FuzzDelegate(const mdns::Minimal::BytesRange & packet) : mPacketRange(packet) {} + virtual ~FuzzDelegate() {} + + void OnHeader(ConstHeaderRef & header) override {} + void OnQuery(const QueryData & data) override {} + void OnResource(ResourceType type, const ResourceData & data) override + { + switch (data.GetType()) + { + case QType::SRV: { + mdns::Minimal::SrvRecord srv; + (void) srv.Parse(data.GetData(), mPacketRange); + break; + } + case QType::A: { + chip::Inet::IPAddress addr; + (void) mdns::Minimal::ParseARecord(data.GetData(), &addr); + break; + } + case QType::AAAA: { + chip::Inet::IPAddress addr; + (void) mdns::Minimal::ParseAAAARecord(data.GetData(), &addr); + break; + } + case QType::PTR: { + mdns::Minimal::SerializedQNameIterator name; + (void) mdns::Minimal::ParsePtrRecord(data.GetData(), mPacketRange, &name); + break; + } + default: + // nothing to do + break; + } + } + +private: + mdns::Minimal::BytesRange mPacketRange; +}; + +void PacketParserFuzz(const std::vector & bytes) +{ + BytesRange packet(bytes.data(), bytes.data() + bytes.size()); + FuzzDelegate delegate(packet); + + mdns::Minimal::ParsePacket(packet, &delegate); +} + +FUZZ_TEST(MinimalmDNS, PacketParserFuzz).WithDomains(Arbitrary>()); + +class TxtRecordAccumulator : public TxtRecordDelegate +{ +public: + using DataType = vector>; + + void OnRecord(const BytesRange & name, const BytesRange & value) override + { + mData.push_back(make_pair(AsString(name), AsString(value))); + } + + DataType & Data() { return mData; } + const DataType & Data() const { return mData; } + +private: + DataType mData; + + static string AsString(const BytesRange & range) + { + return string(reinterpret_cast(range.Start()), reinterpret_cast(range.End())); + } +}; + +// The Property Function +void TxtResponderFuzz(const std::vector & aRecord) +{ + + bool equal_sign_present = false; + auto equal_sign_pos = aRecord.end(); + + // This test is only giving a set of values, it can be gives more + vector prefixedRecord{ static_cast(aRecord.size()) }; + + prefixedRecord.insert(prefixedRecord.end(), aRecord.begin(), aRecord.end()); + + TxtRecordAccumulator accumulator; + + // The Function under Test, Check that the function does not Crash + ParseTxtRecord(BytesRange(prefixedRecord.data(), (&prefixedRecord.back() + 1)), &accumulator); + + for (auto it = aRecord.begin(); it != aRecord.end(); it++) + { + // if this is first `=` found in the fuzzed record + if ('=' == static_cast(*it) && false == equal_sign_present) + { + equal_sign_present = true; + equal_sign_pos = it; + } + } + + // The Fuzzed Input (record) needs to have at least two characters in order for ParseTxtRecord to do something + if (aRecord.size() > 1) + { + if (true == equal_sign_present) + { + std::string input_record_value(equal_sign_pos + 1, aRecord.end()); + EXPECT_EQ(accumulator.Data().at(0).second, input_record_value); + } + } +} + +FUZZ_TEST(MinimalmDNS, TxtResponderFuzz).WithDomains(Arbitrary>().WithMaxSize(254)); + +} // namespace diff --git a/src/lib/format/tests/BUILD.gn b/src/lib/format/tests/BUILD.gn index 840a2eede60c78..1ce417ea91cdc3 100644 --- a/src/lib/format/tests/BUILD.gn +++ b/src/lib/format/tests/BUILD.gn @@ -57,3 +57,18 @@ if (enable_fuzz_test_targets) { ] } } + +if (pw_enable_fuzz_test_targets) { + chip_pw_fuzz_target("fuzz-payload-decoder-pw") { + test_source = [ "FuzzPayloadDecoderPW.cpp" ] + public_deps = [ + "${chip_root}/src/controller/data_model:cluster-tlv-metadata", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/format:flat-tree", + "${chip_root}/src/lib/format:protocol-decoder", + "${chip_root}/src/lib/format:protocol-tlv-metadata", + "${chip_root}/src/lib/support", + "${chip_root}/src/platform/logging:stdio", + ] + } +} diff --git a/src/lib/format/tests/FuzzPayloadDecoderPW.cpp b/src/lib/format/tests/FuzzPayloadDecoderPW.cpp new file mode 100644 index 00000000000000..52b51b308d0c2a --- /dev/null +++ b/src/lib/format/tests/FuzzPayloadDecoderPW.cpp @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace { + +using namespace chip::Decoders; +using namespace chip::FlatTree; +using namespace chip::TLV; +using namespace chip::TLVMeta; +using namespace fuzztest; + +// The Property Function; The FUZZ_TEST macro will call this function, with the fuzzed input domains +void RunDecodeFuzz(const std::vector & bytes, chip::Protocols::Id mProtocol, uint8_t mMessageType) +{ + + PayloadDecoderInitParams params; + params.SetProtocolDecodeTree(chip::TLVMeta::protocols_meta).SetClusterDecodeTree(chip::TLVMeta::clusters_meta); + + // Fuzzing with different Protocols + params.SetProtocol(mProtocol); + + // Fuzzing with different MessageTypes + params.SetMessageType(mMessageType); + chip::Decoders::PayloadDecoder<64, 128> decoder(params); + + chip::ByteSpan payload(bytes.data(), bytes.size()); + + decoder.StartDecoding(payload); + + PayloadEntry entry; + while (decoder.Next(entry)) + { + // Nothing to do ... + } +} + +// This function allows us to fuzz using one of four protocols; by using FuzzTests's `ElementOf` API, we define an +// input domain by explicitly enumerating the set of values in it More Info: +// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#elementof-domains-element-of +auto AnyProtocolID() +{ + return ElementOf({ chip::Protocols::SecureChannel::Id, chip::Protocols::InteractionModel::Id, chip::Protocols::BDX::Id, + chip::Protocols::UserDirectedCommissioning::Id }); +} + +FUZZ_TEST(PayloadDecoder, RunDecodeFuzz).WithDomains(Arbitrary>(), AnyProtocolID(), Arbitrary()); + +} // namespace diff --git a/src/setup_payload/tests/BUILD.gn b/src/setup_payload/tests/BUILD.gn index 75cdb8a71b0ad3..fc7bd6fe13c83c 100644 --- a/src/setup_payload/tests/BUILD.gn +++ b/src/setup_payload/tests/BUILD.gn @@ -56,3 +56,13 @@ if (enable_fuzz_test_targets) { ] } } + +if (pw_enable_fuzz_test_targets) { + chip_pw_fuzz_target("fuzz-setup-payload-base38-pw") { + test_source = [ "FuzzBase38PW.cpp" ] + public_deps = [ + "${chip_root}/src/platform/logging:stdio", + "${chip_root}/src/setup_payload", + ] + } +} diff --git a/src/setup_payload/tests/FuzzBase38PW.cpp b/src/setup_payload/tests/FuzzBase38PW.cpp new file mode 100644 index 00000000000000..b39db0905dfea0 --- /dev/null +++ b/src/setup_payload/tests/FuzzBase38PW.cpp @@ -0,0 +1,77 @@ +#include +#include +#include + +#include +#include + +#include "setup_payload/QRCodeSetupPayloadParser.h" +#include +#include + +namespace { + +using namespace fuzztest; +using namespace chip; + +// The property Function +void Base38DecodeFuzz(const std::vector & bytes) +{ + std::string base38EncodedString(reinterpret_cast(bytes.data()), bytes.size()); + std::vector decodedData; + + // Ignoring return value, because in general the data is garbage and won't decode properly. + // We're just testing that the decoder does not crash on the fuzzer-generated inputs. + chip::base38Decode(base38EncodedString, decodedData); +} + +// The invocation of the FuzzTest +FUZZ_TEST(Base38Decoder, Base38DecodeFuzz).WithDomains(Arbitrary>()); + +/* The property function for a base38 roundtrip Fuzzer. + * It starts by encoding the fuzzing value passed + * into Base38. The encoded value will then be decoded. + * + * The fuzzer verifies that the decoded value is the same + * as the one in input.*/ +void Base38RoundTripFuzz(const std::vector & bytes) +{ + + size_t outputSizeNeeded = base38EncodedLength(bytes.size()); + const size_t kMaxOutputSize = 512; + + ASSERT_LT(outputSizeNeeded, kMaxOutputSize); + + ByteSpan span(bytes.data(), bytes.size()); + + char encodedBuf[kMaxOutputSize]; + MutableCharSpan encodedSpan(encodedBuf); + CHIP_ERROR encodingError = base38Encode(span, encodedSpan); + ASSERT_EQ(encodingError, CHIP_NO_ERROR); + + std::string base38EncodedString(encodedSpan.data(), encodedSpan.size()); + + std::vector decodedData; + CHIP_ERROR decodingError = base38Decode(base38EncodedString, decodedData); + + ASSERT_EQ(decodingError, CHIP_NO_ERROR); + + // Make sure that decoded data is equal to the original fuzzed input; the bytes vector + ASSERT_EQ(decodedData, bytes); +} + +// Max size of the vector is defined as 306 since that will give an outputSizeNeeded of 511 which is less than the required +// kMaxOutputSize +FUZZ_TEST(Base38Decoder, Base38RoundTripFuzz).WithDomains(Arbitrary>().WithMaxSize(306)); + +void FuzzQRCodeSetupPayloadParser(const std::string & s) +{ + chip::Platform::MemoryInit(); + + SetupPayload payload; + QRCodeSetupPayloadParser(s).populatePayload(payload); +} + +FUZZ_TEST(Base38Decoder, FuzzQRCodeSetupPayloadParser).WithDomains(Arbitrary()); + +} // namespace diff --git a/third_party/abseil-cpp/src b/third_party/abseil-cpp/src new file mode 160000 index 00000000000000..3ab97e7212bff9 --- /dev/null +++ b/third_party/abseil-cpp/src @@ -0,0 +1 @@ +Subproject commit 3ab97e7212bff931a201c794fa1331960158bbfa diff --git a/third_party/fuzztest b/third_party/fuzztest new file mode 160000 index 00000000000000..6eb010c7223a6a --- /dev/null +++ b/third_party/fuzztest @@ -0,0 +1 @@ +Subproject commit 6eb010c7223a6aa609b94d49bfc06ac88f922961 diff --git a/third_party/googletest b/third_party/googletest new file mode 160000 index 00000000000000..1d17ea141d2c11 --- /dev/null +++ b/third_party/googletest @@ -0,0 +1 @@ +Subproject commit 1d17ea141d2c11b8917d2c7d029f1c4e2b9769b2 diff --git a/third_party/re2/src b/third_party/re2/src new file mode 160000 index 00000000000000..85dd7ad833a730 --- /dev/null +++ b/third_party/re2/src @@ -0,0 +1 @@ +Subproject commit 85dd7ad833a73095ecf3e3baea608ba051bbe2c7 From 5d9b14522afc1e91f0bba78d6addd989f55f9ce6 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:37:51 +0200 Subject: [PATCH 38/70] Stop VSCode from Formatting .gitmodules file on save (#35373) * Stop VSCode from running Formatter on .gitmodules * associating .gitmodules with ini instead of plaintext --- .vscode/settings.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 33bdd5e9f63d6f..fe0c4be3f84155 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -50,6 +50,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "files.associations": { + ".gitmodules": "ini", "*.mm": "cpp", "iostream": "cpp", "array": "cpp", @@ -138,6 +139,9 @@ "list": "cpp", "unordered_set": "cpp" }, + "[ini]": { + "editor.formatOnSave": false + }, // Configure paths or glob patterns to exclude from file watching. "files.watcherExclude": { "**/.git/objects/**": true, From 910ef8cc78b9203004d61fe213249d943eddff29 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:24:02 +0200 Subject: [PATCH 39/70] [Docker Image] remove workaround for bloaty build (#35395) * remove workaround for bloaty * update version file --- integrations/docker/images/base/chip-build/Dockerfile | 8 -------- integrations/docker/images/base/chip-build/version | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/integrations/docker/images/base/chip-build/Dockerfile b/integrations/docker/images/base/chip-build/Dockerfile index 37edf89730ecd9..db209a82f20b87 100644 --- a/integrations/docker/images/base/chip-build/Dockerfile +++ b/integrations/docker/images/base/chip-build/Dockerfile @@ -123,14 +123,6 @@ RUN set -x \ ruff \ && : # last line -#TODO Issue #35280: this is only added as a workaround to bloaty build failures, remove it once bloaty fixes issue -# Clone and install abseil-cpp -RUN git clone https://github.com/abseil/abseil-cpp.git /tmp/abseil-cpp \ - && cd /tmp/abseil-cpp \ - && cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ - && cmake --build build --target install \ - && rm -rf /tmp/abseil-cpp - # Install bloat comparison tools RUN set -x \ && git clone https://github.com/google/bloaty.git \ diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 0ca6f37e4e236e..cad8a84802febb 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -74 : Update Silabs docker SiSDK 2024.06.1 WiseConnect 3.3.1 Wiseconnect Wifi bt sdk 2.10.0 +75: remove workaround for bloaty build, workaround involved cloning and installing abseil From 6729452294f90c3ece4af66434d73b8d9c100ff3 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 4 Sep 2024 08:27:57 -0400 Subject: [PATCH 40/70] Update spacing error for docker versioning (#35401) --- integrations/docker/images/base/chip-build/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index cad8a84802febb..6ee6f069675a0c 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -75: remove workaround for bloaty build, workaround involved cloning and installing abseil +75 : remove workaround for bloaty build, workaround involved cloning and installing abseil From f66727d82a37197e891926219b2f87fd3a1a5fd3 Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:30:36 +0800 Subject: [PATCH 41/70] [Ameba] refactor platform (#35396) * refactor platform codes for all-clusters-app, integrated it to platform sdk. --- .../ameba/main/chipinterface.cpp | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/examples/all-clusters-app/ameba/main/chipinterface.cpp b/examples/all-clusters-app/ameba/main/chipinterface.cpp index 99ed719f0fab28..5bf20befc73107 100644 --- a/examples/all-clusters-app/ameba/main/chipinterface.cpp +++ b/examples/all-clusters-app/ameba/main/chipinterface.cpp @@ -23,22 +23,16 @@ #include "DeviceCallbacks.h" #include "Globals.h" #include "LEDWidget.h" -#include "ManualOperationCommand.h" #include "chip_porting.h" #include -#include #include -#include -#include #include #include #include #include -#include -#include #include -#include + #include #include #if CONFIG_ENABLE_AMEBA_CRYPTO @@ -47,11 +41,9 @@ #include #include #include -#include -#include #include + #if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER -#include #include #endif @@ -76,9 +68,6 @@ constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(kNetworkCommissioningEndpointMain /* Endpoint Id */, &(NetworkCommissioning::AmebaWiFiDriver::GetInstance())); - -app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; -Clusters::ModeSelect::StaticSupportedModesManager sStaticSupportedModesManager; } // namespace void NetWorkCommissioningInstInit() @@ -180,15 +169,8 @@ static void InitServer(intptr_t context) #if CONFIG_ENABLE_CHIP_SHELL InitBindingHandler(); - InitManualOperation(); -#endif - app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); - Clusters::ModeSelect::setSupportedModesManager(&sStaticSupportedModesManager); - MatterMicrowaveOvenServerInit(); -#if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER - static SmokeCOTestEventTriggerHandler sSmokeCOTestEventTriggerHandler; - Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&sSmokeCOTestEventTriggerHandler); #endif + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAmebaObserver); } @@ -231,15 +213,3 @@ bool lowPowerClusterSleep() { return true; } - -using namespace chip::app::Clusters::LaundryWasherControls; -void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) -{ - LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); -} - -using namespace chip::app::Clusters::LaundryDryerControls; -void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) -{ - LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); -} From 23a81aece368c24559be1cc4e5869a97322684a5 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Wed, 4 Sep 2024 21:31:27 +0900 Subject: [PATCH 42/70] [Android] Fix DNSSD interupped system call issue (#35388) * Fix Android DNSSD signal 3 issue * Restyled by google-java-format --------- Co-authored-by: Restyled.io --- .../platform/NsdManagerServiceResolver.java | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 40595263cb8214..33d5f44d64ee05 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -45,6 +46,8 @@ public class NsdManagerServiceResolver implements ServiceResolver { @Nullable private final NsdManagerResolverAvailState nsdManagerResolverAvailState; private final long timeout; + private ExecutorService mResolveExecutorService; + /** * @param context application context * @param nsdManagerResolverAvailState Passing NsdManagerResolverAvailState allows @@ -69,6 +72,8 @@ public NsdManagerServiceResolver( this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; this.timeout = timeout; + + mResolveExecutorService = Executors.newSingleThreadExecutor(); } public NsdManagerServiceResolver(Context context) { @@ -116,29 +121,28 @@ public void run() { } }; - new Thread( - () -> { - if (nsdManagerResolverAvailState != null) { - nsdManagerResolverAvailState.acquireResolver(); - } + mResolveExecutorService.execute( + () -> { + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.acquireResolver(); + } - ScheduledFuture resolveTimeoutExecutor = - Executors.newSingleThreadScheduledExecutor() - .schedule(timeoutRunnable, timeout, TimeUnit.MILLISECONDS); + ScheduledFuture resolveTimeoutExecutor = + Executors.newSingleThreadScheduledExecutor() + .schedule(timeoutRunnable, timeout, TimeUnit.MILLISECONDS); - NsdServiceFinderAndResolver serviceFinderResolver = - new NsdServiceFinderAndResolver( - this.nsdManager, - serviceInfo, - callbackHandle, - contextHandle, - chipMdnsCallback, - multicastLock, - resolveTimeoutExecutor, - nsdManagerResolverAvailState); - serviceFinderResolver.start(); - }) - .start(); + NsdServiceFinderAndResolver serviceFinderResolver = + new NsdServiceFinderAndResolver( + this.nsdManager, + serviceInfo, + callbackHandle, + contextHandle, + chipMdnsCallback, + multicastLock, + resolveTimeoutExecutor, + nsdManagerResolverAvailState); + serviceFinderResolver.start(); + }); } @Override From 7bc96399c74a5e96742e29c0ee11dfd669a54d9e Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:34:58 +0100 Subject: [PATCH 43/70] TC_EEVSE_2.2 through 2.5 python script has to be updated as per the test plan changes (#35399) * Updated 2.2 test steps - autogen'd from test plan. No functional changes. * Update TC EEVSE 2.3 with autogen'd test steps. No functional code change. * Updated TC_EEVSE_2.4 test steps - no functional code changes. * TC_EEVSE_2.5 - updated test steps - no functional changes. * TC_EEVSE_2.5 added new step 8 (try to send Enable Charge Command when in diagnostics mode which should return failure). --- src/python_testing/TC_EEVSE_2_2.py | 174 +++++++++++++++-------------- src/python_testing/TC_EEVSE_2_3.py | 158 +++++++++++++------------- src/python_testing/TC_EEVSE_2_4.py | 93 +++++++-------- src/python_testing/TC_EEVSE_2_5.py | 81 ++++++++------ 4 files changed, 263 insertions(+), 243 deletions(-) diff --git a/src/python_testing/TC_EEVSE_2_2.py b/src/python_testing/TC_EEVSE_2_2.py index a0e226b9d15cbb..b2591fa4a5d206 100644 --- a/src/python_testing/TC_EEVSE_2_2.py +++ b/src/python_testing/TC_EEVSE_2_2.py @@ -52,93 +52,97 @@ def pics_TC_EEVSE_2_2(self): def steps_TC_EEVSE_2_2(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", - is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", - "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "After a few seconds TH reads from the DUT the State attribute.", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute.", - "Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute.", - "Verify value is 0x00 (NoError)"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event.", - "Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("4a", "TH reads from the DUT the State attribute.", - "Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("4b", - "TH reads from the DUT the SessionID attribute. Value is noted for later"), - TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=2 minutes in the future, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event.", - "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("6a", "TH reads from the DUT the State attribute.", - "Verify value is 0x3 (PluggedInCharging)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute.", - "Verify value is 0x1 (ChargingEnabled)"), - TestStep("6c", "TH reads from the DUT the ChargingEnabledUntil attribute.", - "Verify value is the commanded value"), - TestStep("6d", "TH reads from the DUT the MinimumChargeCurrent attribute.", - "Verify value is the commanded value (6000)"), - TestStep("6e", "TH reads from the DUT the MaximumChargeCurrent attribute.", - "Verify value is the min(command value (60000), CircuitCapacity)"), - TestStep("7", "Wait 2 minutes.", - "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), - TestStep("7a", "TH reads from the DUT the State attribute.", - "Verify value is 0x02 (PluggedInDemand)"), - TestStep("7b", "TH reads from the DUT the SupplyState attribute.", - "Verify value is 0x00 (Disabled)"), - TestStep("8", "TH sends command EnableCharging with ChargingEnabledUntil=NULL, minimumChargeCurrent = 6000, maximumChargeCurrent=12000"), - TestStep("8a", "TH reads from the DUT the State attribute.", - "Verify value is 0x03 (PluggedInCharging)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute.", - "Verify value is 1 (ChargingEnabled)"), - TestStep("8c", "TH reads from the DUT the ChargingEnabledUntil attribute", - "Verify value is the commanded value (NULL)"), - TestStep("8d", "TH reads from the DUT the MinimumChargeCurrent attribute", - "Verify value is the commanded value (6000)"), - TestStep("8e", "TH reads from the DUT the MaximumChargeCurrent attribute", - "Verify value is the MIN(command value (60000), CircuitCapacity)"), - TestStep("9", - "If the optional attribute is supported TH writes to the DUT UserMaximumChargeCurrent=6000"), + TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)"), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Value has to be 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("3a", "After a few seconds TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState", + "Value has to be 0x00 (NoError)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("4a", "TH reads from the DUT the State", + "Value has to be 0x01 (PluggedInNoDemand)"), + TestStep("4b", "TH reads from the DUT the SessionID", + "Value is noted for later"), + TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=2 minutes in the future, minimumChargeCurrent=6000, maximumChargeCurrent=60000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("6a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("6b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), + TestStep("6c", "TH reads from the DUT the ChargingEnabledUntil", + "Value has to be the ChargingEnabledUntil commanded value"), + TestStep("6d", "TH reads from the DUT the MinimumChargeCurrent", + "Value has to be the minimumChargeCurrent commanded value"), + TestStep("6e", "TH reads from the DUT the MaximumChargeCurrent", + "Value has to be the min(maximumChargeCurrent commanded value,CircuitCapacity)"), + TestStep("7", "Wait 2 minutes", + "Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), + TestStep("7a", "TH reads from the DUT the State", + "Value has to be 0x02 (PluggedInDemand)"), + TestStep("7b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("8", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=12000", + "Verify DUT responds w/ status SUCCESS(0x00) and Event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("8a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("8b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), + TestStep("8c", "TH reads from the DUT the ChargingEnabledUntil", + "Value has to be the ChargingEnabledUntil commanded value"), + TestStep("8d", "TH reads from the DUT the MinimumChargeCurrent", + "Value has to be the minimumChargeCurrent commanded value"), + TestStep("8e", "TH reads from the DUT the MaximumChargeCurrent", + "Value has to be the min(maximumChargeCurrent commanded value,CircuitCapacity)"), + TestStep("9", "If the optional attribute is supported, TH writes to the DUT the UserMaximumChargeCurrent=6000", + "Charging rate reduced to 6A"), TestStep("9a", "After a few seconds TH reads from the DUT the MaximumChargeCurrent", - "Verify value is UserMaximumChargeCurrent value (6000)"), - TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear", - "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), - TestStep("10a", "TH reads from the DUT the State attribute", - "Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", - "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("11a", "TH reads from the DUT the State attribute", - "Verify value is 0x03 (PluggedInCharging)"), - TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear", - "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), - TestStep("12a", "TH reads from the DUT the State attribute", - "Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", - "Verify Event EEVSE.S.E01(EVNotDetected) sent"), - TestStep("13a", "TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("13b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x01 (ChargingEnabled)"), - TestStep("13c", "TH reads from the DUT the SessionID attribute", - "Verify value is the same value noted in 4b"), - TestStep("13d", "TH reads from the DUT the SessionDuration attribute", - "Verify value is greater than 120 (and match the time taken for the tests from step 4 to step 13)"), - TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event", - "Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("14a", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", - "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("14b", "TH reads from the DUT the SessionID attribute", - "Verify value is 1 more than the value noted in 4b"), + "Value has to be the configured UserMaximumChargeCurrent value"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), + TestStep("10a", "TH reads from the DUT the State", + "Value has to be 0x01 (PluggedInNoDemand)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("11a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), + TestStep("12a", "TH reads from the DUT the State", + "Value has to be 0x01 (PluggedInNoDemand)"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("13a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("13b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), + TestStep("13c", "TH reads from the DUT the SessionID", + "Value has to be the same value noted in 4b"), + TestStep("13d", "TH reads from the DUT the SessionDuration", + "Value has to be greater than 120 (and match the time taken for the tests from step 4 to step 13)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("14a", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("14b", "TH reads from the DUT the SessionID", + "Value has to be 1 more than the value noted in 4b"), TestStep("15", "TH sends command Disable", - "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), - TestStep("15a", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x00 (Disabled)"), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear."), - TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", - "Verify Event EEVSE.S.E01(EVNotDetected) sent"), - TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), + "Verify DUT responds w/ status SUCCESS(0x00) and Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), + TestStep("15a", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), ] return steps diff --git a/src/python_testing/TC_EEVSE_2_3.py b/src/python_testing/TC_EEVSE_2_3.py index 27507a4899fb69..8de0ebef13e8a2 100644 --- a/src/python_testing/TC_EEVSE_2_3.py +++ b/src/python_testing/TC_EEVSE_2_3.py @@ -52,91 +52,89 @@ def pics_TC_EEVSE_2_3(self): def steps_TC_EEVSE_2_3(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", - is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", - "Verify value is 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event.", - "Verify Command response is Success"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE TimeOfUse Mode Test Event.", - "Verify Command response is Success"), - TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event.", - "Verify Command response is Success and event EEVSE.S.E00(EVConnected) sent"), - TestStep("6", "TH sends ClearTargets.", - "Verify Command response is Success"), - TestStep("6a", "TH reads NextChargeStartTime attribute.", - "Verify value is null."), - TestStep("6b", "TH reads NextChargeTargetTime attribute.", - "Verify value is null."), - TestStep("6c", "TH reads NextChargeRequiredEnergy attribute.", - "Verify value is null."), - TestStep("6d", "TH reads NextChargeTargetSoC attribute.", - "Verify value is null."), - TestStep("7", "TH sends GetTargets.", + TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)"), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Value has to be 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE TimeOfUse Mode Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("6", "TH sends command ClearTargets", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("6a", "TH reads from the DUT the NextChargeStartTime", + "Value has to be null."), + TestStep("6b", "TH reads from the DUT the NextChargeTargetTime", + "Value has to be null."), + TestStep("6c", "TH reads from the DUT the NextChargeRequiredEnergy", + "Value has to be null."), + TestStep("6d", "TH reads from the DUT the NextChargeTargetSoC", + "Value has to be null."), + TestStep("7", "TH sends command GetTargets", "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with no targets defined."), - TestStep("8", "TH sends SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1439, TargetSoC=null, AddedEnergy=25000000}.", - "Verify Command response is Success"), - TestStep("8a", "TH reads NextChargeStartTime attribute.", - "Verify value is null."), - TestStep("8b", "TH reads NextChargeTargetTime attribute.", - "Verify value is null."), - TestStep("8c", "TH reads NextChargeRequiredEnergy attribute.", - "Verify value is null."), - TestStep("8d", "TH reads NextChargeTargetSoC attribute.", - "Verify value is null."), - TestStep("9", "TH sends EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000.", - "Verify Command response is Success"), - TestStep("9a", "TH reads NextChargeStartTime attribute.", - "Verify value is before the next TargetTime above."), - TestStep("9b", "TH reads NextChargeTargetTime attribute.", - "Verify value is TargetTime above."), - TestStep("9c", "TH reads NextChargeRequiredEnergy attribute.", - "Verify value is AddedEnergy above."), - TestStep("9d", "TH reads NextChargeTargetSoC attribute.", - "Verify value is null."), - TestStep("10", "TH sends GetTargets.", + TestStep("8", "TH sends command SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1439, TargetSoC=null, AddedEnergy=25000000}", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("8a", "TH reads from the DUT the NextChargeStartTime", + "Value has to be null."), + TestStep("8b", "TH reads from the DUT the NextChargeTargetTime", + "Value has to be null."), + TestStep("8c", "TH reads from the DUT the NextChargeRequiredEnergy", + "Value has to be null."), + TestStep("8d", "TH reads from the DUT the NextChargeTargetSoC", + "Value has to be null."), + TestStep("9", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("9a", "TH reads from the DUT the NextChargeStartTime", + "Value has to be before the next TargetTime above."), + TestStep("9b", "TH reads from the DUT the NextChargeTargetTime", + "Value has to be TargetTime above."), + TestStep("9c", "TH reads from the DUT the NextChargeRequiredEnergy", + "Value has to be AddedEnergy above."), + TestStep("9d", "TH reads from the DUT the NextChargeTargetSoC", + "Value has to be null."), + TestStep("10", "TH sends command GetTargets", "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with targets equivalent to the above (Note 1)."), - TestStep("11", "TH sends SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1, TargetSoC=100, AddedEnergy=null}.", - "Verify Command response is Success"), - TestStep("11a", "TH reads NextChargeStartTime attribute.", - "Verify value is before the next TargetTime above."), - TestStep("11b", "TH reads NextChargeTargetTime attribute.", - "Verify value is TargetTime above."), - TestStep("11c", "TH reads NextChargeRequiredEnergy attribute.", - "Verify value is null."), - TestStep("11d", "TH reads NextChargeTargetSoC attribute.", - "Verify value is 100."), - TestStep("12", "TH sends GetTargets.", + TestStep("11", "TH sends command SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1, TargetSoC=100, AddedEnergy=null}", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("11a", "TH reads from the DUT the NextChargeStartTime", + "Value has to be before the next TargetTime above."), + TestStep("11b", "TH reads from the DUT the NextChargeTargetTime", + "Value has to be TargetTime above."), + TestStep("11c", "TH reads from the DUT the NextChargeRequiredEnergy", + "Value has to be null."), + TestStep("11d", "TH reads from the DUT the NextChargeTargetSoC", + "Value has to be 100."), + TestStep("12", "TH sends command GetTargets", "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with targets equivalent to the above (Note 1)."), - TestStep("13", "TH sends SetTargets with DayOfTheWeekforSequence=0x40 (i.e. having Saturday set) and 10 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140 and all with TargetSoC=null, AddedEnergy=2500000.", - "Verify Command response is Success"), - TestStep("14", "TH sends SetTargets with DayOfTheWeekforSequence=0x01 (i.e. having Sunday set) and no ChargingTargets.", - "Verify Command response is Success"), - TestStep("15", "TH sends GetTargets.", + TestStep("13", "TH sends command SetTargets with DayOfTheWeekforSequence=0x40 (i.e. having Saturday set) and 10 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140 and all with TargetSoC=null, AddedEnergy=2500000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("14", "TH sends command SetTargets with DayOfTheWeekforSequence=0x01 (i.e. having Sunday set) and no ChargingTargets", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("15", "TH sends command GetTargets", "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with 1 target for each day Monday to Friday equivalent to step 9 (Note 1), 10 targets for Saturday as step 11, and no targets for Sunday."), - TestStep("16", "TH sends ClearTargets.", - "Verify Command response is Success"), - TestStep("16a", "TH reads NextChargeStartTime attribute.", - "Verify value is null."), - TestStep("16b", "TH reads NextChargeTargetTime attribute.", - "Verify value is null."), - TestStep("16c", "TH reads NextChargeRequiredEnergy attribute.", - "Verify value is null."), - TestStep("16d", "TH reads NextChargeTargetSoC attribute.", - "Verify value is null."), - TestStep("17", "TH sends GetTargets.", + TestStep("16", "TH sends command ClearTargets", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("16a", "TH reads from the DUT the NextChargeStartTime", + "Value has to be null."), + TestStep("16b", "TH reads from the DUT the NextChargeTargetTime", + "Value has to be null."), + TestStep("16c", "TH reads from the DUT the NextChargeRequiredEnergy", + "Value has to be null."), + TestStep("16d", "TH reads from the DUT the NextChargeTargetSoC", + "Value has to be null."), + TestStep("17", "TH sends command GetTargets", "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with no targets defined."), - TestStep("18", "TH sends SetTargets with two identical ChargingTargetSchedules={DayOfTheWeekforSequence=0x01,ChargingTarget[0]={TargetTime=60,TargetSoC=null,AddedEnergy=2500000}}.", - "Verify Command response is ConstraintError"), - TestStep("19", "TH sends SetTargets with DayOfTheWeekforSequence=0x40 and 11 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140,1260 and all with TargetSoC=null, AddedEnergy=2500000.", - "Verify Command response is ResourceExhausted"), - TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear.", - "Verify Command response is Success and event EEVSE.S.E01(EVNotDetected) sent"), - TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear.", - "Verify Command response is Success"), - TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for for EVSE TimeOfUse Mode Test Event Clear.", - "Verify Command response is Success"), - + TestStep("18", "TH sends command SetTargets with two identical ChargingTargetSchedules={DayOfTheWeekforSequence=0x01,ChargingTarget[0]={TargetTime=60,TargetSoC=null,AddedEnergy=2500000}}", + "Verify DUT responds w/ status CONSTRAINT_ERROR(0x87)"), + TestStep("19", "TH sends command SetTargets with DayOfTheWeekforSequence=0x40 and 11 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140,1260 and all with TargetSoC=null, AddedEnergy=2500000", + "Verify DUT responds w/ status RESOURCE_EXHAUSTED(0x89)"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE TimeOfUse Mode Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), ] return steps diff --git a/src/python_testing/TC_EEVSE_2_4.py b/src/python_testing/TC_EEVSE_2_4.py index 33eb143b8db5a4..ee8dbae5fa43a2 100644 --- a/src/python_testing/TC_EEVSE_2_4.py +++ b/src/python_testing/TC_EEVSE_2_4.py @@ -50,52 +50,55 @@ def pics_TC_EEVSE_2_4(self): def steps_TC_EEVSE_2_4(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", - is_commissioning=True), + TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)"), TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", - "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "After a few seconds TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute", - "Verify value is 0x00 (NoError)"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event", - "Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("4a", "TH reads from the DUT the State attribute", - "Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("4b", - "TH reads from the DUT the SessionID attribute. Value is saved for later"), - TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=Null, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", - "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("6a", "TH reads from the DUT the State attribute", - "Verify value is 0x3 (PluggedInCharging)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x1 (ChargingEnabled)"), - TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Ground Fault Test Event", - "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x00 (NoError), FaultStateCurrentFaultState = 0x07 (GroundFault)"), - TestStep("7a", "TH reads from the DUT the State attribute", - "Verify value is 0x6 (Fault)"), - TestStep("7b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x4 (DisabledError)"), - TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Over Temperature Fault Test Event", - "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x07 (GroundFault), FaultStateCurrentFaultState = 0x0F (OverTemperature)"), - TestStep("8a", "TH reads from the DUT the State attribute", - "Verify value is 0x6 (Fault)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x4 (DisabledError)"), - TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Fault Test Event Clear", - "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x0F (OverTemperature), FaultStateCurrentFaultState = 0x00 (NoError)"), - TestStep("9a", "TH reads from the DUT the State attribute", - "Verify value is 0x3 (PluggedInCharging)"), - TestStep("9b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x1 (ChargingEnabled)"), - TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear."), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", - "Verify Event EEVSE.S.E01(EVNotDetected) sent"), - TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), + "Value has to be 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("3a", "After a few seconds TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState", + "Value has to be 0x00 (NoError)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E00(EVConnected) sent"), + TestStep("4a", "TH reads from the DUT the State", + "Value has to be 0x01 (PluggedInNoDemand)"), + TestStep("4b", "TH reads from the DUT the SessionID", + "Value is noted for later"), + TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E02(EnergyTransferStarted) sent"), + TestStep("6a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("6b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), + TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE Ground Fault Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x00 (NoError), FaultStateCurrentFaultState = 0x07 (GroundFault)"), + TestStep("7a", "TH reads from the DUT the State", + "Value has to be 0x06 (Fault)"), + TestStep("7b", "TH reads from the DUT the SupplyState", + "Value has to be 0x04 (DisabledError)"), + TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE Over Temperature Fault Test Event", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x07 (GroundFault), FaultStateCurrentFaultState = 0x0F (OverTemperature)"), + TestStep("8a", "TH reads from the DUT the State", + "Value has to be 0x06 (Fault)"), + TestStep("8b", "TH reads from the DUT the SupplyState", + "Value has to be 0x04 (DisabledError)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE Fault Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x0F (OverTemperature), FaultStateCurrentFaultState = 0x00 (NoError)"), + TestStep("9a", "TH reads from the DUT the State", + "Value has to be 0x03 (PluggedInCharging)"), + TestStep("9b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Charge Demand Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EV Plugged-in Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00) and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), ] return steps diff --git a/src/python_testing/TC_EEVSE_2_5.py b/src/python_testing/TC_EEVSE_2_5.py index ecd88b4514288b..3096f013dde8af 100644 --- a/src/python_testing/TC_EEVSE_2_5.py +++ b/src/python_testing/TC_EEVSE_2_5.py @@ -50,39 +50,47 @@ def pics_TC_EEVSE_2_5(self): def steps_TC_EEVSE_2_5(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", - is_commissioning=True), + TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)"), TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", - "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute", - "Verify value is 0x00 (NoError)"), - TestStep("4", "TH sends command EnableCharging with ChargingEnabledUntil=Null, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("4a", "TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("4b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x01 (ChargingEnabled)"), + "Value has to be 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("3a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState", + "Value has to be 0x00 (NoError)"), + TestStep("4", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("4a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("4b", "TH reads from the DUT the SupplyState", + "Value has to be 0x01 (ChargingEnabled)"), TestStep("5", "TH sends command StartDiagnostics", - "Verify that command is rejected with Failure"), - TestStep("6", "TH sends command Disable."), - TestStep("6a", "TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x00 (Disabled)"), + "Verify DUT responds w/ status FAILURE(0x01)"), + TestStep("6", "TH sends command Disable", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("6a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("6b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), TestStep("7", "TH sends command StartDiagnostics", - "Verify that command is accepted with Success"), - TestStep("7a", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x04 (DisabledDiagnostics)"), - TestStep("8", "A few seconds later TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Diagnostics Complete Event"), - TestStep("8a", "TH reads from the DUT the State attribute", - "Verify value is 0x00 (NotPluggedIn)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute", - "Verify value is 0x00 (Disabled)"), - TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("7a", "TH reads from the DUT the SupplyState", + "Value has to be 0x04 (DisabledDiagnostics)"), + TestStep("8", "TH sends command EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000", + "Verify DUT responds w/ status FAILURE(0x01)"), + TestStep("8a", "TH reads from the DUT the SupplyState", + "Value has to be 0x04 (DisabledDiagnostics)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for EVSE Diagnostics Complete Event", + "Verify DUT responds w/ status SUCCESS(0x00)"), + TestStep("9a", "TH reads from the DUT the State", + "Value has to be 0x00 (NotPluggedIn)"), + TestStep("9b", "TH reads from the DUT the SupplyState", + "Value has to be 0x00 (Disabled)"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TESTEVENT_TRIGGERKEY and EventTrigger field set to PIXIT.EEVSE.TESTEVENTTRIGGER for Basic Functionality Test Event Clear", + "Verify DUT responds w/ status SUCCESS(0x00)"), ] return steps @@ -145,16 +153,23 @@ async def test_TC_EEVSE_2_5(self): await self.check_evse_attribute("SupplyState", Clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics) self.step("8") - await self.send_test_event_trigger_evse_diagnostics_complete() + await self.send_enable_charge_command(charge_until=charge_until, min_charge=min_charge_current, + max_charge=max_charge_current, expected_status=Status.Failure) self.step("8a") + await self.check_evse_attribute("SupplyState", Clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics) + + self.step("9") + await self.send_test_event_trigger_evse_diagnostics_complete() + + self.step("9a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn) - self.step("8b") + self.step("9b") # It should stay disabled after a diagnostics session await self.check_evse_attribute("SupplyState", Clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled) - self.step("9") + self.step("10") await self.send_test_event_trigger_basic_clear() From 83ae2376ec56324bcce725aaed1c44ae263bcb32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 08:36:05 -0400 Subject: [PATCH 44/70] Bump third_party/openthread/repo from `f0b6fce` to `aed9cd1` (#35374) Bumps [third_party/openthread/repo](https://github.com/openthread/openthread) from `f0b6fce` to `aed9cd1`. - [Release notes](https://github.com/openthread/openthread/releases) - [Commits](https://github.com/openthread/openthread/compare/f0b6fcea6ef77c9a54ab11767593f9a8798e3662...aed9cd1a307c05fe2f5b6b4b5677baaabce3d38e) --- updated-dependencies: - dependency-name: third_party/openthread/repo dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- third_party/openthread/repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/openthread/repo b/third_party/openthread/repo index f0b6fcea6ef77c..aed9cd1a307c05 160000 --- a/third_party/openthread/repo +++ b/third_party/openthread/repo @@ -1 +1 @@ -Subproject commit f0b6fcea6ef77c9a54ab11767593f9a8798e3662 +Subproject commit aed9cd1a307c05fe2f5b6b4b5677baaabce3d38e From ed3403d8e081fc453c749d1d5dc08a3f5a033c13 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 4 Sep 2024 14:49:53 +0200 Subject: [PATCH 45/70] [Python] Avoid InvalidStateError on cancel (#35380) When the co-routine GetConnectedDevice() gets cancelled, the wait_for call will cancel the future we are waiting for. However, the SDK still calls the _DeviceAvailableCallback with an error (CHIP Error 0x00000074: The operation has been cancelled). However, we can't set the future result at this point as the co-routine is already cancelled. Simply check the future state before setting the result. --- src/controller/python/chip/ChipDeviceCtrl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 011174185fd440..d76d415d746945 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -1062,6 +1062,8 @@ def __init__(self, loop, future: asyncio.Future): self._future = future def _deviceAvailable(self): + if self._future.cancelled(): + return if self._returnDevice.value is not None: self._future.set_result(self._returnDevice) else: From 44f883733280ff798ec112318f75e2f088b9f378 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:06:59 +0100 Subject: [PATCH 46/70] EVSE - Update FakeReadings when a MaxChargeCurrent change occurs (#35346) * Updated FakeReadings when a MaxChargeCurrent change is made so that the readings are more representative of a real EV. * Restyled by whitespace * Removed using namespace from header file and added chip:: back into the type defintion since build fails. * Apply suggestions from code review Co-authored-by: Andrei Litvin * Apply suggestions from code review * Restyled by clang-format --------- Co-authored-by: Restyled.io Co-authored-by: Andrei Litvin --- .../include/EVSEManufacturerImpl.h | 7 ++++++ .../energy-evse/src/EVSEManufacturerImpl.cpp | 9 +++++++ .../energy-reporting/include/FakeReadings.h | 10 ++++++++ .../energy-reporting/src/FakeReadings.cpp | 25 +++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/examples/energy-management-app/energy-management-common/energy-evse/include/EVSEManufacturerImpl.h b/examples/energy-management-app/energy-management-common/energy-evse/include/EVSEManufacturerImpl.h index b94220d11b28f3..17d2c865bbaf53 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/include/EVSEManufacturerImpl.h +++ b/examples/energy-management-app/energy-management-common/energy-evse/include/EVSEManufacturerImpl.h @@ -213,6 +213,13 @@ class EVSEManufacturer : public DEMManufacturerDelegate */ static void FakeReadingsTimerExpiry(System::Layer * systemLayer, void * manufacturer); + /* + * @brief Updates the parameters used to generate fake power and energy readings + * + * @param maximumChargeCurrent Maximum Charge current in mA + */ + void UpdateEVFakeReadings(const Amperage_mA maximumChargeCurrent); + private: EnergyEvseManager * mEvseInstance; ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * mEPMInstance; diff --git a/examples/energy-management-app/energy-management-common/energy-evse/src/EVSEManufacturerImpl.cpp b/examples/energy-management-app/energy-management-common/energy-evse/src/EVSEManufacturerImpl.cpp index 359e7c8066551d..4f28c3249f6538 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/src/EVSEManufacturerImpl.cpp +++ b/examples/energy-management-app/energy-management-common/energy-evse/src/EVSEManufacturerImpl.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -551,6 +552,13 @@ CHIP_ERROR EVSEManufacturer::SendPeriodicEnergyReading(EndpointId aEndpointId, i return CHIP_NO_ERROR; } +void EVSEManufacturer::UpdateEVFakeReadings(const Amperage_mA maximumChargeCurrent) +{ + FakeReadings::GetInstance().SetCurrent(maximumChargeCurrent); + // Note we have to divide by 1000 to make ma * mv = mW + FakeReadings::GetInstance().SetPower((FakeReadings::GetInstance().GetVoltage() * maximumChargeCurrent) / 1000); +} + /** * @brief Main Callback handler - to be implemented by Manufacturer * @@ -573,6 +581,7 @@ void EVSEManufacturer::ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_ ChipLogProgress(AppServer, "EVSE callback - maxChargeCurrent changed to %ld", static_cast(cb->ChargingCurrent.maximumChargeCurrent)); pClass->ComputeChargingSchedule(); + pClass->UpdateEVFakeReadings(cb->ChargingCurrent.maximumChargeCurrent); break; case EVSECallbackType::EnergyMeterReadingRequested: ChipLogProgress(AppServer, "EVSE callback - EnergyMeterReadingRequested"); diff --git a/examples/energy-management-app/energy-management-common/energy-reporting/include/FakeReadings.h b/examples/energy-management-app/energy-management-common/energy-reporting/include/FakeReadings.h index f8334ba2708b7e..4d8415ac39a40b 100644 --- a/examples/energy-management-app/energy-management-common/energy-reporting/include/FakeReadings.h +++ b/examples/energy-management-app/energy-management-common/energy-reporting/include/FakeReadings.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include @@ -58,6 +59,15 @@ class FakeReadings */ void FakeReadingsUpdate(); + void SetPower(chip::Power_mW power_mW); + chip::Power_mW GetPower(); + + void SetVoltage(chip::Voltage_mV voltage_mV); + chip::Voltage_mV GetVoltage(); + + void SetCurrent(chip::Amperage_mA current_mA); + chip::Amperage_mA GetCurrent(); + /** * @brief Timer expiry callback to handle fake load */ diff --git a/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp b/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp index c887357a5f7b58..78795976c0bbc2 100644 --- a/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp +++ b/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp @@ -180,3 +180,28 @@ void FakeReadings::FakeReadingsTimerExpiry(System::Layer * systemLayer, void * m mn->FakeReadingsUpdate(); } + +void FakeReadings::SetPower(Power_mW aPower_mW) +{ + mPower_mW = aPower_mW; +} +Power_mW FakeReadings::GetPower() +{ + return mPower_mW; +}; +void FakeReadings::SetVoltage(Voltage_mV aVoltage_mV) +{ + mVoltage_mV = aVoltage_mV; +} +Voltage_mV FakeReadings::GetVoltage() +{ + return mVoltage_mV; +}; +void FakeReadings::SetCurrent(Amperage_mA aCurrent_mA) +{ + mCurrent_mA = aCurrent_mA; +} +Amperage_mA FakeReadings::GetCurrent() +{ + return mCurrent_mA; +} From 6144736cdc09a9691a594a5f43926e6458541bed Mon Sep 17 00:00:00 2001 From: feasel <120589145+feasel0@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:59:27 -0400 Subject: [PATCH 47/70] Generating separate binaries for each unit test for EFR32 (#35028) * silabs full changes, flashable just if * silabs full changes, flashable just if (corrected) * silabs changes, flashable changes * yes executables.gni, cts.gni, args.gni, test_driver build.gn * yes executables.gni, args.gni, test_driver build.gn * Modified chip_test_suite to handle logic for both efr32 test_driver and chip_link_test * Doc update * Added final newline * Comment updates * Remove deprecated `tests` variable for per-test custom mains. * switched to shutil.copy instead of subprocess copy * Added chip_link_tests to test_driver/efr32/args.gni and removed special logic from chip_test_suite * Restyled by gn * Restyled by autopep8 * Punctuation change * Added special exception for darwin to always include test_sources in common lib. * Added comment re darwin exception * Restyled by gn * Revisions to builder scripts - removing map() usage and propagating OSError to make_wrapper. * Restyled by autopep8 --------- Co-authored-by: Restyled.io --- .github/.wordlist.txt | 2 - build/chip/chip_test.gni | 71 --------- build/chip/chip_test_suite.gni | 101 ++++++------- build/toolchain/flashable_executable.gni | 18 ++- scripts/build/builders/efr32.py | 55 ++++++- scripts/build/builders/host.py | 2 +- scripts/flashing/firmware_utils.py | 11 +- scripts/flashing/silabs_firmware_utils.py | 38 +++++ src/test_driver/efr32/BUILD.gn | 26 +--- src/test_driver/efr32/README.md | 16 +- src/test_driver/efr32/args.gni | 19 ++- src/test_driver/efr32/py/BUILD.gn | 26 ---- .../efr32/py/nl_test_runner/nl_test_runner.py | 141 ------------------ .../__init__.py | 0 .../efr32/py/pw_test_runner/pw_test_runner.py | 42 ++++-- src/test_driver/efr32/py/setup.cfg | 2 +- third_party/silabs/silabs_executable.gni | 73 ++++++--- 17 files changed, 265 insertions(+), 378 deletions(-) delete mode 100644 build/chip/chip_test.gni delete mode 100644 src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py rename src/test_driver/efr32/py/{nl_test_runner => pw_test_runner}/__init__.py (100%) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 4444d8299d26cb..5637540f7f9b25 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -950,8 +950,6 @@ NitricOxideConcentrationMeasurement NitrogenDioxideConcentrationMeasurement nl nltest -NLUnitTest -NLUnitTests nmcli nmtui noc diff --git a/build/chip/chip_test.gni b/build/chip/chip_test.gni deleted file mode 100644 index b5b32f24d0b0b7..00000000000000 --- a/build/chip/chip_test.gni +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") -import("//build_overrides/pigweed.gni") - -import("$dir_pw_build/python_action.gni") - -import("${chip_root}/build/chip/tests.gni") -import("${chip_root}/src/platform/device.gni") -import("${dir_pw_unit_test}/test.gni") - -assert(chip_build_tests) - -if (chip_link_tests) { - template("chip_test") { - _test_name = target_name - - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - executable(_test_name) { - forward_variables_from(invoker, "*", [ "output_dir" ]) - output_dir = _test_output_dir - } - - group(_test_name + ".lib") { - } - - if (chip_pw_run_tests) { - pw_python_action(_test_name + ".run") { - deps = [ ":${_test_name}" ] - inputs = [ pw_unit_test_AUTOMATIC_RUNNER ] - module = "pw_unit_test.test_runner" - python_deps = [ - "$dir_pw_cli/py", - "$dir_pw_unit_test/py", - ] - args = [ - "--runner", - rebase_path(pw_unit_test_AUTOMATIC_RUNNER, root_build_dir), - "--test", - rebase_path("$_test_output_dir/$_test_name", root_build_dir), - ] - stamp = true - } - } - } -} else { - template("chip_test") { - group(target_name) { - } - group(target_name + ".lib") { - } - not_needed(invoker, "*") - } -} diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 60f29346a48fa6..de6b7c16848eb5 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -14,13 +14,20 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") -import("${chip_root}/build/chip/chip_test.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") assert(chip_build_tests) +declare_args() { + # These may be overridden in args.gni to build platform-specific test binaries. + test_executable_output_name = "" + test_executable_output_name_suffix = "" + test_executable_ldflags = [] +} + # Define CHIP unit tests # # Simple usage @@ -41,50 +48,34 @@ assert(chip_build_tests) # "${chip_root}/src/lib/foo", # add dependencies here # ] # } -# -# -# Deprecated usage (writing own driver files): -# -# chip_test_suite("tests") { -# output_name = "libFooTests" -# -# sources = [ -# "TestDeclarations.h", -# "TestFoo.cpp", -# "TestBar.cpp", -# ] -# -# public_deps = [ -# "${chip_root}/src/lib/foo", # add dependencies here -# ] -# -# tests = [ -# "TestFoo", # Assumes TestFooDriver.cpp exists -# "TestBar", # Assumes TestBarDriver.cpp exists -# ] -# } # template("chip_test_suite") { _suite_name = target_name - # Ensures that the common library has sources containing both common - # and individual unit tests. - if (!defined(invoker.sources)) { - invoker.sources = [] - } - - if (defined(invoker.test_sources)) { - invoker.sources += invoker.test_sources + exclude_variables = [ "tests" ] + if (chip_link_tests && chip_device_platform != "darwin") { + # Common library shouldn't have all the individual unit tests, only the common sources. + exclude_variables += [ "test_sources" ] + # NOTE: For `Build on Darwin (clang, python_lib, simulated)` the test_sources must be in common lib. + } else { + # Common library should have all the individual unit tests, in addition to the common sources. + if (!defined(invoker.sources)) { + invoker.sources = [] + } + if (defined(invoker.test_sources)) { + invoker.sources += invoker.test_sources + } } + # Target for the common library. Contains all the common sources, and sometimes all the individual test sources. if (chip_build_test_static_libraries) { _target_type = "static_library" } else { _target_type = "source_set" } target(_target_type, "${_suite_name}.lib") { - forward_variables_from(invoker, "*", [ "tests" ]) + forward_variables_from(invoker, "*", exclude_variables) output_dir = "${root_out_dir}/lib" @@ -102,6 +93,8 @@ template("chip_test_suite") { public_deps += [ "${chip_root}/src/platform/logging:default" ] } } + + # Build a source_set or a flashable executable for each individual unit test source, which also includes the common files. if (chip_link_tests) { tests = [] @@ -115,6 +108,7 @@ template("chip_test_suite") { } pw_test(_test_name) { + # Forward certain variables from the invoker. forward_variables_from(invoker, [ "deps", @@ -122,43 +116,30 @@ template("chip_test_suite") { "cflags", "configs", ]) + + # Link to the common lib for this suite so we get its `sources`. public_deps += [ ":${_suite_name}.lib" ] - sources = [ _test ] - output_dir = _test_output_dir - } - tests += [ _test_name ] - } - } - if (defined(invoker.tests)) { - foreach(_test, invoker.tests) { - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } + # Set variables that the platform executable may need. + if (test_executable_output_name != "") { + output_name = test_executable_output_name + _test_name + + test_executable_output_name_suffix + } + ldflags = test_executable_ldflags + + # Add the individual test source file (e.g. "TestSomething.cpp"). + sources = [ _test ] - pw_test(_test) { - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - public_deps += [ ":${_suite_name}.lib" ] - test_main = "" - sources = [ - "${_test}.cpp", - "${_test}Driver.cpp", - ] output_dir = _test_output_dir } - tests += [ _test ] + tests += [ _test_name ] } } group(_suite_name) { deps = [] + + # Add each individual unit test. foreach(_test, tests) { deps += [ ":${_test}" ] } @@ -167,6 +148,8 @@ template("chip_test_suite") { if (chip_pw_run_tests) { group("${_suite_name}_run") { deps = [] + + # Add the .run targets created by pw_test. foreach(_test, tests) { deps += [ ":${_test}.run" ] } diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index 6233d58382b43d..b7f96b95f46f08 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -86,6 +86,10 @@ template("gen_flashing_script") { template("flashable_executable") { executable_target = "$target_name.executable" + if (!defined(invoker.output_dir)) { + invoker.output_dir = root_out_dir + } + if (defined(invoker.flashing_script_name)) { # Generating the flashing script is the final target. final_target = "$target_name.flashing" @@ -110,7 +114,10 @@ template("flashable_executable") { data_deps += invoker.data_deps } - write_runtime_deps = "${root_out_dir}/${flashbundle_name}" + # Invoker can stop this template from creating the flashbundle.txt by setting flashbundle_name to empty string. + if (flashbundle_name != "") { + write_runtime_deps = "${invoker.output_dir}/${flashbundle_name}" + } } if (defined(invoker.objcopy_image_name)) { @@ -124,8 +131,8 @@ template("flashable_executable") { objcopy = invoker.objcopy objcopy_convert(image_target) { - conversion_input = "${root_out_dir}/${invoker.output_name}" - conversion_output = "${root_out_dir}/${image_name}" + conversion_input = "${invoker.output_dir}/${invoker.output_name}" + conversion_output = "${invoker.output_dir}/${image_name}" conversion_target_format = image_format deps = [ ":$executable_target" ] } @@ -141,7 +148,8 @@ template("flashable_executable") { gen_flashing_script("$target_name.flashing") { flashing_script_generator = invoker.flashing_script_generator flashing_script_inputs = invoker.flashing_script_inputs - flashing_script_name = "$root_out_dir/${invoker.flashing_script_name}" + flashing_script_name = + "${invoker.output_dir}/${invoker.flashing_script_name}" if (defined(invoker.flashing_options)) { flashing_options = invoker.flashing_options } else { @@ -155,7 +163,7 @@ template("flashable_executable") { flashing_options += [ "--application", - rebase_path(image_name, root_out_dir, root_out_dir), + rebase_path(image_name, invoker.output_dir, invoker.output_dir), ] data_deps = [ ":$image_target" ] } diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 3972dc7bb48eff..6545f75b55da6b 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import glob +import logging import os import shlex import subprocess @@ -78,7 +80,7 @@ def FlashBundleName(self): elif self == Efr32App.PUMP: return 'pump_app.flashbundle.txt' elif self == Efr32App.UNIT_TEST: - return 'efr32_device_tests.flashbundle.txt' + return os.path.join('tests', 'efr32_device_tests.flashbundle.txt') else: raise Exception('Unknown app type: %r' % self) @@ -259,27 +261,64 @@ def __init__(self, def GnBuildArgs(self): return self.extra_gn_options + def _bundle(self): + # Only unit-test needs to generate the flashbundle here. All other examples will generate a flashbundle via the silabs_executable template. + if self.app == Efr32App.UNIT_TEST: + flash_bundle_path = os.path.join(self.output_dir, self.app.FlashBundleName()) + logging.info(f'Generating flashbundle {flash_bundle_path}') + + patterns = [ + os.path.join(self.output_dir, "tests", "*.flash.py"), + os.path.join(self.output_dir, "tests", "*.s37"), + os.path.join(self.output_dir, "tests", "silabs_firmware_utils.py"), + os.path.join(self.output_dir, "tests", "firmware_utils.py"), + ] + + # Generate the list of files by globbing each pattern. + files = [] + for pattern in patterns: + files.extend([os.path.basename(x) for x in glob.glob(pattern)]) + + # Create the bundle file. + with open(flash_bundle_path, 'w') as bundle_file: + bundle_file.write("\n".join(files)) + def build_outputs(self): extensions = ["out", "hex"] if self.options.enable_link_map_file: extensions.append("out.map") - for ext in extensions: - name = f"{self.app.AppNamePrefix()}.{ext}" - yield BuilderOutput(os.path.join(self.output_dir, name), name) + + if self.app == Efr32App.UNIT_TEST: + # Efr32 unit-test generates the "tests" subdir with a set of files for each individual unit test source. + for ext in extensions: + pattern = os.path.join(self.output_dir, "tests", f"*.{ext}") + for name in [os.path.basename(x) for x in glob.glob(pattern)]: + yield BuilderOutput(os.path.join(self.output_dir, "tests", name), name) + else: + # All other examples have just one set of files. + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) if self.app == Efr32App.UNIT_TEST: # Include test runner python wheels - for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): + for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_pw_test_runner_wheels')): for file in files: yield BuilderOutput( os.path.join(root, file), - os.path.join("chip_nl_test_runner_wheels", file)) + os.path.join("chip_pw_test_runner_wheels", file)) - # Figure out flash bundle files and build accordingly + def bundle_outputs(self): + # If flashbundle creation is enabled, the outputs will include the s37 and flash.py files, plus the two firmware utils scripts that support flash.py. + # For the unit-test example, there will be a s37 and flash.py file for each unit test source. with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: for name in filter(None, [x.strip() for x in f.readlines()]): + if self.app == Efr32App.UNIT_TEST: + sourcepath = os.path.join(self.output_dir, "tests", name) # Unit tests are in the "tests" subdir. + else: + sourcepath = os.path.join(self.output_dir, name) yield BuilderOutput( - os.path.join(self.output_dir, name), + sourcepath, os.path.join("flashbundle", name)) def generate(self): diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index b69421a782e948..01b35c7a01185f 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -220,7 +220,7 @@ def OutputNames(self): elif self == HostApp.PYTHON_BINDINGS: yield 'controller/python' # Directory containing WHL files elif self == HostApp.EFR32_TEST_RUNNER: - yield 'chip_nl_test_runner_wheels' + yield 'chip_pw_test_runner_wheels' elif self == HostApp.TV_CASTING: yield 'chip-tv-casting-app' yield 'chip-tv-casting-app.map' diff --git a/scripts/flashing/firmware_utils.py b/scripts/flashing/firmware_utils.py index 6087360c0614ac..2b844e8e3eb550 100644 --- a/scripts/flashing/firmware_utils.py +++ b/scripts/flashing/firmware_utils.py @@ -23,6 +23,7 @@ import subprocess import sys import textwrap +import traceback # Here are the options that can be use to configure a `Flasher` # object (as dictionary keys) and/or passed as command line options. @@ -409,7 +410,11 @@ def make_wrapper(self, argv): # Give platform-specific code a chance to manipulate the arguments # for the wrapper script. - self._platform_wrapper_args(args) + try: + self._platform_wrapper_args(args) + except OSError: + traceback.print_last() + return 1 # Find any option values that differ from the class defaults. # These will be inserted into the wrapper script. @@ -445,7 +450,7 @@ def make_wrapper(self, argv): os.chmod(args.output, (stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXGRP | stat.S_IRGRP | stat.S_IXOTH | stat.S_IROTH)) - except OSError as exception: - print(exception, sys.stderr) + except OSError: + traceback.print_last() return 1 return 0 diff --git a/scripts/flashing/silabs_firmware_utils.py b/scripts/flashing/silabs_firmware_utils.py index 5e0a689f5a62f4..bd7b64cf021bcd 100755 --- a/scripts/flashing/silabs_firmware_utils.py +++ b/scripts/flashing/silabs_firmware_utils.py @@ -49,6 +49,8 @@ Do not reset device after flashing """ +import os +import shutil import sys import firmware_utils @@ -169,6 +171,42 @@ def actions(self): return self + def _platform_wrapper_args(self, args): + """Called from make_wrapper() to optionally manipulate arguments.""" + # Generate the flashbundle.txt file and copy the firmware utils. + if args.flashbundle_file is not None: + # Generate the flashbundle contents. + # Copy the platform-specific and general firmware utils to the same directory as the wrapper. + flashbundle_contents = os.path.basename(args.output) + if args.application is not None: + flashbundle_contents += "\n" + os.path.basename(args.application) + output_dir = os.path.dirname(args.output) or "." + if args.platform_firmware_utils is not None: + flashbundle_contents += "\n" + os.path.basename(args.platform_firmware_utils) + shutil.copy(args.platform_firmware_utils, output_dir) + if args.firmware_utils is not None: + flashbundle_contents += "\n" + os.path.basename(args.firmware_utils) + shutil.copy(args.firmware_utils, output_dir) + + # Create the flashbundle file. + with open(args.flashbundle_file, 'w') as flashbundle_file: + flashbundle_file.write(flashbundle_contents.strip()) + + def make_wrapper(self, argv): + self.parser.add_argument( + '--flashbundle-file', + metavar='FILENAME', + help='path and name of the flashbundle text file to create') + self.parser.add_argument( + '--platform-firmware-utils', + metavar='FILENAME', + help='path and file of the platform-specific firmware utils script') + self.parser.add_argument( + '--firmware-utils', + metavar='FILENAME', + help='path and file of the general firmware utils script') + super().make_wrapper(argv) + if __name__ == '__main__': sys.exit(Flasher().flash_command(sys.argv)) diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index b15b16864548c9..0d10cb8d76a475 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -19,7 +19,6 @@ import("//build_overrides/pigweed.gni") import("${build_root}/config/defaults.gni") import("${efr32_sdk_build_root}/efr32_sdk.gni") -import("${efr32_sdk_build_root}/silabs_executable.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") import("${chip_root}/src/platform/device.gni") @@ -62,9 +61,8 @@ efr32_sdk("sdk") { ] } -silabs_executable("efr32_device_tests") { - output_name = "matter-silabs-device_tests.out" - +# This is the test runner. `pw_test` will dep this for each `silabs_executable` target. +source_set("efr32_test_main") { defines = [ "PW_RPC_ENABLED" ] sources = [ "${chip_root}/examples/common/pigweed/RpcService.cpp", @@ -83,7 +81,6 @@ silabs_executable("efr32_device_tests") { "$dir_pw_unit_test:rpc_service", "${chip_root}/config/efr32/lib/pw_rpc:pw_rpc", "${chip_root}/examples/common/pigweed:system_rpc_server", - "${chip_root}/src:tests", "${chip_root}/src/lib", "${chip_root}/src/lib/support:pw_tests_wrapper", "${chip_root}/src/platform/silabs/provision:provision-headers", @@ -106,27 +103,18 @@ silabs_executable("efr32_device_tests") { ] include_dirs = [ "${chip_root}/examples/common/pigweed/efr32" ] - - ldscript = "${examples_common_plat_dir}/ldscripts/${silabs_family}.ld" - - inputs = [ ldscript ] - - ldflags = [ - "-T" + rebase_path(ldscript, root_build_dir), - "-Wl,--no-warn-rwx-segment", - ] - - output_dir = root_out_dir } +# This target is referred to by BuildRoot in scripts/build/builders/efr32.py, as well as the example in README.md. +# It builds the root target "src:tests", which builds the chip_test_suite target in each test directory, which builds a pw_test target for each test source file, which builds a silabs_executable, which includes the "efr32_test_main" target defined above. group("efr32") { - deps = [ ":efr32_device_tests" ] + deps = [ "${chip_root}/src:tests" ] } group("runner") { deps = [ - "${efr32_project_dir}/py:nl_test_runner.install", - "${efr32_project_dir}/py:nl_test_runner_wheel", + "${efr32_project_dir}/py:pw_test_runner.install", + "${efr32_project_dir}/py:pw_test_runner_wheel", ] } diff --git a/src/test_driver/efr32/README.md b/src/test_driver/efr32/README.md index c36812e484fdee..c846426890abaa 100644 --- a/src/test_driver/efr32/README.md +++ b/src/test_driver/efr32/README.md @@ -1,6 +1,6 @@ #CHIP EFR32 Test Driver -This builds and runs the NLUnitTest on the efr32 device +This builds and runs the unit tests on the efr32 device.
@@ -14,9 +14,9 @@ This builds and runs the NLUnitTest on the efr32 device ## Introduction -This builds a test binary which contains the NLUnitTests and can be flashed onto -a device. The device is controlled using the included RPCs, through the python -test runner. +This builds a set of test binaries which contain the unit tests and can be +flashed onto a device. The device is controlled using the included RPCs, through +the python test runner. @@ -83,7 +83,7 @@ Or build using build script from the root ``` cd - ./scripts/build/build_examples.py --target linux-x64-nl-test-runner build + ./scripts/build/build_examples.py --target linux-x64-pw-test-runner build ``` The runner will be installed into the venv and python wheels will be packaged in @@ -92,7 +92,7 @@ the output folder for deploying. Then the python wheels need to installed using pip3. ``` - pip3 install out/debug/chip_nl_test_runner_wheels/*.whl + pip3 install out/debug/chip_pw_test_runner_wheels/*.whl ``` Other python libraries may need to be installed such as @@ -101,8 +101,8 @@ Other python libraries may need to be installed such as pip3 install pyserial ``` -- To run the tests: +- To run all tests: ``` - python -m nl_test_runner.nl_test_runner -d /dev/ttyACM1 -f out/debug/matter-silabs-device_tests.s37 -o out.log + python -m pw_test_runner.pw_test_runner -d /dev/ttyACM1 -f out/debug/matter-silabs-device_tests.s37 -o out.log ``` diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 71bf093f3e3a16..f7f52398a5889e 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -17,14 +17,15 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/config/efr32/lib/pw_rpc/pw_rpc.gni") import("${chip_root}/examples/platform/silabs/args.gni") import("${chip_root}/src/platform/silabs/efr32/args.gni") +import("${chip_root}/third_party/silabs/silabs_board.gni") # silabs_family silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_pw_rpc = true chip_build_tests = true +chip_link_tests = true chip_enable_openthread = true chip_openthread_ftd = false # use mtd as it is smaller. -chip_monolithic_tests = true openthread_external_platform = "${chip_root}/third_party/openthread/platforms/efr32:libopenthread-efr32" @@ -35,3 +36,19 @@ pw_assert_BACKEND = "$dir_pw_assert_log" pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" + +# Override the executable type and the test main's target. +pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" +pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = + "${efr32_sdk_build_root}/silabs_executable.gni" +pw_unit_test_MAIN = "//:efr32_test_main" + +# Additional variables needed by silabs_executable that must be passed in to pw_test. +test_executable_output_name = "matter-silabs-device_tests-" +test_executable_output_name_suffix = ".out" +_ldscript = + "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" +test_executable_ldflags = [ + "-T" + rebase_path(_ldscript, root_build_dir), + "-Wl,--no-warn-rwx-segment", +] diff --git a/src/test_driver/efr32/py/BUILD.gn b/src/test_driver/efr32/py/BUILD.gn index 615fe5603d00c9..6f36e8f3e4a839 100644 --- a/src/test_driver/efr32/py/BUILD.gn +++ b/src/test_driver/efr32/py/BUILD.gn @@ -19,32 +19,6 @@ import("$dir_pw_build/python.gni") import("$dir_pw_build/python_dist.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") -# TODO [PW_MIGRATION]: remove nl test runner script once transition away from nlunit-test is completed -pw_python_package("nl_test_runner") { - setup = [ - "pyproject.toml", - "setup.cfg", - "setup.py", - ] - - sources = [ - "nl_test_runner/__init__.py", - "nl_test_runner/nl_test_runner.py", - ] - - python_deps = [ - "$dir_pw_hdlc/py", - "$dir_pw_protobuf_compiler/py", - "$dir_pw_rpc/py", - "${chip_root}/src/test_driver/efr32:nl_test_service.python", - ] -} - -pw_python_wheels("nl_test_runner_wheel") { - packages = [ ":nl_test_runner" ] - directory = "$root_out_dir/chip_nl_test_runner_wheels" -} - pw_python_package("pw_test_runner") { setup = [ "pw_test_runner/pyproject.toml", diff --git a/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py b/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py deleted file mode 100644 index 0fdb2e7aea7e3d..00000000000000 --- a/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright (c) 2021 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import argparse -import logging -import subprocess -import sys -import time -from typing import Any - -import serial # type: ignore -from pw_hdlc import rpc - -# RPC Protos -from nl_test_service import nl_test_pb2 # isort:skip - -PW_LOG = logging.getLogger(__name__) - -PROTOS = [nl_test_pb2] - - -class colors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - - -PASS_STRING = colors.OKGREEN + u'\N{check mark}' + colors.ENDC -FAIL_STRING = colors.FAIL + 'FAILED' + colors.ENDC - - -def _parse_args(): - """Parses and returns the command line arguments.""" - parser = argparse.ArgumentParser( - description="CHIP on device unit test runner.") - parser.add_argument('-d', '--device', help='the serial port to use') - parser.add_argument('-b', - '--baudrate', - type=int, - default=115200, - help='the baud rate to use') - parser.add_argument('-f', '--flash_image', - help='a firmware image which will be flashed berfore runnning the test') - parser.add_argument( - '-o', - '--output', - type=argparse.FileType('wb'), - default=sys.stdout.buffer, - help=('The file to which to write device output (HDLC channel 1); ' - 'provide - or omit for stdout.')) - return parser.parse_args() - - -def flash_device(device: str, flash_image: str, **kwargs): - """flashes the EFR32 device using commander""" - err = subprocess.call( - ['commander', 'flash', '--device', 'EFR32', flash_image]) - if err: - raise Exception("flash failed") - - -def get_hdlc_rpc_client(device: str, baudrate: int, output: Any, **kwargs): - """Get the HdlcRpcClient based on arguments.""" - serial_device = serial.Serial(device, baudrate, timeout=1) - reader = rpc.SerialReader(serial_device, 8192) - write = serial_device.write - return rpc.HdlcRpcClient(reader, PROTOS, rpc.default_channels(write), - lambda data: rpc.write_to_file(data, output)) - - -def runner(client) -> int: - """ Run the tests""" - def on_error_callback(call_object, error): - raise Exception("Error running test RPC: {}".format(error)) - - rpc = client.client.channel(1).rpcs.chip.rpc.NlTest.Run - invoke = rpc.invoke(rpc.request(), on_error=on_error_callback) - - total_failed = 0 - total_run = 0 - for streamed_data in invoke.get_responses(): - if streamed_data.HasField("test_suite_start"): - print("\n{}".format( - colors.HEADER + streamed_data.test_suite_start.suite_name) + colors.ENDC) - if streamed_data.HasField("test_case_run"): - print("\t{}: {}".format(streamed_data.test_case_run.test_case_name, - FAIL_STRING if streamed_data.test_case_run.failed else PASS_STRING)) - if streamed_data.HasField("test_suite_tests_run_summary"): - total_run += streamed_data.test_suite_tests_run_summary.total_count - total_failed += streamed_data.test_suite_tests_run_summary.failed_count - print("{}Total tests failed: {} of {}".format( - colors.OKGREEN if streamed_data.test_suite_tests_run_summary.failed_count == 0 else colors.FAIL, - streamed_data.test_suite_tests_run_summary.failed_count, - streamed_data.test_suite_tests_run_summary.total_count) + colors.ENDC) - if streamed_data.HasField("test_suite_asserts_summary"): - print("{}Total asserts failed: {} of {}".format( - colors.OKGREEN if streamed_data.test_suite_asserts_summary.failed_count == 0 else colors.FAIL, - streamed_data.test_suite_asserts_summary.failed_count, - streamed_data.test_suite_asserts_summary.total_count) + colors.ENDC) - for step in ["test_suite_setup", "test_suite_teardown", "test_case_initialize", "test_case_terminate"]: - if streamed_data.HasField(step): - print(colors.OKCYAN + "\t{}: {}".format(step, - FAIL_STRING if getattr(streamed_data, step).failed else PASS_STRING)) - print(colors.OKBLUE + colors.BOLD + - "\n\nAll tests completed" + colors.ENDC) - print("{}Total of all tests failed: {} of {}".format( - colors.OKGREEN if total_failed == 0 else colors.FAIL, - total_failed, total_run) + colors.ENDC) - return total_failed - - -def main() -> int: - args = _parse_args() - if args.flash_image: - flash_device(**vars(args)) - time.sleep(1) # Give time for device to boot - with get_hdlc_rpc_client(**vars(args)) as client: - return runner(client) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/src/test_driver/efr32/py/nl_test_runner/__init__.py b/src/test_driver/efr32/py/pw_test_runner/__init__.py similarity index 100% rename from src/test_driver/efr32/py/nl_test_runner/__init__.py rename to src/test_driver/efr32/py/pw_test_runner/__init__.py diff --git a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py index c8fca307f015ff..8e10903920cc77 100644 --- a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py +++ b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py @@ -16,6 +16,7 @@ # import argparse +import glob import logging import os import subprocess @@ -60,7 +61,7 @@ def _parse_args(): parser.add_argument( "-f", "--flash_image", - help="a firmware image which will be flashed berfore runnning the test", + help="A firmware image which will be flashed berfore runnning the test. Or a directory containing firmware images, each of which will be flashed and then run.", ) parser.add_argument( "-o", @@ -75,7 +76,7 @@ def _parse_args(): return parser.parse_args() -def flash_device(device: str, flash_image: str, **kwargs): +def flash_device(device: str, flash_image: str): """flashes the EFR32 device using commander""" err = subprocess.call( ["commander", "flash", "--device", "EFR32", flash_image]) @@ -96,22 +97,41 @@ def get_hdlc_rpc_client(device: str, baudrate: int, output: Any, **kwargs): ) -def runner(client: rpc.HdlcRpcClient) -> int: - """Run the tests""" +def run(args) -> int: + """Run the tests. Return the number of failed tests.""" + with get_hdlc_rpc_client(**vars(args)) as client: + test_records = run_tests(client.rpcs()) + return len(test_records.failing_tests) - test_records = run_tests(client.rpcs()) - return len(test_records.failing_tests) +def list_images(flash_directory: str) -> list[str]: + filenames: list[str] = glob.glob(os.path.join(flash_directory, "*.s37")) + return list(map(lambda x: os.path.join(flash_directory, x), filenames)) def main() -> int: args = _parse_args() - if args.flash_image: - flash_device(**vars(args)) - time.sleep(1) # Give time for device to boot - with get_hdlc_rpc_client(**vars(args)) as client: - return runner(client) + failures = 0 + if args.flash_image: + if os.path.isdir(args.flash_image): + images = list_images(args.flash_image) + if not images: + raise Exception(f"No images found in `{args.flash_image}`") + elif os.path.isfile(args.flash_image): + images = [args.flash_image] + else: + raise Exception(f"File or directory not found `{args.flash_image}`") + + for image in images: + flash_device(args.device, image) + time.sleep(1) # Give time for device to boot + + failures += run(args) + else: # No image provided. Just run what's on the device. + failures += run(args) + + return failures if __name__ == "__main__": diff --git a/src/test_driver/efr32/py/setup.cfg b/src/test_driver/efr32/py/setup.cfg index 77108ab8288747..cb949a38092b07 100644 --- a/src/test_driver/efr32/py/setup.cfg +++ b/src/test_driver/efr32/py/setup.cfg @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. [metadata] -name = nl_test_runner +name = pw_test_runner version = 0.0.1 [options] diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index a639a4d19ae62d..37b853c5df84b8 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -47,64 +47,93 @@ template("generate_rps_file") { } template("silabs_executable") { + # output_dir is optional and will default to root_out_dir + if (!defined(invoker.output_dir)) { + invoker.output_dir = root_out_dir + } + + # output_name is optional and will default to "$target_name.bin" + if (!defined(invoker.output_name)) { + invoker.output_name = target_name + ".bin" + } + output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".s37" objcopy_image_format = "srec" objcopy = "arm-none-eabi-objcopy" - # Copy flashing dependencies to the output directory so that the output - # is collectively self-contained; this allows flashing to work reliably - # even if the build and flashing steps take place on different machines - # or in different containers. - if (use_rps_extension) { flashing_image_name = output_base_name + ".rps" } - flashing_runtime_target = target_name + ".flashing_runtime" - flashing_script_inputs = [ - "${chip_root}/scripts/flashing/silabs_firmware_utils.py", - "${chip_root}/scripts/flashing/firmware_utils.py", - ] - copy(flashing_runtime_target) { - sources = flashing_script_inputs - outputs = [ "${root_out_dir}/{{source_file_part}}" ] - } + # flashable_executable calls a generator script to do the following: + # Create a flash.py script with the name of the binary hardcoded in it. + # Copy flashing dependencies to the output directory so that the output + # is collectively self-contained; this allows flashing to work reliably + # even if the build and flashing steps take place on different machines + # or in different containers. + # Create *.flashbundle.txt with a list of all files needed for flashing flashing_script_generator = "${chip_root}/scripts/flashing/gen_flashing_script.py" flashing_script_name = output_base_name + ".flash.py" - flashing_options = [ "silabs" ] + _flashbundle_file = "${invoker.output_dir}/${target_name}.flashbundle.txt" + _platform_firmware_utils = + "${chip_root}/scripts/flashing/silabs_firmware_utils.py" + _firmware_utils = "${chip_root}/scripts/flashing/firmware_utils.py" + flashing_options = [ + # Use module "{platform}_firmware_utils.py" + "silabs", + + # flashbundle.txt file to create. + "--flashbundle-file", + rebase_path(_flashbundle_file, root_build_dir), + + # Platform-specific firmware module to copy. + "--platform-firmware-utils", + rebase_path(_platform_firmware_utils, root_build_dir), + # General firmware module to copy. + "--firmware-utils", + rebase_path(_firmware_utils, root_build_dir), + ] + flashing_script_inputs = [ + _platform_firmware_utils, + _firmware_utils, + ] + flashbundle_name = "" # Stop flashable_executable from making flashbundle. + + # Target to generate the s37 file, flashing script, and flashbundle. flash_target_name = target_name + ".flash_executable" - flashbundle_name = "${target_name}.flashbundle.txt" flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") - data_deps = [ ":${flashing_runtime_target}" ] } - # Add a target which generates the hex file in addition to s37. + # Target to generate the hex file. executable_target = "$flash_target_name.executable" hex_image_name = output_base_name + ".hex" hex_target_name = target_name + ".hex" objcopy_convert(hex_target_name) { - conversion_input = "${root_out_dir}/${invoker.output_name}" - conversion_output = "${root_out_dir}/${hex_image_name}" + conversion_input = "${invoker.output_dir}/${invoker.output_name}" + conversion_output = "${invoker.output_dir}/${hex_image_name}" conversion_target_format = "ihex" deps = [ ":$executable_target" ] } + # Target to generate the rps file. if (use_rps_extension) { rps_target_name = target_name + ".rps" generate_rps_file(rps_target_name) { - conversion_input = "${root_out_dir}/${objcopy_image_name}" - conversion_output = "${root_out_dir}/${flashing_image_name}" + conversion_input = "${invoker.output_dir}/${objcopy_image_name}" + conversion_output = "${invoker.output_dir}/${flashing_image_name}" deps = [ ":$executable_target", ":$flash_target_name.image", ] } } + + # Main target that deps the targets defined above. group(target_name) { deps = [ ":$flash_target_name", From 19e7aa39bb6452d8777d9d13d4d4adb83b929fca Mon Sep 17 00:00:00 2001 From: William Date: Wed, 4 Sep 2024 18:37:36 +0100 Subject: [PATCH 48/70] Added a CopyCharSpanToMutableCharSpanTruncate function. (#35360) * Added a CopyCharSpanToMutableCharSpanTruncate function. * Applied minor renaming suggestion. * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Update src/lib/support/Span.h Co-authored-by: Arkadiusz Bokowy --------- Co-authored-by: Boris Zbarsky Co-authored-by: Arkadiusz Bokowy --- src/lib/support/Span.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/lib/support/Span.h b/src/lib/support/Span.h index 2e6627d937e560..bba719e69e779c 100644 --- a/src/lib/support/Span.h +++ b/src/lib/support/Span.h @@ -390,4 +390,18 @@ inline CHIP_ERROR CopyCharSpanToMutableCharSpan(CharSpan cspan_to_copy, MutableC return CHIP_NO_ERROR; } +/** + * Copies a CharSpan into a MutableCharSpan. + * If the span_to_copy does not fit in out_span, span_to_copy is truncated to fit in out_span. + * @param span_to_copy The CharSpan to copy. + * @param out_span The MutableCharSpan in which span_to_copy is to be copied. + */ +inline void CopyCharSpanToMutableCharSpanWithTruncation(CharSpan span_to_copy, MutableCharSpan & out_span) +{ + size_t size_to_copy = std::min(span_to_copy.size(), out_span.size()); + + memcpy(out_span.data(), span_to_copy.data(), size_to_copy); + out_span.reduce_size(size_to_copy); +} + } // namespace chip From a5d5f856d171468581d716f17efa7c604066f062 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 4 Sep 2024 10:47:09 -0700 Subject: [PATCH 49/70] use imEngine to get case session in RefreshKeySender (#35236) --- src/app/icd/client/RefreshKeySender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/icd/client/RefreshKeySender.cpp b/src/app/icd/client/RefreshKeySender.cpp index c49bf79f30a17c..9e4547538e679e 100644 --- a/src/app/icd/client/RefreshKeySender.cpp +++ b/src/app/icd/client/RefreshKeySender.cpp @@ -87,7 +87,7 @@ CHIP_ERROR RefreshKeySender::RegisterClientWithNewKey(Messaging::ExchangeManager CHIP_ERROR RefreshKeySender::EstablishSessionToPeer() { ChipLogProgress(ICD, "Trying to establish a CASE session for re-registering an ICD client"); - auto * caseSessionManager = InteractionModelEngine::GetInstance()->GetCASESessionManager(); + auto * caseSessionManager = mpImEngine->GetCASESessionManager(); VerifyOrReturnError(caseSessionManager != nullptr, CHIP_ERROR_INVALID_CASE_PARAMETER); caseSessionManager->FindOrEstablishSession(mICDClientInfo.peer_node, &mOnConnectedCallback, &mOnConnectionFailureCallback); return CHIP_NO_ERROR; From 95339255e05669ce452bbc7061e548dfd357c348 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 15:04:33 -0400 Subject: [PATCH 50/70] IDM-10.2: Handle MACL feature (#35404) * Reapply "TC-IDM-10.2: Add check for MACL (#35086)" (#35111) This reverts commit 796394ffadb6d0322a16eb5eabfb28950c8e6116. * Change function name to more generic --- .github/workflows/tests.yaml | 1 + src/python_testing/TC_DeviceConformance.py | 25 ++++++ src/python_testing/TestConformanceTest.py | 96 ++++++++++++++++++++++ src/python_testing/execute_python_tests.py | 1 + 4 files changed, 123 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a99cc0a24d1f98..8d8b0064202c9d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -522,6 +522,7 @@ jobs: scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingSupport.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceTest.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceSupport.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceTest.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestChoiceConformanceSupport.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_IDM_10_4.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_TC_SC_7_1.py' diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 060228a5170f17..a6d6f19bfb53e7 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -50,6 +50,24 @@ async def setup_class_helper(self): self.xml_device_types, problems = build_xml_device_types() self.problems.extend(problems) + def _get_device_type_id(self, device_type_name: str) -> int: + id = [id for id, dt in self.xml_device_types.items() if dt.name.lower() == device_type_name.lower()] + if len(id) != 1: + self.fail_current_test(f"Unable to find {device_type_name} device type") + return id[0] + + def _has_device_type_supporting_macl(self): + # Currently this is just NIM. We may later be able to pull this from the device type scrape using the ManagedAclAllowed condition, + # but these are not currently exposed directly by the device. + allowed_ids = [self._get_device_type_id('network infrastructure manager')] + for endpoint in self.endpoints_tlv.values(): + desc = Clusters.Descriptor + device_types = [dt.deviceType for dt in endpoint[desc.id][desc.Attributes.DeviceTypeList.attribute_id]] + if set(allowed_ids).intersection(set(device_types)): + # TODO: it's unclear if this needs to be present on every endpoint. Right now, this assumes one is sufficient. + return True + return False + def check_conformance(self, ignore_in_progress: bool, is_ci: bool, allow_provisional: bool): problems = [] success = True @@ -120,6 +138,13 @@ def record_warning(location, problem): for f in feature_masks: location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=GlobalAttributeIds.FEATURE_MAP_ID) + if cluster_id == Clusters.AccessControl.id and f == Clusters.AccessControl.Bitmaps.Feature.kManagedDevice: + # Managed ACL is treated as a special case because it is only allowed if other endpoints support NIM and disallowed otherwise. + if not self._has_device_type_supporting_macl(): + record_error( + location=location, problem="MACL feature is disallowed if the a supported device type is not present") + continue + if f not in self.xml_clusters[cluster_id].features.keys(): record_error(location=location, problem=f'Unknown feature with mask 0x{f:02x}') continue diff --git a/src/python_testing/TestConformanceTest.py b/src/python_testing/TestConformanceTest.py index 23b06fb67c7e2a..5af8d1f639ef0c 100644 --- a/src/python_testing/TestConformanceTest.py +++ b/src/python_testing/TestConformanceTest.py @@ -18,6 +18,8 @@ from typing import Any import chip.clusters as Clusters +from conformance_support import ConformanceDecision +from global_attribute_ids import GlobalAttributeIds from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts from spec_parsing_support import build_xml_clusters, build_xml_device_types @@ -109,6 +111,10 @@ def create_onoff_endpoint(endpoint: int) -> dict[int, dict[int, dict[int, Any]]] return endpoint_tlv +def is_mandatory(conformance): + return conformance(0, [], []).decision == ConformanceDecision.MANDATORY + + class TestConformanceSupport(MatterBaseTest, DeviceConformanceTests): def setup_class(self): self.xml_clusters, self.problems = build_xml_clusters() @@ -135,6 +141,96 @@ async def test_provisional_cluster(self): success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=False) asserts.assert_true(success, "Unexpected failure parsing endpoint with no clusters marked as provisional") + def _create_minimal_cluster(self, cluster_id: int) -> dict[int, Any]: + attrs = {} + attrs[GlobalAttributeIds.FEATURE_MAP_ID] = 0 + + mandatory_attributes = [id for id, a in self.xml_clusters[cluster_id].attributes.items() if is_mandatory(a.conformance)] + for m in mandatory_attributes: + # dummy versions - we're not using the values in this test + attrs[m] = 0 + attrs[GlobalAttributeIds.ATTRIBUTE_LIST_ID] = mandatory_attributes + mandatory_accepted_commands = [id for id, a in self.xml_clusters[cluster_id].accepted_commands.items() + if is_mandatory(a.conformance)] + attrs[GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID] = mandatory_accepted_commands + mandatory_generated_commands = [id for id, a in self.xml_clusters[cluster_id].generated_commands.items() + if is_mandatory(a.conformance)] + attrs[GlobalAttributeIds.GENERATED_COMMAND_LIST_ID] = mandatory_generated_commands + attrs[GlobalAttributeIds.CLUSTER_REVISION_ID] = self.xml_clusters[cluster_id].revision + return attrs + + def _create_minimal_dt(self, device_type_id: int) -> dict[int, dict[int, Any]]: + ''' Creates the internals of an endpoint_tlv with the minimal set of clusters, with the minimal set of attributes and commands. Global attributes only. + Does NOT take into account overrides yet. + ''' + endpoint_tlv = {} + required_servers = [id for id, c in self.xml_device_types[device_type_id].server_clusters.items() + if is_mandatory(c.conformance)] + required_clients = [id for id, c in self.xml_device_types[device_type_id].client_clusters.items() + if is_mandatory(c.conformance)] + device_type_revision = self.xml_device_types[device_type_id].revision + + for s in required_servers: + endpoint_tlv[s] = self._create_minimal_cluster(s) + + # Descriptor + attr = Clusters.Descriptor.Attributes + attrs = {} + attrs[attr.FeatureMap.attribute_id] = 0 + attrs[attr.AcceptedCommandList.attribute_id] = [] + attrs[attr.GeneratedCommandList.attribute_id] = [] + attrs[attr.ClusterRevision.attribute_id] = self.xml_clusters[Clusters.Descriptor.id].revision + attrs[attr.DeviceTypeList.attribute_id] = [ + Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=device_type_revision)] + attrs[attr.ServerList.attribute_id] = required_servers + attrs[attr.ClientList.attribute_id] = required_clients + attrs[attr.PartsList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = [] + attrs[attr.AttributeList.attribute_id] = list(attrs.keys()) + + endpoint_tlv[Clusters.Descriptor.id] = attrs + return endpoint_tlv + + def add_macl(self, root_endpoint: dict[int, dict[int, Any]]): + ac = Clusters.AccessControl + root_endpoint[ac.id][ac.Attributes.FeatureMap.attribute_id] = ac.Bitmaps.Feature.kManagedDevice + root_endpoint[ac.id][ac.Attributes.Arl.attribute_id] = [] + root_endpoint[ac.id][ac.Attributes.CommissioningARL.attribute_id] = [] + root_endpoint[ac.id][ac.Attributes.AttributeList.attribute_id].extend([ + ac.Attributes.Arl.attribute_id, ac.Attributes.CommissioningARL.attribute_id]) + root_endpoint[ac.id][ac.Attributes.AcceptedCommandList.attribute_id].append(ac.Commands.ReviewFabricRestrictions.command_id) + root_endpoint[ac.id][ac.Attributes.GeneratedCommandList.attribute_id].append( + ac.Commands.ReviewFabricRestrictionsResponse.command_id) + + @async_test_body + async def test_macl_handling(self): + nim_id = self._get_device_type_id('network infrastructure manager') + root_node_id = self._get_device_type_id('root node') + on_off_id = self._get_device_type_id('On/Off Light') + + root = self._create_minimal_dt(device_type_id=root_node_id) + nim = self._create_minimal_dt(device_type_id=nim_id) + self.endpoints_tlv = {0: root, 1: nim} + asserts.assert_true(self._has_device_type_supporting_macl(), "Did not find supported device in generated device") + + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True) + self.problems.extend(problems) + asserts.assert_true(success, "Unexpected failure parsing minimal dt") + + self.add_macl(root) + # A MACL is allowed when there is a NIM, so this should succeed as well + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True) + self.problems.extend(problems) + asserts.assert_true(success, "Unexpected failure with NIM and MACL") + + # A MACL is not allowed when there is no NIM + self.endpoints_tlv[1] = self._create_minimal_dt(device_type_id=on_off_id) + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=True) + self.problems.extend(problems) + asserts.assert_false(success, "Unexpected success with On/Off and MACL") + + # TODO: what happens if there is a NIM and a non-NIM endpoint? + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/execute_python_tests.py b/src/python_testing/execute_python_tests.py index a1965ec6360392..956e252de6c8c2 100644 --- a/src/python_testing/execute_python_tests.py +++ b/src/python_testing/execute_python_tests.py @@ -85,6 +85,7 @@ def main(search_directory, env_file): "TestChoiceConformanceSupport.py", "TC_DEMTestBase.py", "choice_conformance_support.py", + "TestConformanceTest.py", # Unit test of the conformance test (TC_DeviceConformance) - does not run against an app. "TestIdChecks.py", "TestSpecParsingDeviceType.py", "TestConformanceTest.py", From 6b93a30e9d65e02a6db809fb4bd44a38bc5c21e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Josefsen?= <69624991+ReneJosefsen@users.noreply.github.com> Date: Wed, 4 Sep 2024 21:37:28 +0200 Subject: [PATCH 51/70] Update TC-CC-2_2 to match latest test plan (#35361) * Update TC-CC-2_2 to match latest test plan * Remove unused import --- src/python_testing/TC_CC_2_2.py | 259 +++++++++++++++++++------------- 1 file changed, 151 insertions(+), 108 deletions(-) diff --git a/src/python_testing/TC_CC_2_2.py b/src/python_testing/TC_CC_2_2.py index 2cd9aef8a09f35..c575ae81f5c2d3 100644 --- a/src/python_testing/TC_CC_2_2.py +++ b/src/python_testing/TC_CC_2_2.py @@ -35,7 +35,7 @@ from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, has_cluster, run_if_endpoint_matches) from mobly import asserts -from test_plan_support import commission_if_required, if_feature_supported, read_attribute, verify_success +from test_plan_support import commission_if_required, read_attribute, verify_success class TC_CC_2_3(MatterBaseTest): @@ -48,14 +48,14 @@ def default_timeout(self) -> int: def steps_TC_CC_2_2(self): THcommand = "Test Harness sends the" - def store_values(attr: str) -> str: - return f"TH stores the reported values of _{attr}_ in all incoming reports for _{attr}_ attribute, that contains data in _reportedCurrentHueValuesList_, over a period of 20 seconds." + def store_values(reportList: str, attr: str) -> str: + return f"TH stores the reported values of _{attr}_ in all incoming reports for _{attr}_ attribute, that contains data in _{reportList}_, over a period of 20 seconds." - def verify_entry_count(attr: str) -> str: - return f'TH verifies that _reportedCurrentHueValuesList_ does not contain more than 10 entries for _{attr}_' + def verify_entry_count(reportList: str, attr: str) -> str: + return f'TH verifies that _{reportList}_ does not contain more than 12 entries for _{attr}_' - def entry_count_verification() -> str: - return '_reportedCurrentHueValuesList_ has 10 or less entries in the list' + def entry_count_verification(reportList: str) -> str: + return f'_{reportList}_ has 12 or less entries in the list' return [TestStep(1, commission_if_required(), is_commissioning=True), TestStep(2, read_attribute('FeatureMap')), @@ -63,47 +63,65 @@ def entry_count_verification() -> str: TestStep(4, read_attribute('ServerList', 'Descriptor')), TestStep( 5, f"If OnOff cluster is present in _ServerList_, {THcommand} On command on OnOff cluster", verify_success()), - TestStep( - 6, f'{if_feature_supported("HS")}, {THcommand} MoveHue with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), - TestStep(7, f'{if_feature_supported("HS")}, {THcommand} MoveSaturation with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), - TestStep(8, 'Set up a subscription wildcard subscription for the Color Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false', + TestStep(6, 'Set up a subscription wildcard subscription for the Color Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false', 'Subscription successfully established'), - TestStep(9, 'If the HS feature is not supported, skip step 10 to 15'), - TestStep(10, f'{THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0', verify_success()), - TestStep(11, store_values('CurrentHue')), - TestStep(12, verify_entry_count('CurrentHue'), entry_count_verification()), + TestStep(7, 'If the CT feature is not supported, skip step 8 to 12'), + TestStep( + 8, f'{THcommand} MoveColorTemperature with _MoveMode_ field set to Down, _Rate_ field set to 65535 and remaining fields set to 0', verify_success()), + TestStep( + 9, 'TH reads from the DUT the ColorTempPhysicalMaxMireds and stores the returned value as colorTempPhysicalMaxMireds', verify_success()), + TestStep(10, f'{THcommand} MoveToColorTemperature with ColorTemperatureMireds field set to the value of colorTempPhysicalMaxMireds, TransitionTime field set to 100, remaining fields set to 0', verify_success()), + TestStep(11, store_values('reportedColorTemperatureMiredsValuesList', 'ColorTemperatureMireds')), + TestStep(12, verify_entry_count('reportedColorTemperatureMiredsValuesList', 'ColorTemperatureMireds'), + entry_count_verification('reportedColorTemperatureMiredsValuesList')), + TestStep(13, 'If the HS feature is not supported, skip step 14 to 21'), + TestStep( + 14, f'{THcommand} MoveHue with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), + TestStep( + 15, f'{THcommand} MoveSaturation with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), + TestStep(16, f'{THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0', verify_success()), + TestStep(17, store_values('reportedCurrentHueValuesList', 'CurrentHue')), + TestStep(18, verify_entry_count('reportedCurrentHueValuesList', 'CurrentHue'), + entry_count_verification('reportedCurrentHueValuesList')), + TestStep( + 19, f"{THcommand} MoveToSaturation with _Saturation_ field set to 254, _TransitionTime_ field set to 100 and remaining fields set to 0"), + TestStep(20, store_values('reportedCurrentSaturationValuesList', 'CurrentSaturation')), + TestStep(21, verify_entry_count('reportedCurrentSaturationValuesList', + 'CurrentSaturation'), entry_count_verification('reportedCurrentSaturationValuesList')), + TestStep(22, 'If XY feature is not supported, skip steps 23-28'), + TestStep( + 23, f"{THcommand} MoveToColor with _ColorX_ field set to 32768, _ColorY_ set to 19660, _TransitionTime_ field set to 0 and remaining fields set to 0"), TestStep( - 13, f"{THcommand} MoveToSaturation with _Saturation_ field set to 254, _TransitionTime_ field set to 100 and remaining fields set to 0"), - TestStep(14, store_values('CurrentSaturation')), - TestStep(15, verify_entry_count('CurrentSaturation'), entry_count_verification()), - TestStep(16, 'If XY feature is not supported, skip steps 17-21'), + 24, f"{THcommand} MoveToColor with _ColorX_ field set to 13107, _ColorY_ set to 13107, _TransitionTime_ field set to 100 and remaining fields set to 0"), + TestStep(25, store_values('reportedCurrentXValuesList', 'CurrentX')), + TestStep(26, store_values('reportedCurrentYValuesList', 'CurrentY')), + TestStep(27, verify_entry_count('reportedCurrentXValuesList', 'CurrentX'), + entry_count_verification('reportedCurrentXValuesList')), + TestStep(28, verify_entry_count('reportedCurrentYValuesList', 'CurrentY'), + entry_count_verification('reportedCurrentYValuesList')), + TestStep(29, "If the EHUE feature is not supported, skip steps 30 to 32"), + TestStep(30, f"{THcommand} EnhancedMoveToHue with _EnhancedHue_ field set to 0, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()), + TestStep(31, store_values('reportedEnhancedCurrentHueValuesList', 'EnhancedCurrentHue')), + TestStep(32, verify_entry_count('reportedEnhancedCurrentHueValuesList', + 'EnhancedCurrentHue'), entry_count_verification('reportedEnhancedCurrentHueValuesList')), TestStep( - "17a", f"{THcommand} MoveToColor with _ColorX_ field set to 32768, _ColorY_ set to 19660, _TransitionTime_ field set to 0 and remaining fields set to 0"), + 33, 'If the RemainingTime attribute is not supported or the CT feature is not supported, skip the remaining steps and end test case'), TestStep( - "17b", f"{THcommand} MoveToColor with _ColorX_ field set to 13107, _ColorY_ set to 13107, _TransitionTime_ field set to 100 and remaining fields set to 0"), - TestStep(18, store_values('CurrentX')), - TestStep(19, store_values('CurrentY')), - TestStep(20, verify_entry_count('CurrentX'), entry_count_verification()), - TestStep(21, verify_entry_count('CurrentY'), entry_count_verification()), - TestStep(22, "If the EHUE feature is not supported, skip steps 23 to 25"), - TestStep(23, f"{THcommand} EnhancedMoveToHue with _EnhancedHue_ field set to 0, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()), - TestStep(24, store_values('EnhancedCurrentHue')), - TestStep(25, verify_entry_count('EnhancedCurrentHue'), entry_count_verification()), - TestStep(26, "If the RemainingTime attribute is not supported, skip the remaining steps and end test case"), - TestStep(27, store_values('RemainingTime')), + 34, f'{THcommand} MoveColorTemperature with MoveMode field set to Down, Rate field set to 65535 and remaining fields set to 0', verify_success()), + TestStep(35, 'TH stores the reported values of RemainingTime in all incoming reports for RemainingTime attribute, for steps 36 to 39 that contains data in reportedRemainingTimeValuesList.'), TestStep( - 29, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 32768, _ColorY_ set to 19660, _TransitionTime_ field set to 100 and remaining fields set to 0", verify_success()), - TestStep(30, "Wait for 5 seconds"), + 36, f'{THcommand} MoveToColorTemperature with ColorTemperatureMireds field set to the value of colorTempPhysicalMaxMireds / 2, TransitionTime field set to 100, remaining fields set to 0', verify_success()), + TestStep(37, "Wait for 5 seconds"), TestStep( - 32, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 13107, _ColorY_ set to 13107, _TransitionTime_ field set to 150 and remaining fields set to 0", verify_success()), - TestStep(33, "Wait for 20 seconds"), - TestStep(34, "TH verifies _reportedRemainingTimeValuesList_ contains three entries", + 38, f'{THcommand} MoveToColorTemperature with ColorTemperatureMireds field set to the value of colorTempPhysicalMaxMireds, TransitionTime field set to 150, remaining fields set to 0', verify_success()), + TestStep(39, "Wait for 20 seconds"), + TestStep(40, "TH verifies _reportedRemainingTimeValuesList_ contains three entries", "_reportedRemainingTimeValuesList_ has 3 entries in the list"), - TestStep(35, "TH verifies the first entry in _reportedRemainingTimeValuesList_ is 100", - "The first entry in _reportedRemainingTimeValuesList_ is equal to 100"), - TestStep(36, "TH verifies the second entry in _reportedRemainingTimeValuesList_ is approximately 150", - "The second entry in _reportedRemainingTimeValuesList_ is approximately equal to 150"), - TestStep(37, "TH verifies the third entry in _reportedRemainingTimeValuesList_ is 0", + TestStep(41, "TH verifies the first entry in _reportedRemainingTimeValuesList_ is 100", + "The first entry in reportedRemainingTimeValuesList is in the range of 95 to 100"), + TestStep(42, "TH verifies the second entry in _reportedRemainingTimeValuesList_ is approximately 150", + "The second entry in reportedRemainingTimeValuesList is in the range of 145 to 150"), + TestStep(43, "TH verifies the third entry in _reportedRemainingTimeValuesList_ is 0", "The third entry in _reportedRemainingTimeValuesList_ is equal to 0") ] @@ -118,6 +136,7 @@ async def test_TC_CC_2_2(self): self.step(2) feature_map = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.FeatureMap) + supports_ct = (feature_map & cc.Bitmaps.Feature.kColorTemperature) != 0 supports_hs = (feature_map & cc.Bitmaps.Feature.kHueAndSaturation) != 0 supports_xy = (feature_map & cc.Bitmaps.Feature.kXy) != 0 supports_ehue = (feature_map & cc.Bitmaps.Feature.kEnhancedHue) != 0 @@ -136,20 +155,6 @@ async def test_TC_CC_2_2(self): self.mark_current_step_skipped() self.step(6) - if supports_hs: - cmd = cc.Commands.MoveHue(moveMode=cc.Enums.MoveModeEnum.kDown, rate=225) - await self.send_single_cmd(cmd) - else: - self.mark_current_step_skipped() - - self.step(7) - if supports_hs: - cmd = cc.Commands.MoveSaturation(moveMode=cc.Enums.MoveModeEnum.kDown, rate=225) - await self.send_single_cmd(cmd) - else: - self.mark_current_step_skipped() - - self.step(8) sub_handler = ClusterAttributeChangeAccumulator(cc) await sub_handler.start(self.default_controller, self.dut_node_id, self.matter_test_config.endpoint) @@ -163,124 +168,162 @@ def check_report_counts(attr: ClusterObjects.ClusterAttributeDescriptor): asserts.assert_less_equal(count, 12, "More than 12 reports received") asserts.assert_less_equal(count, gather_time, f"More than {gather_time} reports received") - self.step(9) - if not supports_hs: + self.step(7) + if not supports_ct: + self.skip_step(8) + self.skip_step(9) self.skip_step(10) self.skip_step(11) self.skip_step(12) - self.skip_step(13) - self.skip_step(14) - self.skip_step(15) else: + self.step(8) + cmd = cc.Commands.MoveColorTemperature(moveMode=cc.Enums.MoveModeEnum.kDown, rate=65535) + await self.send_single_cmd(cmd) + + self.step(9) + colorTempPhysicalMaxMireds = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.ColorTempPhysicalMaxMireds) + self.step(10) - cmd = cc.Commands.MoveToHue(hue=254, transitionTime=100, direction=cc.Enums.DirectionEnum.kShortest) + cmd = cc.Commands.MoveToColorTemperature(colorTemperatureMireds=colorTempPhysicalMaxMireds, transitionTime=100) await self.send_single_cmd(cmd) self.step(11) accumulate_reports() self.step(12) + check_report_counts(cc.Attributes.ColorTemperatureMireds) + + self.step(13) + if not supports_hs: + self.skip_step(14) + self.skip_step(15) + self.skip_step(16) + self.skip_step(17) + self.skip_step(18) + self.skip_step(19) + self.skip_step(20) + self.skip_step(21) + else: + self.step(14) + cmd = cc.Commands.MoveHue(moveMode=cc.Enums.MoveModeEnum.kDown, rate=225) + await self.send_single_cmd(cmd) + + self.step(15) + cmd = cc.Commands.MoveSaturation(moveMode=cc.Enums.MoveModeEnum.kDown, rate=225) + await self.send_single_cmd(cmd) + + self.step(16) + cmd = cc.Commands.MoveToHue(hue=254, transitionTime=100, direction=cc.Enums.DirectionEnum.kShortest) + await self.send_single_cmd(cmd) + + self.step(17) + accumulate_reports() + + self.step(18) check_report_counts(cc.Attributes.CurrentHue) - self.step(13) + self.step(19) cmd = cc.Commands.MoveToSaturation(saturation=254, transitionTime=100) await self.send_single_cmd(cmd) - self.step(14) + self.step(20) accumulate_reports() - self.step(15) + self.step(21) check_report_counts(cc.Attributes.CurrentSaturation) - self.step(16) + self.step(22) if not supports_xy: - self.skip_step(17) - self.skip_step(18) - self.skip_step(19) - self.skip_step(20) - self.skip_step(21) + self.skip_step(23) + self.skip_step(24) + self.skip_step(25) + self.skip_step(26) + self.skip_step(27) + self.skip_step(28) else: - self.step("17a") + self.step(23) cmd = cc.Commands.MoveToColor(colorX=32768, colorY=19660, transitionTime=0) await self.send_single_cmd(cmd) - self.step("17b") - cmd = cc.Commands.MoveToColor(colorX=13107, colorY=13107, transitionTime=0) + self.step(24) + cmd = cc.Commands.MoveToColor(colorX=13107, colorY=13107, transitionTime=100) await self.send_single_cmd(cmd) - self.step(18) + self.step(25) accumulate_reports() - self.step(19) + self.step(26) # reports for x and y are both accumulated in a dict - done above - self.step(20) + self.step(27) check_report_counts(cc.Attributes.CurrentX) - self.step(21) + self.step(28) check_report_counts(cc.Attributes.CurrentY) - self.step(22) + self.step(29) if not supports_ehue: - self.skip_step(23) - self.skip_step(24) - self.skip_step(25) + self.skip_step(30) + self.skip_step(31) + self.skip_step(32) else: - self.step(23) + self.step(30) cmd = cc.Commands.EnhancedMoveToHue(enhancedHue=0, transitionTime=100, direction=cc.Enums.DirectionEnum.kShortest) await self.send_single_cmd(cmd) - self.step(24) + self.step(31) accumulate_reports() - self.step(25) + self.step(32) check_report_counts(cc.Attributes.EnhancedCurrentHue) - self.step(26) - if cc.Attributes.RemainingTime.attribute_id not in attribute_list: - self.skip_all_remaining_steps(27) + self.step(33) + if cc.Attributes.RemainingTime.attribute_id not in attribute_list or not supports_ct: + self.skip_all_remaining_steps(34) return - self.step(27) + self.step(34) + cmd = cc.Commands.MoveColorTemperature(moveMode=cc.Enums.MoveModeEnum.kDown, rate=65535) + await self.send_single_cmd(cmd) + + self.step(35) accumulate_reports() - self.step(29) - # TODO: If this is mandatory, we should just omit this - if supports_xy: - cmd = cc.Commands.MoveToColor(colorX=32768, colorY=19660, transitionTime=100) - await self.send_single_cmd(cmd) - else: - self.mark_current_step_skipped() + self.step(36) + cmd = cc.Commands.MoveToColorTemperature(colorTemperatureMireds=colorTempPhysicalMaxMireds/2, transitionTime=100) + await self.send_single_cmd(cmd) - self.step(30) + self.step(37) logging.info("Test will now wait for 5 seconds") time.sleep(5) - self.step(32) - if supports_xy: - cmd = cc.Commands.MoveToColor(colorX=13107, colorY=13107, transitionTime=150) - await self.send_single_cmd(cmd) - else: - self.mark_current_step_skipped() + self.step(38) + cmd = cc.Commands.MoveToColorTemperature(colorTemperatureMireds=colorTempPhysicalMaxMireds, transitionTime=150) + await self.send_single_cmd(cmd) - self.step(33) + self.step(39) logging.info("Test will now wait for 20 seconds") time.sleep(20) - self.step(34) + self.step(40) logging.info(f'received reports: {sub_handler.attribute_reports[cc.Attributes.RemainingTime]}') count = sub_handler.attribute_report_counts[cc.Attributes.RemainingTime] asserts.assert_equal(count, 3, "Unexpected number of reports received") - self.step(35) - asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][0].value, 100, "Unexpected first report") + self.step(41) + asserts.assert_less_equal( + sub_handler.attribute_reports[cc.Attributes.RemainingTime][0].value, 100, "Unexpected first report") + asserts.assert_almost_equal( + sub_handler.attribute_reports[cc.Attributes.RemainingTime][0].value, 100, delta=10, msg="Unexpected first report") - self.step(36) + self.step(42) + asserts.assert_less_equal( + sub_handler.attribute_reports[cc.Attributes.RemainingTime][1].value, 150, "Unexpected second report") asserts.assert_almost_equal( sub_handler.attribute_reports[cc.Attributes.RemainingTime][1].value, 150, delta=10, msg="Unexpected second report") - self.step(37) + self.step(43) asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][-1].value, 0, "Unexpected last report") From edd241c215302488c5d506fd60f1721a8e0a32cb Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 15:46:30 -0400 Subject: [PATCH 52/70] Updated data model XML updates from Sept 3 (#35385) * check * New DM XML drop from Sept 3 * add to word list --- .github/.wordlist.txt | 1 + .../in_progress/clusters/ACL-Cluster.xml | 20 +++------- data_model/in_progress/clusters/Channel.xml | 4 -- .../in_progress/clusters/ColorControl.xml | 16 ++++---- .../clusters/CommissionerControlCluster.xml | 20 ++++------ .../clusters/ConcentrationMeasurement.xml | 1 - .../clusters/Descriptor-Cluster.xml | 9 +---- .../clusters/DeviceEnergyManagement.xml | 35 +++++++++-------- .../in_progress/clusters/EnergyCalendar.xml | 2 +- .../in_progress/clusters/FanControl.xml | 6 +-- .../in_progress/clusters/FlowMeasurement.xml | 4 +- .../clusters/GeneralCommissioningCluster.xml | 26 ++++++------- data_model/in_progress/clusters/Identify.xml | 3 +- .../clusters/IlluminanceMeasurement.xml | 4 +- .../clusters/JointFabricDatastoreCluster.xml | 8 +++- .../clusters/JointFabricPKICluster.xml | 38 +++++++++++++++++-- .../in_progress/clusters/LevelControl.xml | 3 +- .../clusters/Mode_DeviceEnergyManagement.xml | 4 +- .../in_progress/clusters/Mode_Dishwasher.xml | 10 ++--- data_model/in_progress/clusters/Mode_EVSE.xml | 2 +- .../clusters/Mode_LaundryWasher.xml | 10 ++--- .../clusters/Mode_MicrowaveOven.xml | 2 +- data_model/in_progress/clusters/Mode_Oven.xml | 10 ++--- .../in_progress/clusters/Mode_RVCClean.xml | 12 +++--- .../in_progress/clusters/Mode_RVCRun.xml | 12 +++--- .../clusters/Mode_Refrigerator.xml | 10 ++--- .../in_progress/clusters/Mode_WaterHeater.xml | 2 +- .../in_progress/clusters/OccupancySensing.xml | 16 +++++++- .../clusters/OperationalState_RVC.xml | 4 +- .../clusters/PressureMeasurement.xml | 14 +++---- .../clusters/PumpConfigurationControl.xml | 33 +++++++++------- .../in_progress/clusters/ServiceArea.xml | 4 +- data_model/in_progress/clusters/Switch.xml | 2 +- .../clusters/TemperatureControl.xml | 2 +- .../clusters/TemperatureMeasurement.xml | 6 +-- .../in_progress/clusters/Thermostat.xml | 9 ++--- .../clusters/ValveConfigurationControl.xml | 5 +-- .../clusters/WaterContentMeasurement.xml | 6 +-- .../in_progress/clusters/WindowCovering.xml | 31 ++++++--------- ...s-BridgedDeviceBasicInformationCluster.xml | 6 ++- ...e-clusters-EcosystemInformationCluster.xml | 21 +++------- .../in_progress/clusters/cluster_ids.json | 4 +- .../device_types/JointFabricAdmin.xml | 6 +-- .../MountedDimmableLoadControl.xml | 2 +- .../device_types/MountedOnOffControl.xml | 2 +- .../device_types/ThreadBorderRouter.xml | 3 ++ .../device_types/WindowCovering.xml | 30 --------------- data_model/in_progress/spec_sha | 2 +- data_model/master/clusters/ACL-Cluster.xml | 20 +++------- data_model/master/clusters/Channel.xml | 4 -- data_model/master/clusters/ColorControl.xml | 16 ++++---- .../clusters/CommissionerControlCluster.xml | 20 ++++------ .../clusters/ConcentrationMeasurement.xml | 1 - .../clusters/DeviceEnergyManagement.xml | 35 +++++++++-------- data_model/master/clusters/EnergyCalendar.xml | 2 +- data_model/master/clusters/FanControl.xml | 6 +-- .../master/clusters/FlowMeasurement.xml | 4 +- .../clusters/GeneralCommissioningCluster.xml | 15 +++++++- data_model/master/clusters/Identify.xml | 3 +- .../clusters/IlluminanceMeasurement.xml | 4 +- .../clusters/JointFabricDatastoreCluster.xml | 8 +++- .../master/clusters/JointFabricPKICluster.xml | 38 +++++++++++++++++-- data_model/master/clusters/LevelControl.xml | 3 +- .../clusters/Mode_DeviceEnergyManagement.xml | 4 +- .../master/clusters/Mode_Dishwasher.xml | 10 ++--- data_model/master/clusters/Mode_EVSE.xml | 2 +- .../master/clusters/Mode_LaundryWasher.xml | 10 ++--- .../master/clusters/Mode_MicrowaveOven.xml | 2 +- data_model/master/clusters/Mode_Oven.xml | 10 ++--- data_model/master/clusters/Mode_RVCClean.xml | 15 +++++--- data_model/master/clusters/Mode_RVCRun.xml | 15 +++++--- .../master/clusters/Mode_Refrigerator.xml | 10 ++--- .../master/clusters/Mode_WaterHeater.xml | 2 +- .../master/clusters/OccupancySensing.xml | 16 +++++++- .../master/clusters/OperationalState_RVC.xml | 4 +- .../master/clusters/PressureMeasurement.xml | 14 +++---- .../clusters/PumpConfigurationControl.xml | 33 +++++++++------- data_model/master/clusters/ServiceArea.xml | 4 +- data_model/master/clusters/Switch.xml | 2 +- .../master/clusters/TemperatureControl.xml | 2 +- .../clusters/TemperatureMeasurement.xml | 6 +-- data_model/master/clusters/Thermostat.xml | 9 ++--- .../clusters/ValveConfigurationControl.xml | 5 +-- .../clusters/WaterContentMeasurement.xml | 6 +-- data_model/master/clusters/WindowCovering.xml | 31 ++++++--------- ...s-BridgedDeviceBasicInformationCluster.xml | 6 ++- ...e-clusters-EcosystemInformationCluster.xml | 21 +++------- data_model/master/clusters/cluster_ids.json | 2 + .../master/device_types/JointFabricAdmin.xml | 6 +-- .../MountedDimmableLoadControl.xml | 2 +- .../device_types/MountedOnOffControl.xml | 2 +- .../device_types/ThreadBorderRouter.xml | 3 ++ .../master/device_types/WindowCovering.xml | 30 --------------- data_model/master/spec_sha | 2 +- docs/spec_clusters.md | 3 ++ src/python_testing/spec_parsing_support.py | 2 + 96 files changed, 476 insertions(+), 476 deletions(-) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 5637540f7f9b25..9cb24bcf4d8b0b 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -341,6 +341,7 @@ datamodel DataModelRevision dataset datasets +datastore DataVersion dbf DBG diff --git a/data_model/in_progress/clusters/ACL-Cluster.xml b/data_model/in_progress/clusters/ACL-Cluster.xml index 2f9de14e0adfad..15eebb425286a4 100644 --- a/data_model/in_progress/clusters/ACL-Cluster.xml +++ b/data_model/in_progress/clusters/ACL-Cluster.xml @@ -68,9 +68,7 @@ Davis, CA 95616, USA - - - + @@ -333,13 +331,7 @@ Davis, CA 95616, USA - - - - - - - + @@ -348,13 +340,11 @@ Davis, CA 95616, USA - - + - - - + + diff --git a/data_model/in_progress/clusters/Channel.xml b/data_model/in_progress/clusters/Channel.xml index a2edf151cb6001..02bfcf3b25c854 100644 --- a/data_model/in_progress/clusters/Channel.xml +++ b/data_model/in_progress/clusters/Channel.xml @@ -366,7 +366,6 @@ Davis, CA 95616, USA - @@ -401,7 +400,6 @@ Davis, CA 95616, USA - @@ -414,7 +412,6 @@ Davis, CA 95616, USA - @@ -440,7 +437,6 @@ Davis, CA 95616, USA - diff --git a/data_model/in_progress/clusters/ColorControl.xml b/data_model/in_progress/clusters/ColorControl.xml index 6901b6ee4130c6..fa14aca0f8b5f4 100644 --- a/data_model/in_progress/clusters/ColorControl.xml +++ b/data_model/in_progress/clusters/ColorControl.xml @@ -65,8 +65,10 @@ Davis, CA 95616, USA - + @@ -291,7 +293,7 @@ Davis, CA 95616, USA - + @@ -666,14 +668,14 @@ Davis, CA 95616, USA - + - + - + @@ -699,7 +701,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/CommissionerControlCluster.xml b/data_model/in_progress/clusters/CommissionerControlCluster.xml index 9b01df6a9aec0c..d3b8380aaba929 100644 --- a/data_model/in_progress/clusters/CommissionerControlCluster.xml +++ b/data_model/in_progress/clusters/CommissionerControlCluster.xml @@ -80,13 +80,13 @@ Davis, CA 95616, USA - + - + - + @@ -97,19 +97,13 @@ Davis, CA 95616, USA - + - + - - - - - - @@ -138,10 +132,10 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/in_progress/clusters/ConcentrationMeasurement.xml b/data_model/in_progress/clusters/ConcentrationMeasurement.xml index b622a3560b4ff0..68d4b7937bf717 100644 --- a/data_model/in_progress/clusters/ConcentrationMeasurement.xml +++ b/data_model/in_progress/clusters/ConcentrationMeasurement.xml @@ -193,7 +193,6 @@ Davis, CA 95616, USA - diff --git a/data_model/in_progress/clusters/Descriptor-Cluster.xml b/data_model/in_progress/clusters/Descriptor-Cluster.xml index fabc3a2a16c658..e30b12ea713d6b 100644 --- a/data_model/in_progress/clusters/Descriptor-Cluster.xml +++ b/data_model/in_progress/clusters/Descriptor-Cluster.xml @@ -57,11 +57,10 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - @@ -115,11 +114,5 @@ Davis, CA 95616, USA - - - - - - \ No newline at end of file diff --git a/data_model/in_progress/clusters/DeviceEnergyManagement.xml b/data_model/in_progress/clusters/DeviceEnergyManagement.xml index cb7f46c008f5e1..776a06f20b3fd4 100644 --- a/data_model/in_progress/clusters/DeviceEnergyManagement.xml +++ b/data_model/in_progress/clusters/DeviceEnergyManagement.xml @@ -62,7 +62,7 @@ Davis, CA 95616, USA - + @@ -123,27 +123,27 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -230,13 +230,13 @@ Davis, CA 95616, USA - + - + - + @@ -255,13 +255,13 @@ Davis, CA 95616, USA - + - + - + @@ -359,12 +359,14 @@ Davis, CA 95616, USA + + @@ -495,17 +497,18 @@ Davis, CA 95616, USA + - + - + diff --git a/data_model/in_progress/clusters/EnergyCalendar.xml b/data_model/in_progress/clusters/EnergyCalendar.xml index 5be0f8ff520aea..2ba93203618609 100644 --- a/data_model/in_progress/clusters/EnergyCalendar.xml +++ b/data_model/in_progress/clusters/EnergyCalendar.xml @@ -158,7 +158,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/FanControl.xml b/data_model/in_progress/clusters/FanControl.xml index 9eba1df549981c..ec05b6f74e069d 100644 --- a/data_model/in_progress/clusters/FanControl.xml +++ b/data_model/in_progress/clusters/FanControl.xml @@ -57,13 +57,12 @@ Davis, CA 95616, USA :xrefstyle: short --> - + - @@ -211,7 +210,6 @@ Davis, CA 95616, USA - @@ -233,7 +231,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/FlowMeasurement.xml b/data_model/in_progress/clusters/FlowMeasurement.xml index 85879977faa509..7ee97f586e708a 100644 --- a/data_model/in_progress/clusters/FlowMeasurement.xml +++ b/data_model/in_progress/clusters/FlowMeasurement.xml @@ -78,13 +78,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/in_progress/clusters/GeneralCommissioningCluster.xml b/data_model/in_progress/clusters/GeneralCommissioningCluster.xml index 7dae043cd4df98..a569fef5d44118 100644 --- a/data_model/in_progress/clusters/GeneralCommissioningCluster.xml +++ b/data_model/in_progress/clusters/GeneralCommissioningCluster.xml @@ -81,21 +81,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - @@ -145,24 +130,35 @@ Davis, CA 95616, USA + + + + + + + + + + + diff --git a/data_model/in_progress/clusters/Identify.xml b/data_model/in_progress/clusters/Identify.xml index a6682b7233d30a..ddc3e33e9d28d3 100644 --- a/data_model/in_progress/clusters/Identify.xml +++ b/data_model/in_progress/clusters/Identify.xml @@ -63,7 +63,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,6 @@ Davis, CA 95616, USA - diff --git a/data_model/in_progress/clusters/IlluminanceMeasurement.xml b/data_model/in_progress/clusters/IlluminanceMeasurement.xml index f24df314ca2ead..d7cb9a993d0e4e 100644 --- a/data_model/in_progress/clusters/IlluminanceMeasurement.xml +++ b/data_model/in_progress/clusters/IlluminanceMeasurement.xml @@ -92,13 +92,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/in_progress/clusters/JointFabricDatastoreCluster.xml b/data_model/in_progress/clusters/JointFabricDatastoreCluster.xml index 79143f34d03f55..137edd2857f74d 100644 --- a/data_model/in_progress/clusters/JointFabricDatastoreCluster.xml +++ b/data_model/in_progress/clusters/JointFabricDatastoreCluster.xml @@ -55,12 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + @@ -267,6 +267,10 @@ Davis, CA 95616, USA + + + + diff --git a/data_model/in_progress/clusters/JointFabricPKICluster.xml b/data_model/in_progress/clusters/JointFabricPKICluster.xml index 7fba1e17376ecd..847d2548e3b1f1 100644 --- a/data_model/in_progress/clusters/JointFabricPKICluster.xml +++ b/data_model/in_progress/clusters/JointFabricPKICluster.xml @@ -55,12 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + @@ -80,7 +80,24 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + @@ -104,5 +121,20 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/in_progress/clusters/LevelControl.xml b/data_model/in_progress/clusters/LevelControl.xml index 28f88b96832c32..de342812287b0f 100644 --- a/data_model/in_progress/clusters/LevelControl.xml +++ b/data_model/in_progress/clusters/LevelControl.xml @@ -136,7 +136,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,6 @@ Davis, CA 95616, USA - diff --git a/data_model/in_progress/clusters/Mode_DeviceEnergyManagement.xml b/data_model/in_progress/clusters/Mode_DeviceEnergyManagement.xml index b991a36577bdd2..48cf6df4955a15 100644 --- a/data_model/in_progress/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/in_progress/clusters/Mode_DeviceEnergyManagement.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA - + @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/Mode_Dishwasher.xml b/data_model/in_progress/clusters/Mode_Dishwasher.xml index 8069fdddcf0cc3..1c3a99b9e3d245 100644 --- a/data_model/in_progress/clusters/Mode_Dishwasher.xml +++ b/data_model/in_progress/clusters/Mode_Dishwasher.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/in_progress/clusters/Mode_EVSE.xml b/data_model/in_progress/clusters/Mode_EVSE.xml index fddd0e078c6df1..025e9de9884c89 100644 --- a/data_model/in_progress/clusters/Mode_EVSE.xml +++ b/data_model/in_progress/clusters/Mode_EVSE.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/Mode_LaundryWasher.xml b/data_model/in_progress/clusters/Mode_LaundryWasher.xml index 444d536fd178fd..b5f557a4b46a4b 100644 --- a/data_model/in_progress/clusters/Mode_LaundryWasher.xml +++ b/data_model/in_progress/clusters/Mode_LaundryWasher.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/in_progress/clusters/Mode_MicrowaveOven.xml b/data_model/in_progress/clusters/Mode_MicrowaveOven.xml index b5076d8c270099..24d682fecac68b 100644 --- a/data_model/in_progress/clusters/Mode_MicrowaveOven.xml +++ b/data_model/in_progress/clusters/Mode_MicrowaveOven.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/Mode_Oven.xml b/data_model/in_progress/clusters/Mode_Oven.xml index f7e8c8a4268cf2..a3e3323fe98777 100644 --- a/data_model/in_progress/clusters/Mode_Oven.xml +++ b/data_model/in_progress/clusters/Mode_Oven.xml @@ -65,6 +65,11 @@ Davis, CA 95616, USA + + + + + @@ -79,11 +84,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/in_progress/clusters/Mode_RVCClean.xml b/data_model/in_progress/clusters/Mode_RVCClean.xml index 26b5d15c185fe3..b73a4a5361d81f 100644 --- a/data_model/in_progress/clusters/Mode_RVCClean.xml +++ b/data_model/in_progress/clusters/Mode_RVCClean.xml @@ -67,6 +67,11 @@ Davis, CA 95616, USA + + + + + @@ -81,11 +86,6 @@ Davis, CA 95616, USA - - - - - @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/in_progress/clusters/Mode_RVCRun.xml b/data_model/in_progress/clusters/Mode_RVCRun.xml index ad0d7601a45c22..c65bc3850473bd 100644 --- a/data_model/in_progress/clusters/Mode_RVCRun.xml +++ b/data_model/in_progress/clusters/Mode_RVCRun.xml @@ -67,6 +67,11 @@ Davis, CA 95616, USA + + + + + @@ -81,11 +86,6 @@ Davis, CA 95616, USA - - - - - @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/in_progress/clusters/Mode_Refrigerator.xml b/data_model/in_progress/clusters/Mode_Refrigerator.xml index 84410d1ddfc465..2728ac0f42b8fb 100644 --- a/data_model/in_progress/clusters/Mode_Refrigerator.xml +++ b/data_model/in_progress/clusters/Mode_Refrigerator.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/in_progress/clusters/Mode_WaterHeater.xml b/data_model/in_progress/clusters/Mode_WaterHeater.xml index 5aaf1d244f1898..cc9c96e484bce2 100644 --- a/data_model/in_progress/clusters/Mode_WaterHeater.xml +++ b/data_model/in_progress/clusters/Mode_WaterHeater.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/OccupancySensing.xml b/data_model/in_progress/clusters/OccupancySensing.xml index 4cd027deb07279..7ca0d3631dbe05 100644 --- a/data_model/in_progress/clusters/OccupancySensing.xml +++ b/data_model/in_progress/clusters/OccupancySensing.xml @@ -68,6 +68,7 @@ Davis, CA 95616, USA add sensitivity setting (via co-located BooleanStateConfiguration cluster on same endpoint); add new attribute for tuning the sensor's reporting; add event OccupancyChanged; + add `N` quality for HoldTime and other timing attributes; describe how to accommodate legacy clients"/> @@ -134,11 +135,12 @@ Davis, CA 95616, USA - + + @@ -171,8 +173,9 @@ Davis, CA 95616, USA - + + @@ -185,6 +188,7 @@ Davis, CA 95616, USA + @@ -210,6 +214,7 @@ Davis, CA 95616, USA + @@ -257,6 +262,7 @@ Davis, CA 95616, USA + @@ -305,6 +311,7 @@ Davis, CA 95616, USA + @@ -317,6 +324,7 @@ Davis, CA 95616, USA + @@ -336,6 +344,7 @@ Davis, CA 95616, USA + @@ -356,6 +365,7 @@ Davis, CA 95616, USA + @@ -368,6 +378,7 @@ Davis, CA 95616, USA + @@ -387,6 +398,7 @@ Davis, CA 95616, USA + diff --git a/data_model/in_progress/clusters/OperationalState_RVC.xml b/data_model/in_progress/clusters/OperationalState_RVC.xml index 5d2d28db2c2cad..9b83bc4dfde257 100644 --- a/data_model/in_progress/clusters/OperationalState_RVC.xml +++ b/data_model/in_progress/clusters/OperationalState_RVC.xml @@ -108,10 +108,10 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/in_progress/clusters/PressureMeasurement.xml b/data_model/in_progress/clusters/PressureMeasurement.xml index bf9b6a9286e381..09b9577cc84585 100644 --- a/data_model/in_progress/clusters/PressureMeasurement.xml +++ b/data_model/in_progress/clusters/PressureMeasurement.xml @@ -83,18 +83,18 @@ Davis, CA 95616, USA - + - + - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,21 +118,21 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/in_progress/clusters/PumpConfigurationControl.xml b/data_model/in_progress/clusters/PumpConfigurationControl.xml index 95ede00d0eb72e..9b7e4ab56dc5c2 100644 --- a/data_model/in_progress/clusters/PumpConfigurationControl.xml +++ b/data_model/in_progress/clusters/PumpConfigurationControl.xml @@ -55,13 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - @@ -97,37 +96,44 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -137,7 +143,8 @@ Davis, CA 95616, USA - + @@ -331,12 +338,12 @@ Davis, CA 95616, USA - + - + @@ -346,7 +353,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/ServiceArea.xml b/data_model/in_progress/clusters/ServiceArea.xml index 6a54264a94928b..2533d4b549d2f0 100644 --- a/data_model/in_progress/clusters/ServiceArea.xml +++ b/data_model/in_progress/clusters/ServiceArea.xml @@ -113,7 +113,7 @@ Davis, CA 95616, USA - +
@@ -121,7 +121,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/Switch.xml b/data_model/in_progress/clusters/Switch.xml index 92489c1e9228a3..8662d262f0b50e 100644 --- a/data_model/in_progress/clusters/Switch.xml +++ b/data_model/in_progress/clusters/Switch.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA + Introduction of ActionSwitch feature flag."/> diff --git a/data_model/in_progress/clusters/TemperatureControl.xml b/data_model/in_progress/clusters/TemperatureControl.xml index 79519716ea1cf8..511761b24b9e89 100644 --- a/data_model/in_progress/clusters/TemperatureControl.xml +++ b/data_model/in_progress/clusters/TemperatureControl.xml @@ -113,7 +113,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/TemperatureMeasurement.xml b/data_model/in_progress/clusters/TemperatureMeasurement.xml index 0935b18edab675..5c1df46ccbf115 100644 --- a/data_model/in_progress/clusters/TemperatureMeasurement.xml +++ b/data_model/in_progress/clusters/TemperatureMeasurement.xml @@ -79,18 +79,18 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/in_progress/clusters/Thermostat.xml b/data_model/in_progress/clusters/Thermostat.xml index faf147839facb4..6c5584e087d47c 100644 --- a/data_model/in_progress/clusters/Thermostat.xml +++ b/data_model/in_progress/clusters/Thermostat.xml @@ -63,8 +63,7 @@ Davis, CA 95616, USA - @@ -653,12 +652,12 @@ Davis, CA 95616, USA - + - + @@ -996,7 +995,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/ValveConfigurationControl.xml b/data_model/in_progress/clusters/ValveConfigurationControl.xml index 03d40acd480ff4..6f38375a1a31c6 100644 --- a/data_model/in_progress/clusters/ValveConfigurationControl.xml +++ b/data_model/in_progress/clusters/ValveConfigurationControl.xml @@ -57,10 +57,9 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - @@ -143,7 +142,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/in_progress/clusters/WaterContentMeasurement.xml b/data_model/in_progress/clusters/WaterContentMeasurement.xml index af11c9cf8d514c..b613bf4e1522fb 100644 --- a/data_model/in_progress/clusters/WaterContentMeasurement.xml +++ b/data_model/in_progress/clusters/WaterContentMeasurement.xml @@ -78,18 +78,18 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/in_progress/clusters/WindowCovering.xml b/data_model/in_progress/clusters/WindowCovering.xml index f8c60b46901dc9..09133513af736a 100644 --- a/data_model/in_progress/clusters/WindowCovering.xml +++ b/data_model/in_progress/clusters/WindowCovering.xml @@ -57,14 +57,13 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - @@ -420,7 +419,7 @@ Davis, CA 95616, USA - + @@ -432,7 +431,7 @@ Davis, CA 95616, USA - + @@ -464,7 +463,7 @@ Davis, CA 95616, USA - + @@ -474,7 +473,7 @@ Davis, CA 95616, USA - + @@ -517,7 +516,7 @@ Davis, CA 95616, USA - + @@ -528,7 +527,7 @@ Davis, CA 95616, USA - + @@ -652,12 +651,8 @@ Davis, CA 95616, USA - - - - - - + + @@ -687,12 +682,8 @@ Davis, CA 95616, USA - - - - - - + + diff --git a/data_model/in_progress/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/in_progress/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 4368d991c832f4..62633f55cf08cc 100644 --- a/data_model/in_progress/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/in_progress/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + @@ -154,6 +154,10 @@ Davis, CA 95616, USA + + + + diff --git a/data_model/in_progress/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/in_progress/clusters/bridge-clusters-EcosystemInformationCluster.xml index 22cc88097acf75..ddebe95679370e 100644 --- a/data_model/in_progress/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/in_progress/clusters/bridge-clusters-EcosystemInformationCluster.xml @@ -84,12 +84,10 @@ Davis, CA 95616, USA - - - + - + @@ -123,24 +121,17 @@ Davis, CA 95616, USA
- - - - - - + - + - - + - + - \ No newline at end of file diff --git a/data_model/in_progress/clusters/cluster_ids.json b/data_model/in_progress/clusters/cluster_ids.json index c65c08ab4a5879..9de2f243b377d6 100644 --- a/data_model/in_progress/clusters/cluster_ids.json +++ b/data_model/in_progress/clusters/cluster_ids.json @@ -118,5 +118,7 @@ "1295": "Content Control", "1296": "Content App Observer", "1872": "Ecosystem Information", - "1873": "Commissioner Control" + "1873": "Commissioner Control", + "1874": "Joint Fabric Datastore Cluster", + "1875": "Joint Fabric PKI" } diff --git a/data_model/in_progress/device_types/JointFabricAdmin.xml b/data_model/in_progress/device_types/JointFabricAdmin.xml index 7d29cbba1305d5..6c63dc9bdd96a1 100644 --- a/data_model/in_progress/device_types/JointFabricAdmin.xml +++ b/data_model/in_progress/device_types/JointFabricAdmin.xml @@ -55,16 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + diff --git a/data_model/in_progress/device_types/MountedDimmableLoadControl.xml b/data_model/in_progress/device_types/MountedDimmableLoadControl.xml index 2527eb6aaefcd2..d0cee6e5ef37cd 100644 --- a/data_model/in_progress/device_types/MountedDimmableLoadControl.xml +++ b/data_model/in_progress/device_types/MountedDimmableLoadControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/in_progress/device_types/MountedOnOffControl.xml b/data_model/in_progress/device_types/MountedOnOffControl.xml index 1be3cf746418aa..09628bb4e0e9f0 100644 --- a/data_model/in_progress/device_types/MountedOnOffControl.xml +++ b/data_model/in_progress/device_types/MountedOnOffControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/in_progress/device_types/ThreadBorderRouter.xml b/data_model/in_progress/device_types/ThreadBorderRouter.xml index abe38a81396cd6..792f002801b9a0 100644 --- a/data_model/in_progress/device_types/ThreadBorderRouter.xml +++ b/data_model/in_progress/device_types/ThreadBorderRouter.xml @@ -68,5 +68,8 @@ Davis, CA 95616, USA + + + \ No newline at end of file diff --git a/data_model/in_progress/device_types/WindowCovering.xml b/data_model/in_progress/device_types/WindowCovering.xml index 0e907045e3e1b6..da8780b3c94be4 100644 --- a/data_model/in_progress/device_types/WindowCovering.xml +++ b/data_model/in_progress/device_types/WindowCovering.xml @@ -84,36 +84,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/in_progress/spec_sha b/data_model/in_progress/spec_sha index 8f9072976d9c15..a399f222280c76 100644 --- a/data_model/in_progress/spec_sha +++ b/data_model/in_progress/spec_sha @@ -1 +1 @@ -3432866fff8e0c21e1189a10d4ee66b9eb004844 +ec20ddf482db8deffe8b2eb745e34d2f9cea72b2 diff --git a/data_model/master/clusters/ACL-Cluster.xml b/data_model/master/clusters/ACL-Cluster.xml index 2f9de14e0adfad..15eebb425286a4 100644 --- a/data_model/master/clusters/ACL-Cluster.xml +++ b/data_model/master/clusters/ACL-Cluster.xml @@ -68,9 +68,7 @@ Davis, CA 95616, USA - - - + @@ -333,13 +331,7 @@ Davis, CA 95616, USA - - - - - - - + @@ -348,13 +340,11 @@ Davis, CA 95616, USA - - + - - - + + diff --git a/data_model/master/clusters/Channel.xml b/data_model/master/clusters/Channel.xml index a2edf151cb6001..02bfcf3b25c854 100644 --- a/data_model/master/clusters/Channel.xml +++ b/data_model/master/clusters/Channel.xml @@ -366,7 +366,6 @@ Davis, CA 95616, USA - @@ -401,7 +400,6 @@ Davis, CA 95616, USA - @@ -414,7 +412,6 @@ Davis, CA 95616, USA - @@ -440,7 +437,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/ColorControl.xml b/data_model/master/clusters/ColorControl.xml index 6901b6ee4130c6..fa14aca0f8b5f4 100644 --- a/data_model/master/clusters/ColorControl.xml +++ b/data_model/master/clusters/ColorControl.xml @@ -65,8 +65,10 @@ Davis, CA 95616, USA - + @@ -291,7 +293,7 @@ Davis, CA 95616, USA - + @@ -666,14 +668,14 @@ Davis, CA 95616, USA - + - + - + @@ -699,7 +701,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/CommissionerControlCluster.xml b/data_model/master/clusters/CommissionerControlCluster.xml index 9b01df6a9aec0c..d3b8380aaba929 100644 --- a/data_model/master/clusters/CommissionerControlCluster.xml +++ b/data_model/master/clusters/CommissionerControlCluster.xml @@ -80,13 +80,13 @@ Davis, CA 95616, USA - + - + - + @@ -97,19 +97,13 @@ Davis, CA 95616, USA - + - + - - - - - - @@ -138,10 +132,10 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ConcentrationMeasurement.xml b/data_model/master/clusters/ConcentrationMeasurement.xml index b622a3560b4ff0..68d4b7937bf717 100644 --- a/data_model/master/clusters/ConcentrationMeasurement.xml +++ b/data_model/master/clusters/ConcentrationMeasurement.xml @@ -193,7 +193,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/DeviceEnergyManagement.xml b/data_model/master/clusters/DeviceEnergyManagement.xml index cb7f46c008f5e1..776a06f20b3fd4 100644 --- a/data_model/master/clusters/DeviceEnergyManagement.xml +++ b/data_model/master/clusters/DeviceEnergyManagement.xml @@ -62,7 +62,7 @@ Davis, CA 95616, USA - + @@ -123,27 +123,27 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -230,13 +230,13 @@ Davis, CA 95616, USA - + - + - + @@ -255,13 +255,13 @@ Davis, CA 95616, USA - + - + - + @@ -359,12 +359,14 @@ Davis, CA 95616, USA + + @@ -495,17 +497,18 @@ Davis, CA 95616, USA + - + - + diff --git a/data_model/master/clusters/EnergyCalendar.xml b/data_model/master/clusters/EnergyCalendar.xml index 5be0f8ff520aea..2ba93203618609 100644 --- a/data_model/master/clusters/EnergyCalendar.xml +++ b/data_model/master/clusters/EnergyCalendar.xml @@ -158,7 +158,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FanControl.xml b/data_model/master/clusters/FanControl.xml index 9eba1df549981c..ec05b6f74e069d 100644 --- a/data_model/master/clusters/FanControl.xml +++ b/data_model/master/clusters/FanControl.xml @@ -57,13 +57,12 @@ Davis, CA 95616, USA :xrefstyle: short --> - + - @@ -211,7 +210,6 @@ Davis, CA 95616, USA - @@ -233,7 +231,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FlowMeasurement.xml b/data_model/master/clusters/FlowMeasurement.xml index 85879977faa509..7ee97f586e708a 100644 --- a/data_model/master/clusters/FlowMeasurement.xml +++ b/data_model/master/clusters/FlowMeasurement.xml @@ -78,13 +78,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/GeneralCommissioningCluster.xml b/data_model/master/clusters/GeneralCommissioningCluster.xml index 8d6c428259f427..2342e6704c25c8 100644 --- a/data_model/master/clusters/GeneralCommissioningCluster.xml +++ b/data_model/master/clusters/GeneralCommissioningCluster.xml @@ -91,12 +91,12 @@ Davis, CA 95616, USA - + - + @@ -150,24 +150,35 @@ Davis, CA 95616, USA + + + + + + + + + + + diff --git a/data_model/master/clusters/Identify.xml b/data_model/master/clusters/Identify.xml index a6682b7233d30a..ddc3e33e9d28d3 100644 --- a/data_model/master/clusters/Identify.xml +++ b/data_model/master/clusters/Identify.xml @@ -63,7 +63,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/IlluminanceMeasurement.xml b/data_model/master/clusters/IlluminanceMeasurement.xml index f24df314ca2ead..d7cb9a993d0e4e 100644 --- a/data_model/master/clusters/IlluminanceMeasurement.xml +++ b/data_model/master/clusters/IlluminanceMeasurement.xml @@ -92,13 +92,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/JointFabricDatastoreCluster.xml b/data_model/master/clusters/JointFabricDatastoreCluster.xml index 79143f34d03f55..137edd2857f74d 100644 --- a/data_model/master/clusters/JointFabricDatastoreCluster.xml +++ b/data_model/master/clusters/JointFabricDatastoreCluster.xml @@ -55,12 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + @@ -267,6 +267,10 @@ Davis, CA 95616, USA + + + + diff --git a/data_model/master/clusters/JointFabricPKICluster.xml b/data_model/master/clusters/JointFabricPKICluster.xml index 7fba1e17376ecd..847d2548e3b1f1 100644 --- a/data_model/master/clusters/JointFabricPKICluster.xml +++ b/data_model/master/clusters/JointFabricPKICluster.xml @@ -55,12 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + @@ -80,7 +80,24 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + @@ -104,5 +121,20 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/LevelControl.xml b/data_model/master/clusters/LevelControl.xml index 28f88b96832c32..de342812287b0f 100644 --- a/data_model/master/clusters/LevelControl.xml +++ b/data_model/master/clusters/LevelControl.xml @@ -136,7 +136,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml index b991a36577bdd2..48cf6df4955a15 100644 --- a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA - + @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Mode_Dishwasher.xml b/data_model/master/clusters/Mode_Dishwasher.xml index 8069fdddcf0cc3..1c3a99b9e3d245 100644 --- a/data_model/master/clusters/Mode_Dishwasher.xml +++ b/data_model/master/clusters/Mode_Dishwasher.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/master/clusters/Mode_EVSE.xml b/data_model/master/clusters/Mode_EVSE.xml index fddd0e078c6df1..025e9de9884c89 100644 --- a/data_model/master/clusters/Mode_EVSE.xml +++ b/data_model/master/clusters/Mode_EVSE.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Mode_LaundryWasher.xml b/data_model/master/clusters/Mode_LaundryWasher.xml index 444d536fd178fd..b5f557a4b46a4b 100644 --- a/data_model/master/clusters/Mode_LaundryWasher.xml +++ b/data_model/master/clusters/Mode_LaundryWasher.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/master/clusters/Mode_MicrowaveOven.xml b/data_model/master/clusters/Mode_MicrowaveOven.xml index b5076d8c270099..24d682fecac68b 100644 --- a/data_model/master/clusters/Mode_MicrowaveOven.xml +++ b/data_model/master/clusters/Mode_MicrowaveOven.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Mode_Oven.xml b/data_model/master/clusters/Mode_Oven.xml index f7e8c8a4268cf2..a3e3323fe98777 100644 --- a/data_model/master/clusters/Mode_Oven.xml +++ b/data_model/master/clusters/Mode_Oven.xml @@ -65,6 +65,11 @@ Davis, CA 95616, USA + + + + + @@ -79,11 +84,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/master/clusters/Mode_RVCClean.xml b/data_model/master/clusters/Mode_RVCClean.xml index 26b5d15c185fe3..4ead99f0915adf 100644 --- a/data_model/master/clusters/Mode_RVCClean.xml +++ b/data_model/master/clusters/Mode_RVCClean.xml @@ -67,6 +67,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -81,11 +89,6 @@ Davis, CA 95616, USA - - - - - @@ -97,7 +100,7 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_RVCRun.xml b/data_model/master/clusters/Mode_RVCRun.xml index ad0d7601a45c22..f1d89e4c747106 100644 --- a/data_model/master/clusters/Mode_RVCRun.xml +++ b/data_model/master/clusters/Mode_RVCRun.xml @@ -67,6 +67,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -81,11 +89,6 @@ Davis, CA 95616, USA - - - - - @@ -97,7 +100,7 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_Refrigerator.xml b/data_model/master/clusters/Mode_Refrigerator.xml index 84410d1ddfc465..2728ac0f42b8fb 100644 --- a/data_model/master/clusters/Mode_Refrigerator.xml +++ b/data_model/master/clusters/Mode_Refrigerator.xml @@ -66,6 +66,11 @@ Davis, CA 95616, USA + + + + + @@ -80,11 +85,6 @@ Davis, CA 95616, USA - - - - - diff --git a/data_model/master/clusters/Mode_WaterHeater.xml b/data_model/master/clusters/Mode_WaterHeater.xml index 5aaf1d244f1898..cc9c96e484bce2 100644 --- a/data_model/master/clusters/Mode_WaterHeater.xml +++ b/data_model/master/clusters/Mode_WaterHeater.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OccupancySensing.xml b/data_model/master/clusters/OccupancySensing.xml index 4cd027deb07279..7ca0d3631dbe05 100644 --- a/data_model/master/clusters/OccupancySensing.xml +++ b/data_model/master/clusters/OccupancySensing.xml @@ -68,6 +68,7 @@ Davis, CA 95616, USA add sensitivity setting (via co-located BooleanStateConfiguration cluster on same endpoint); add new attribute for tuning the sensor's reporting; add event OccupancyChanged; + add `N` quality for HoldTime and other timing attributes; describe how to accommodate legacy clients"/> @@ -134,11 +135,12 @@ Davis, CA 95616, USA - + + @@ -171,8 +173,9 @@ Davis, CA 95616, USA - + + @@ -185,6 +188,7 @@ Davis, CA 95616, USA + @@ -210,6 +214,7 @@ Davis, CA 95616, USA + @@ -257,6 +262,7 @@ Davis, CA 95616, USA + @@ -305,6 +311,7 @@ Davis, CA 95616, USA + @@ -317,6 +324,7 @@ Davis, CA 95616, USA + @@ -336,6 +344,7 @@ Davis, CA 95616, USA + @@ -356,6 +365,7 @@ Davis, CA 95616, USA + @@ -368,6 +378,7 @@ Davis, CA 95616, USA + @@ -387,6 +398,7 @@ Davis, CA 95616, USA + diff --git a/data_model/master/clusters/OperationalState_RVC.xml b/data_model/master/clusters/OperationalState_RVC.xml index 5d2d28db2c2cad..9b83bc4dfde257 100644 --- a/data_model/master/clusters/OperationalState_RVC.xml +++ b/data_model/master/clusters/OperationalState_RVC.xml @@ -108,10 +108,10 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/PressureMeasurement.xml b/data_model/master/clusters/PressureMeasurement.xml index bf9b6a9286e381..09b9577cc84585 100644 --- a/data_model/master/clusters/PressureMeasurement.xml +++ b/data_model/master/clusters/PressureMeasurement.xml @@ -83,18 +83,18 @@ Davis, CA 95616, USA - + - + - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,21 +118,21 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/master/clusters/PumpConfigurationControl.xml b/data_model/master/clusters/PumpConfigurationControl.xml index 95ede00d0eb72e..9b7e4ab56dc5c2 100644 --- a/data_model/master/clusters/PumpConfigurationControl.xml +++ b/data_model/master/clusters/PumpConfigurationControl.xml @@ -55,13 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - @@ -97,37 +96,44 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -137,7 +143,8 @@ Davis, CA 95616, USA - + @@ -331,12 +338,12 @@ Davis, CA 95616, USA - + - + @@ -346,7 +353,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ServiceArea.xml b/data_model/master/clusters/ServiceArea.xml index 6a54264a94928b..2533d4b549d2f0 100644 --- a/data_model/master/clusters/ServiceArea.xml +++ b/data_model/master/clusters/ServiceArea.xml @@ -113,7 +113,7 @@ Davis, CA 95616, USA - + @@ -121,7 +121,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Switch.xml b/data_model/master/clusters/Switch.xml index 92489c1e9228a3..8662d262f0b50e 100644 --- a/data_model/master/clusters/Switch.xml +++ b/data_model/master/clusters/Switch.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA + Introduction of ActionSwitch feature flag."/> diff --git a/data_model/master/clusters/TemperatureControl.xml b/data_model/master/clusters/TemperatureControl.xml index 79519716ea1cf8..511761b24b9e89 100644 --- a/data_model/master/clusters/TemperatureControl.xml +++ b/data_model/master/clusters/TemperatureControl.xml @@ -113,7 +113,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/TemperatureMeasurement.xml b/data_model/master/clusters/TemperatureMeasurement.xml index 0935b18edab675..5c1df46ccbf115 100644 --- a/data_model/master/clusters/TemperatureMeasurement.xml +++ b/data_model/master/clusters/TemperatureMeasurement.xml @@ -79,18 +79,18 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/master/clusters/Thermostat.xml b/data_model/master/clusters/Thermostat.xml index faf147839facb4..6c5584e087d47c 100644 --- a/data_model/master/clusters/Thermostat.xml +++ b/data_model/master/clusters/Thermostat.xml @@ -63,8 +63,7 @@ Davis, CA 95616, USA - @@ -653,12 +652,12 @@ Davis, CA 95616, USA - + - + @@ -996,7 +995,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ValveConfigurationControl.xml b/data_model/master/clusters/ValveConfigurationControl.xml index 03d40acd480ff4..6f38375a1a31c6 100644 --- a/data_model/master/clusters/ValveConfigurationControl.xml +++ b/data_model/master/clusters/ValveConfigurationControl.xml @@ -57,10 +57,9 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - @@ -143,7 +142,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/WaterContentMeasurement.xml b/data_model/master/clusters/WaterContentMeasurement.xml index af11c9cf8d514c..b613bf4e1522fb 100644 --- a/data_model/master/clusters/WaterContentMeasurement.xml +++ b/data_model/master/clusters/WaterContentMeasurement.xml @@ -78,18 +78,18 @@ Davis, CA 95616, USA - + - + - + \ No newline at end of file diff --git a/data_model/master/clusters/WindowCovering.xml b/data_model/master/clusters/WindowCovering.xml index f8c60b46901dc9..09133513af736a 100644 --- a/data_model/master/clusters/WindowCovering.xml +++ b/data_model/master/clusters/WindowCovering.xml @@ -57,14 +57,13 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - @@ -420,7 +419,7 @@ Davis, CA 95616, USA - + @@ -432,7 +431,7 @@ Davis, CA 95616, USA - + @@ -464,7 +463,7 @@ Davis, CA 95616, USA - + @@ -474,7 +473,7 @@ Davis, CA 95616, USA - + @@ -517,7 +516,7 @@ Davis, CA 95616, USA - + @@ -528,7 +527,7 @@ Davis, CA 95616, USA - + @@ -652,12 +651,8 @@ Davis, CA 95616, USA - - - - - - + + @@ -687,12 +682,8 @@ Davis, CA 95616, USA - - - - - - + + diff --git a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 4368d991c832f4..62633f55cf08cc 100644 --- a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + @@ -154,6 +154,10 @@ Davis, CA 95616, USA + + + + diff --git a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml index 22cc88097acf75..ddebe95679370e 100644 --- a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml @@ -84,12 +84,10 @@ Davis, CA 95616, USA - - - + - + @@ -123,24 +121,17 @@ Davis, CA 95616, USA - - - - - - + - + - - + - + - \ No newline at end of file diff --git a/data_model/master/clusters/cluster_ids.json b/data_model/master/clusters/cluster_ids.json index 5896dc1a366f73..ee34f4df93d55f 100644 --- a/data_model/master/clusters/cluster_ids.json +++ b/data_model/master/clusters/cluster_ids.json @@ -121,5 +121,7 @@ "1296": "Content App Observer", "1872": "Ecosystem Information", "1873": "Commissioner Control", + "1874": "Joint Fabric Datastore Cluster", + "1875": "Joint Fabric PKI", "2822": "Meter Identification" } diff --git a/data_model/master/device_types/JointFabricAdmin.xml b/data_model/master/device_types/JointFabricAdmin.xml index 7d29cbba1305d5..6c63dc9bdd96a1 100644 --- a/data_model/master/device_types/JointFabricAdmin.xml +++ b/data_model/master/device_types/JointFabricAdmin.xml @@ -55,16 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + diff --git a/data_model/master/device_types/MountedDimmableLoadControl.xml b/data_model/master/device_types/MountedDimmableLoadControl.xml index 2527eb6aaefcd2..d0cee6e5ef37cd 100644 --- a/data_model/master/device_types/MountedDimmableLoadControl.xml +++ b/data_model/master/device_types/MountedDimmableLoadControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/MountedOnOffControl.xml b/data_model/master/device_types/MountedOnOffControl.xml index 1be3cf746418aa..09628bb4e0e9f0 100644 --- a/data_model/master/device_types/MountedOnOffControl.xml +++ b/data_model/master/device_types/MountedOnOffControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ThreadBorderRouter.xml b/data_model/master/device_types/ThreadBorderRouter.xml index abe38a81396cd6..792f002801b9a0 100644 --- a/data_model/master/device_types/ThreadBorderRouter.xml +++ b/data_model/master/device_types/ThreadBorderRouter.xml @@ -68,5 +68,8 @@ Davis, CA 95616, USA + + + \ No newline at end of file diff --git a/data_model/master/device_types/WindowCovering.xml b/data_model/master/device_types/WindowCovering.xml index 0e907045e3e1b6..da8780b3c94be4 100644 --- a/data_model/master/device_types/WindowCovering.xml +++ b/data_model/master/device_types/WindowCovering.xml @@ -84,36 +84,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/spec_sha b/data_model/master/spec_sha index 8f9072976d9c15..a399f222280c76 100644 --- a/data_model/master/spec_sha +++ b/data_model/master/spec_sha @@ -1 +1 @@ -3432866fff8e0c21e1189a10d4ee66b9eb004844 +ec20ddf482db8deffe8b2eb745e34d2f9cea72b2 diff --git a/docs/spec_clusters.md b/docs/spec_clusters.md index 05bd215fe583dc..43db0725793a8a 100644 --- a/docs/spec_clusters.md +++ b/docs/spec_clusters.md @@ -125,3 +125,6 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1296 |0x0510 |Content App Observer | |1872 |0x0750 |Ecosystem Information | |1873 |0x0751 |Commissioner Control | +|1874 |0x0752 |Joint Fabric Datastore Cluster | +|1875 |0x0753 |Joint Fabric PKI | +|2822 |0x0B06 |Meter Identification | diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index b279c759641249..1444966fe5ea1a 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -403,6 +403,8 @@ def get_command_type(self, element: ElementTree.Element) -> CommandType: return CommandType.UNKNOWN if element.attrib['direction'].lower() == 'commandtoserver': return CommandType.ACCEPTED + if element.attrib['direction'].lower() == 'responsefromclient': + return CommandType.UNKNOWN raise Exception(f"Unknown direction: {element.attrib['direction']}") except KeyError: return CommandType.UNKNOWN From 1685777f079a7796bbc6bbbafaab41490c98c357 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 16:01:59 -0400 Subject: [PATCH 53/70] IDM-10.2: Fix provisional check (#35407) --- src/python_testing/spec_parsing_support.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 1444966fe5ea1a..445e168ecb4f5a 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -216,8 +216,9 @@ def __init__(self, cluster, cluster_id, name): except (KeyError, StopIteration): self._derived = None - if list(cluster.iter('provisionalConform')): - self._is_provisional = True + for id in cluster.iter('clusterIds'): + if list(id.iter('provisionalConform')): + self._is_provisional = True try: classification = next(cluster.iter('classification')) From e2edc0c27d050ba8db29591c053970a8ca887b10 Mon Sep 17 00:00:00 2001 From: Manjunath Date: Wed, 4 Sep 2024 16:42:06 -0400 Subject: [PATCH 54/70] [YAML] Fixed script issues (#35309) * Modified test Test_TC_CC_4_2 Test_TC_CC_7_2 Test_TC_PWRTL_1_1 Test_TC_SWTCH_3_2 Test_TC_OO_2_6 * Fix TC-OO-2.6 and SWTCH_3_2 tests * Restyled by whitespace * Restyled by prettier-json --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_CC_4_2.yaml | 16 + .../suites/certification/Test_TC_CC_7_2.yaml | 2 +- .../suites/certification/Test_TC_OO_2_6.yaml | 58 ++ .../certification/Test_TC_PWRTL_1_1.yaml | 5 +- .../certification/Test_TC_SWTCH_3_2.yaml | 960 +++++++++++++----- src/app/tests/suites/ciTests.json | 2 +- 6 files changed, 767 insertions(+), 276 deletions(-) create mode 100644 src/app/tests/suites/certification/Test_TC_OO_2_6.yaml diff --git a/src/app/tests/suites/certification/Test_TC_CC_4_2.yaml b/src/app/tests/suites/certification/Test_TC_CC_4_2.yaml index 0438a6e376f0ee..cc21bc18a83e94 100644 --- a/src/app/tests/suites/certification/Test_TC_CC_4_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_CC_4_2.yaml @@ -393,6 +393,22 @@ tests: response: error: INVALID_COMMAND + - label: + "Step 6c: TH sends MoveSaturation command to DUT with MoveMode=0x00 + (stop) and Rate=0 (units/s)" + command: "MoveSaturation" + PICS: CC.S.F00 && CC.S.C04.Rsp + arguments: + values: + - name: "MoveMode" + value: 0 + - name: "Rate" + value: 0 + - name: "OptionsMask" + value: 0 + - name: "OptionsOverride" + value: 0 + - label: "Turn off light that we turned on" PICS: OO.S.C00.Rsp cluster: "On/Off" diff --git a/src/app/tests/suites/certification/Test_TC_CC_7_2.yaml b/src/app/tests/suites/certification/Test_TC_CC_7_2.yaml index 18f1113d4928b6..23397fa9cd1d01 100644 --- a/src/app/tests/suites/certification/Test_TC_CC_7_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_CC_7_2.yaml @@ -332,7 +332,7 @@ tests: - label: "Step 5a: TH sends EnhancedMoveHue command to DUT with MoveMode=0x01 (up) and Rate=0 (units/s)" - PICS: CC.S.F01 && CC.S.C41.Rsp" + PICS: CC.S.F01 && CC.S.C41.Rsp command: "EnhancedMoveHue" arguments: values: diff --git a/src/app/tests/suites/certification/Test_TC_OO_2_6.yaml b/src/app/tests/suites/certification/Test_TC_OO_2_6.yaml new file mode 100644 index 00000000000000..b133e1f77541b9 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_OO_2_6.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: 4.1.6. [TC-OO-2.6] OffOnly Feature with DUT as Server + +PICS: + - OO.S + - OO.S.F02 + +config: + nodeId: 0x12344321 + cluster: "On/Off" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Step 1: TH reads the FeatureMap attribute from DUT" + PICS: OO.S.F02 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4] + + - label: + "Step 2: TH sends On command to the On/Off Cluster of DUT on + PIXIT.OO.ENDPOINT" + PICS: OO.S.F02 && OO.S.C01.Rsp + command: "On" + response: + error: UNSUPPORTED_COMMAND + + - label: + "Step 3: TH sends Toggle command to the On/Off Cluster of DUT on + PIXIT.OO.ENDPOINT" + PICS: OO.S.F02 && OO.S.C02.Rsp + command: "Toggle" + response: + error: UNSUPPORTED_COMMAND diff --git a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml index ad4fb3aaa031ca..5d64bedf47ebb3 100644 --- a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml @@ -11,7 +11,6 @@ # 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default name: 44.1.1. [TC-PWRTL-1.1] Global Attributes with DUT as Server @@ -88,7 +87,7 @@ tests: hasMasksSet: [0x4, 0x8] - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PWRTL.S.F02 && !PWRTL.S.F03" + PICS: " !PWRTL.S.F02 && !PWRTL.S.F03 " command: "readAttribute" attribute: "AttributeList" response: @@ -99,7 +98,7 @@ tests: - label: "Step 4b: TH reads feature dependent attribute(AvailableEndpoints) AttributeList from DUT" - PICS: "PWRTL.S.F02 && !PWRTL.S.F03" + PICS: PWRTL.S.F02 command: "readAttribute" attribute: "AttributeList" response: diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_3_2.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_3_2.yaml index be4f2a4683de38..1a2009c320365e 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_3_2.yaml @@ -28,6 +28,17 @@ tests: - label: "Note" verification: | For DUT as client test cases, Chip-tool command used below are an example to verify the functionality. For certification test, we expect DUT should have a capability or way to run the equivalent command. + + Execute the below mentioned command to put TH(Reference app) into a commissionable state in RPI platform, Pls use equivalent command on the respective platform + ./chip-all-clusters-app --trace_decode 1 + + Once TH reach the commissionable state pls send below mentioned command on DUT(chip-tool) in RPI platform. Pls use equivalent command on the respective platform + + ./chip-tool pairing onnetwork 1 20202021 --trace_decode 1 + + Verify the commissioning completed with success on DUT(Chip-tool) + + [1650455358.501816][4366:4371] CHIP:TOO: Device commissioning completed with success disabled: true - label: "Note" @@ -99,6 +110,14 @@ tests: no messages needed, TH checks consistency of PICS flags disabled: true + - label: + "Step 0h: FAIL the test - when supporting SWTCH.C.F02(MSR) the + SWTCH.C.F05(AS) must not be supported" + PICS: SWTCH.C.F02 && SWTCH.C.F05 + verification: | + no messages needed, TH checks consistency of PICS flags + disabled: true + - label: "Step 1a: Commission DUT to TH. Use client mechanism to set it up so switch state can be observed (e.g. UI shows state of switch) and/or @@ -230,83 +249,42 @@ tests: [1659621148.832380][8590:8590] CHIP:ZCL: SwitchServer: OnSwitchLatch [1659621148.832494][8590:8590] CHIP:EVL: LogEvent event number: 0x0000000000000007 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Sys timestamp: 0x00000000022D0CBB - In parallel to this Check the CurrentPosition value. + DUT Reads the CurrentPosition value. ./chip-tool switch read current-position 1 1 - Verify CurrentPosition value is 1 on TH (all-cluster-app) logs - - [1686292319.379553][30986:30986] CHIP:DMG: ReportDataMessage = - [1686292319.379564][30986:30986] CHIP:DMG: { - [1686292319.379572][30986:30986] CHIP:DMG: AttributeReportIBs = - [1686292319.379590][30986:30986] CHIP:DMG: [ - [1686292319.379599][30986:30986] CHIP:DMG: AttributeReportIB = - [1686292319.379616][30986:30986] CHIP:DMG: { - [1686292319.379625][30986:30986] CHIP:DMG: AttributeDataIB = - [1686292319.379637][30986:30986] CHIP:DMG: { - [1686292319.379648][30986:30986] CHIP:DMG: DataVersion = 0xbae40564, - [1686292319.379659][30986:30986] CHIP:DMG: AttributePathIB = - [1686292319.379670][30986:30986] CHIP:DMG: { - [1686292319.379682][30986:30986] CHIP:DMG: Endpoint = 0x1, - [1686292319.379695][30986:30986] CHIP:DMG: Cluster = 0x3b, - [1686292319.379707][30986:30986] CHIP:DMG: Attribute = 0x0000_0001, - [1686292319.379717][30986:30986] CHIP:DMG: } - [1686292319.379731][30986:30986] CHIP:DMG: - [1686292319.379744][30986:30986] CHIP:DMG: Data = 1, - [1686292319.379754][30986:30986] CHIP:DMG: }, - [1686292319.379769][30986:30986] CHIP:DMG: - [1686292319.379778][30986:30986] CHIP:DMG: }, - [1686292319.379794][30986:30986] CHIP:DMG: - [1686292319.379803][30986:30986] CHIP:DMG: ], - [1686292319.379819][30986:30986] CHIP:DMG: - [1686292319.379829][30986:30986] CHIP:DMG: SuppressResponse = true, - [1686292319.379839][30986:30986] CHIP:DMG: InteractionModelRevision = 1 - [1686292319.379847][30986:30986] CHIP:DMG: } - - - TH simulates operation of the switch by changing state (attribute CurrentPosition) from 1 to 0 and read the CurrentPosition attribute + Verify CurrentPosition value is 1 on DUT (chip-tool) : + + [1722927679.396] [30503:30505] [DMG] } + [1722927679.396] [30503:30505] [TOO] Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 1761848624 + [1722927679.397] [30503:30505] [TOO] CurrentPosition: 1 + + + TH simulates operation of the switch by changing state (attribute CurrentPosition) from 1 to 0 and DUT reads the CurrentPosition attribute After 10 seconds, repeat the command with /tmp/chip_all_clusters_fifo using with value 0 as position echo '{"Name":"SwitchLatched","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + Verify SwitchLatched event with NewPosition set to 0 on TH(all-cluster-app) log: + [1686292713.872327][30986:30989] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":0}" [1686292713.872583][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae40566 [1686292713.872617][30986:30986] CHIP:-: The latching switch is moved to a new position:0 [1686292713.872629][30986:30986] CHIP:ZCL: SwitchServer: OnSwitchLatch + DUT Reads the CurrentPosition value. + ./chip-tool switch read current-position 1 1 - Verify CurrentPosition value is 0 on TH (all-cluster-app) logs - - [1686293150.796547][30986:30986] CHIP:DMG: ReportDataMessage = - [1686293150.796549][30986:30986] CHIP:DMG: { - [1686293150.796551][30986:30986] CHIP:DMG: AttributeReportIBs = - [1686293150.796555][30986:30986] CHIP:DMG: [ - [1686293150.796557][30986:30986] CHIP:DMG: AttributeReportIB = - [1686293150.796561][30986:30986] CHIP:DMG: { - [1686293150.796564][30986:30986] CHIP:DMG: AttributeDataIB = - [1686293150.796567][30986:30986] CHIP:DMG: { - [1686293150.796570][30986:30986] CHIP:DMG: DataVersion = 0xbae40566, - [1686293150.796572][30986:30986] CHIP:DMG: AttributePathIB = - [1686293150.796575][30986:30986] CHIP:DMG: { - [1686293150.796578][30986:30986] CHIP:DMG: Endpoint = 0x1, - [1686293150.796581][30986:30986] CHIP:DMG: Cluster = 0x3b, - [1686293150.796584][30986:30986] CHIP:DMG: Attribute = 0x0000_0001, - [1686293150.796587][30986:30986] CHIP:DMG: } - [1686293150.796590][30986:30986] CHIP:DMG: - [1686293150.796594][30986:30986] CHIP:DMG: Data = 0, - [1686293150.796597][30986:30986] CHIP:DMG: }, - [1686293150.796601][30986:30986] CHIP:DMG: - [1686293150.796603][30986:30986] CHIP:DMG: }, - [1686293150.796607][30986:30986] CHIP:DMG: - [1686293150.796609][30986:30986] CHIP:DMG: ], - [1686293150.796613][30986:30986] CHIP:DMG: - [1686293150.796616][30986:30986] CHIP:DMG: SuppressResponse = true, - [1686293150.796618][30986:30986] CHIP:DMG: InteractionModelRevision = 1 - [1686293150.796620][30986:30986] CHIP:DMG: } - - Repeat the above Steps over 1 minute period of time + Verify CurrentPosition value is 0 on DUT (chip-tool) : + + [1722927891.728] [30554:30556] [DMG] } + [1722927891.728] [30554:30556] [TOO] Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 1761848625 + [1722927891.729] [30554:30556] [TOO] CurrentPosition: 0 + + + Repeat the above Steps over 1 minute period of time by changing the New Position 1 to 0 and 0 to 1. AND DUT reads Current position value regularly. disabled: true - label: @@ -329,32 +307,99 @@ tests: [1659621148.832494][8590:8590] CHIP:EVL: LogEvent event number: 0x0000000000000007 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Sys timestamp: 0x00000000022D0CBB Send the SwitchLatched event on every change of position + ./chip-tool switch read-event switch-latched 1 1 - Verify SwitchLatched Position is changing for 0 to 1 on DUT(chip-tool) Log: - - [1659680091.150093][2592:2597] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659680091.150114][2592:2597] CHIP:TOO: Event number: 6 - [1659680091.150135][2592:2597] CHIP:TOO: Priority: Info - [1659680091.150155][2592:2597] CHIP:TOO: Timestamp: 2402459 - [1659680091.150180][2592:2597] CHIP:TOO: SwitchLatched: { - [1659680091.150202][2592:2597] CHIP:TOO: NewPosition: 1 - [1659680091.150222][2592:2597] CHIP:TOO: } - [1659680091.150302][2592:2597] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659680091.150324][2592:2597] CHIP:TOO: Event number: 7 - [1659680091.150345][2592:2597] CHIP:TOO: Priority: Info - [1659680091.150365][2592:2597] CHIP:TOO: Timestamp: 2431571 - [1659680091.150390][2592:2597] CHIP:TOO: SwitchLatched: { - [1659680091.150411][2592:2597] CHIP:TOO: NewPosition: 0 - [1659680091.150432][2592:2597] CHIP:TOO: } - [1659680091.150509][2592:2597] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659680091.150531][2592:2597] CHIP:TOO: Event number: 8 - [1659680091.150551][2592:2597] CHIP:TOO: Priority: Info - [1659680091.150572][2592:2597] CHIP:TOO: Timestamp: 2456884 - [1659680091.150597][2592:2597] CHIP:TOO: SwitchLatched: { - [1659680091.150630][2592:2597] CHIP:TOO: NewPosition: 1 <= this value will change for every change in position of simulated switch + Verify SwitchLatched event with NewPosition is changing for 0 to 1 on DUT(chip-tool) Log: + + [1722928087.971] [30606:30608] [DMG] SuppressResponse = true, + [1722928087.971] [30606:30608] [DMG] InteractionModelRevision = 11 + [1722928087.972] [30606:30608] [DMG] } + [1722928087.972] [30606:30608] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928087.972] [30606:30608] [TOO] Event number: 65540 + [1722928087.973] [30606:30608] [TOO] Priority: Info + [1722928087.973] [30606:30608] [TOO] Timestamp: 1722927614282 + [1722928087.973] [30606:30608] [TOO] SwitchLatched: { + [1722928087.973] [30606:30608] [TOO] NewPosition: 0 + [1722928087.973] [30606:30608] [TOO] } + [1722928087.973] [30606:30608] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928087.974] [30606:30608] [TOO] Event number: 65541 + [1722928087.974] [30606:30608] [TOO] Priority: Info + [1722928087.974] [30606:30608] [TOO] Timestamp: 1722927671837 + [1722928087.974] [30606:30608] [TOO] SwitchLatched: { + [1722928087.974] [30606:30608] [TOO] NewPosition: 1 + [1722928087.974] [30606:30608] [TOO] } + [1722928087.974] [30606:30608] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928087.974] [30606:30608] [TOO] Event number: 65542 + [1722928087.974] [30606:30608] [TOO] Priority: Info + [1722928087.975] [30606:30608] [TOO] Timestamp: 1722927866804 + [1722928087.975] [30606:30608] [TOO] SwitchLatched: { + [1722928087.975] [30606:30608] [TOO] NewPosition: 0 + [1722928087.975] [30606:30608] [TOO] } + [1722928087.975] [30606:30608] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928087.975] [30606:30608] [TOO] Event number: 65543 + [1722928087.975] [30606:30608] [TOO] Priority: Info + [1722928087.975] [30606:30608] [TOO] Timestamp: 1722928067383 + [1722928087.975] [30606:30608] [TOO] SwitchLatched: { + [1722928087.976] [30606:30608] [TOO] NewPosition: 1 + [1722928087.976] [30606:30608] [TOO] } + After 10 seconds, Send the above commands with NewPosition set to 0 + + echo '{"Name":"SwitchLatched","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ + + Verify SwitchLatched event with NewPosition set to 0 on TH(all-cluster-app) log: + + [1722602668.258] [211132:211134] [-] Received payload: "{"Name":"SwitchLatched","NewPosition":0}" + [1722602668.258] [211132:211132] [-] The latching switch is moved to a new position:0 + [1722602668.258] [211132:211132] [ZCL] SwitchServer: OnSwitchLatch + + ./chip-tool switch read-event switch-latched 1 1 + + Verify SwitchLatched event with NewPosition is changing for 1 to 0 on DUT(chip-tool) Log: + + [1722928245.303] [30654:30656] [DMG] SuppressResponse = true, + [1722928245.303] [30654:30656] [DMG] InteractionModelRevision = 11 + [1722928245.303] [30654:30656] [DMG] } + [1722928245.304] [30654:30656] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928245.304] [30654:30656] [TOO] Event number: 65540 + [1722928245.304] [30654:30656] [TOO] Priority: Info + [1722928245.304] [30654:30656] [TOO] Timestamp: 1722927614282 + [1722928245.305] [30654:30656] [TOO] SwitchLatched: { + [1722928245.305] [30654:30656] [TOO] NewPosition: 0 + [1722928245.305] [30654:30656] [TOO] } + [1722928245.305] [30654:30656] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928245.305] [30654:30656] [TOO] Event number: 65541 + [1722928245.305] [30654:30656] [TOO] Priority: Info + [1722928245.305] [30654:30656] [TOO] Timestamp: 1722927671837 + [1722928245.306] [30654:30656] [TOO] SwitchLatched: { + [1722928245.306] [30654:30656] [TOO] NewPosition: 1 + [1722928245.306] [30654:30656] [TOO] } + [1722928245.306] [30654:30656] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928245.306] [30654:30656] [TOO] Event number: 65542 + [1722928245.306] [30654:30656] [TOO] Priority: Info + [1722928245.306] [30654:30656] [TOO] Timestamp: 1722927866804 + [1722928245.306] [30654:30656] [TOO] SwitchLatched: { + [1722928245.307] [30654:30656] [TOO] NewPosition: 0 + [1722928245.307] [30654:30656] [TOO] } + [1722928245.307] [30654:30656] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928245.307] [30654:30656] [TOO] Event number: 65543 + [1722928245.307] [30654:30656] [TOO] Priority: Info + [1722928245.307] [30654:30656] [TOO] Timestamp: 1722928067383 + [1722928245.307] [30654:30656] [TOO] SwitchLatched: { + [1722928245.307] [30654:30656] [TOO] NewPosition: 1 + [1722928245.307] [30654:30656] [TOO] } + [1722928245.308] [30654:30656] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 + [1722928245.308] [30654:30656] [TOO] Event number: 65544 + [1722928245.308] [30654:30656] [TOO] Priority: Info + [1722928245.308] [30654:30656] [TOO] Timestamp: 1722928209578 + [1722928245.308] [30654:30656] [TOO] SwitchLatched: { + [1722928245.308] [30654:30656] [TOO] NewPosition: 0 + [1722928245.308] [30654:30656] [TOO] } + + + Repeat above Steps back every 10 seconds (over a 1 minute period) by changing the New Position 1 to 0 and 0 to 1 disabled: true @@ -375,13 +420,12 @@ tests: - label: "Step 3b: DUT reads global attribute FeatureMap" PICS: SWTCH.C.F01 verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch(LS) or MS, MSR, MSL, MSM. - - In Raspi platform LS feature is implemented, So below mentioned log is for reference only + Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch(LS) or MS, MSR, MSL, MSM or MS, MSL, MSM, AS ./chip-tool switch read feature-map 1 1 - Verify FeatureMap value is 30 On TH (all-clusters-app) log + Verify FeatureMap value is 30 If (MS, MSR, MSL, MSM) features are supported or + Value is 58 If (MS, MSL, MSM, AS) feature are supported On TH (all-clusters-app) log CHIP:DMG: ReportDataMessage = [1671450600.457719][8426:8426] CHIP:DMG: { @@ -399,7 +443,7 @@ tests: [1671450600.458108][8426:8426] CHIP:DMG: Attribute = 0x0000_FFFC, [1671450600.458122][8426:8426] CHIP:DMG: } [1671450600.458137][8426:8426] CHIP:DMG: - [1671450600.458151][8426:8426] CHIP:DMG: Data = 30, + [1671450600.458151][8426:8426] CHIP:DMG: Data = 58, [1671450600.458161][8426:8426] CHIP:DMG: }, [1671450600.458179][8426:8426] CHIP:DMG: [1671450600.458188][8426:8426] CHIP:DMG: }, @@ -416,7 +460,7 @@ tests: verification: | ./chip-tool switch read number-of-positions 1 1 - Verify NumberOfPositions value is 2 in TH (all-clusters-app) log + Verify NumberOfPositions value is 2 On TH (all-clusters-app) log DMG: ReportDataMessage = [1671450651.817816][8426:8426] CHIP:DMG: { @@ -447,9 +491,8 @@ tests: disabled: true - label: - "Step 3d: DUT sets up eventing (InitialPress and ShortRelease; if - SWTCH.C.F03(MSL) also LongPress and LongRelease) so it will receive - events when the switch is operated" + "Step 3d: DUT subscribes to all switch events on the endpoint, so it + will receive events when the switch is operated" PICS: SWTCH.C.F01 && SWTCH.C.M.SwitchStateEventing verification: | Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. @@ -469,78 +512,89 @@ tests: Verify InitialPress event with NewPosition set to 0 on DUT(chip-tool) log: - [1659683181.743214][2829:2835] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1659683181.743251][2829:2835] CHIP:TOO: Event number: 10 - [1659683181.743285][2829:2835] CHIP:TOO: Priority: Info - [1659683181.743319][2829:2835] CHIP:TOO: Timestamp: 4066882 - [1659683181.743419][2829:2835] CHIP:TOO: InitialPress: { - [1659683181.743470][2829:2835] CHIP:TOO: NewPosition: 0 - [1659683181.743506][2829:2835] CHIP:TOO: } + [1722928508.108] [30722:30724] [DMG] SuppressResponse = true, + [1722928508.108] [30722:30724] [DMG] InteractionModelRevision = 11 + [1722928508.108] [30722:30724] [DMG] } + [1722928508.109] [30722:30724] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722928508.109] [30722:30724] [TOO] Event number: 65545 + [1722928508.109] [30722:30724] [TOO] Priority: Info + [1722928508.109] [30722:30724] [TOO] Timestamp: 1722928471541 + [1722928508.110] [30722:30724] [TOO] InitialPress: { + [1722928508.110] [30722:30724] [TOO] NewPosition: 0 + [1722928508.110] [30722:30724] [TOO] } echo '{"Name":"ShortRelease","PreviousPosition":0}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) Verify ShortRelease event with PreviousPosition set to 0 on TH(all-cluster-app) log: - [1659683678.805455][2530:2538] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":0}" - [1659683678.805739][2530:2530] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to ee5e7715 - [1659683678.805777][2530:2530] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1659683678.805858][2530:2530] CHIP:ZCL: SwitchServer: OnShortRelease + [1722928571.190] [29970:29972] [-] Received payload: "{"Name":"ShortRelease","PreviousPosition":0}" + [1722928571.191] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released:0 + [1722928571.191] [29970:29970] [ZCL] SwitchServer: OnShortRelease ./chip-tool switch read-event short-release 1 1 Verify ShortRelease event with PreviousPosition set to 0 on DUT(chip-tool) log: - [1659683195.217253][2838:2843] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1659683195.217275][2838:2843] CHIP:TOO: Event number: 11 - [1659683195.217294][2838:2843] CHIP:TOO: Priority: Info - [1659683195.217313][2838:2843] CHIP:TOO: Timestamp: 4137135 - [1659683195.217377][2838:2843] CHIP:TOO: ShortRelease: { - [1659683195.217411][2838:2843] CHIP:TOO: PreviousPosition: 0 - [1659683195.217432][2838:2843] CHIP:TOO: } + [1722928663.399] [30761:30763] [DMG] SuppressResponse = true, + [1722928663.399] [30761:30763] [DMG] InteractionModelRevision = 11 + [1722928663.399] [30761:30763] [DMG] } + [1722928663.400] [30761:30763] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722928663.400] [30761:30763] [TOO] Event number: 65546 + [1722928663.400] [30761:30763] [TOO] Priority: Info + [1722928663.400] [30761:30763] [TOO] Timestamp: 1722928571191 + [1722928663.400] [30761:30763] [TOO] ShortRelease: { + [1722928663.400] [30761:30763] [TOO] PreviousPosition: 0 + [1722928663.400] [30761:30763] [TOO] } - if SWTCH.C.F03, also: echo '{"Name":"LongPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) Verify LongPress event with NewPosition set to 1 on TH(all-cluster-app) log: - [1686294416.290491][30986:30989] CHIP:-: Received payload: "{"Name":"LongPress","NewPosition":1}" - [1686294416.290729][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae40568 - [1686294416.290761][30986:30986] CHIP:-: The new position when the momentary switch has been pressed for a long time:1 - [1686294416.290775][30986:30986] CHIP:ZCL: SwitchServer: OnLongPress + [1722928724.336] [29970:29972] [-] Received payload: "{"Name":"LongPress","NewPosition":1}" + [1722928724.336] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad34 + [1722928724.337] [29970:29970] [-] The new position when the momentary switch has been pressed for a long time:1 + [1722928724.337] [29970:29970] [ZCL] SwitchServer: OnLongPress ./chip-tool switch read-event long-press 1 1 - Verify LongPress event with NewPosition set to 1 on TH(chip-tool) log: + Verify LongPress event with NewPosition set to 1 on DUT(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 5 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 29687750 - [1659527630.476887][4774:4779] CHIP:TOO: LongPress: { - [1659527630.476934][4774:4779] CHIP:TOO: NewPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + [1722928792.354] [30803:30805] [DMG] SuppressResponse = true, + [1722928792.354] [30803:30805] [DMG] InteractionModelRevision = 11 + [1722928792.354] [30803:30805] [DMG] } + [1722928792.354] [30803:30805] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0002 + [1722928792.354] [30803:30805] [TOO] Event number: 65547 + [1722928792.355] [30803:30805] [TOO] Priority: Info + [1722928792.355] [30803:30805] [TOO] Timestamp: 1722928724337 + [1722928792.355] [30803:30805] [TOO] LongPress: { + [1722928792.355] [30803:30805] [TOO] NewPosition: 1 + [1722928792.355] [30803:30805] [TOO] } echo '{"Name":"LongRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) Verify LongRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: - [1686294209.671991][30986:30989] CHIP:-: Received payload: "{"Name":"LongRelease","PreviousPosition":1}" - [1686294209.672192][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae40567 - [1686294209.672219][30986:30986] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released after having been pressed for a long time:1 - [1686294209.672229][30986:30986] CHIP:ZCL: SwitchServer: OnLongRelease + [1722928835.353] [29970:29972] [-] Received payload: "{"Name":"LongRelease","PreviousPosition":1}" + [1722928835.354] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad35 + [1722928835.354] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released after having been pressed for a long time:1 + [1722928835.354] [29970:29970] [ZCL] SwitchServer: OnLongRelease + ./chip-tool switch read-event long-release 1 1 Verify LongRelease event with PreviousPosition set to 1 on DUT(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 6 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 296889750 - [1659527630.476887][4774:4779] CHIP:TOO: LongRelease: { - [1659527630.476934][4774:4779] CHIP:TOO: PreviousPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + [1722928919.331] [30840:30842] [DMG] SuppressResponse = true, + [1722928919.331] [30840:30842] [DMG] InteractionModelRevision = 11 + [1722928919.331] [30840:30842] [DMG] } + [1722928919.332] [30840:30842] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0004 + [1722928919.332] [30840:30842] [TOO] Event number: 65550 + [1722928919.332] [30840:30842] [TOO] Priority: Info + [1722928919.332] [30840:30842] [TOO] Timestamp: 1722928835354 + [1722928919.332] [30840:30842] [TOO] LongRelease: { + [1722928919.332] [30840:30842] [TOO] PreviousPosition: 1 + [1722928919.332] [30840:30842] [TOO] } disabled: true - label: @@ -555,96 +609,51 @@ tests: On Raspi platform to trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have capability to generate this event) - change state from 0 to 1 + Change the Current Position from 0 to 1 echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: - [1659624126.646996][8590:8596] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1659624126.647380][8590:8590] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4be58f55 - [1659624126.647438][8590:8590] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1659624126.647480][8590:8590] CHIP:ZCL: SwitchServer: OnInitialPress + [1722929050.475] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722929050.476] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad36 + [1722929050.476] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722929050.476] [29970:29970] [ZCL] SwitchServer: OnInitialPress - wait 10 seconds, Read the CurrentPosition attribute + DUT Reads the CurrentPosition attribute ./chip-tool switch read current-position 1 1 - Verify CurrentPosition value is 1 On TH(all-cluster-app) log - - [1686294581.633942][30986:30986] CHIP:DMG: ReportDataMessage = - [1686294581.633954][30986:30986] CHIP:DMG: { - [1686294581.633961][30986:30986] CHIP:DMG: AttributeReportIBs = - [1686294581.633979][30986:30986] CHIP:DMG: [ - [1686294581.633987][30986:30986] CHIP:DMG: AttributeReportIB = - [1686294581.634004][30986:30986] CHIP:DMG: { - [1686294581.634014][30986:30986] CHIP:DMG: AttributeDataIB = - [1686294581.634025][30986:30986] CHIP:DMG: { - [1686294581.634038][30986:30986] CHIP:DMG: DataVersion = 0xbae40569, - [1686294581.634048][30986:30986] CHIP:DMG: AttributePathIB = - [1686294581.634059][30986:30986] CHIP:DMG: { - [1686294581.634071][30986:30986] CHIP:DMG: Endpoint = 0x1, - [1686294581.634083][30986:30986] CHIP:DMG: Cluster = 0x3b, - [1686294581.634095][30986:30986] CHIP:DMG: Attribute = 0x0000_0001, - [1686294581.634119][30986:30986] CHIP:DMG: } - [1686294581.634124][30986:30986] CHIP:DMG: - [1686294581.634127][30986:30986] CHIP:DMG: Data = 1, - [1686294581.634130][30986:30986] CHIP:DMG: }, - [1686294581.634134][30986:30986] CHIP:DMG: - [1686294581.634136][30986:30986] CHIP:DMG: }, - [1686294581.634141][30986:30986] CHIP:DMG: - [1686294581.634143][30986:30986] CHIP:DMG: ], - [1686294581.634147][30986:30986] CHIP:DMG: - [1686294581.634150][30986:30986] CHIP:DMG: SuppressResponse = true, - [1686294581.634152][30986:30986] CHIP:DMG: InteractionModelRevision = 1 - [1686294581.634154][30986:30986] CHIP:DMG: } + Verify CurrentPosition value is 1 On DUT(Chip-tool) log - After 0.2 seconds, send this command + [1722929078.688] [30886:30888] [DMG] } + [1722929078.688] [30886:30888] [TOO] Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 1761848630 + [1722929078.689] [30886:30888] [TOO] CurrentPosition: 1 - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + Wait 0.2 seconds, send this command - Verify ShortRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: + echo '{"Name":"InitialPress","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + + Verify InitialPress event with NewPosition set to 0 on TH(all-cluster-app) log: - [1659683678.805455][2530:2538] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1659683678.805739][2530:2530] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to ee5e7715 - [1659683678.805777][2530:2530] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1659683678.805858][2530:2530] CHIP:ZCL: SwitchServer: OnShortRelease + [1722929478.278] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":0}" + [1722929478.279] [29970:29970] [-] The new position when the momentary switch starts to be pressed:0 + [1722929478.279] [29970:29970] [ZCL] SwitchServer: OnInitialPress - wait 10 seconds, Read the CurrentPosition attribute + DUT Reads the CurrentPosition attribute ./chip-tool switch read current-position 1 1 - Verify CurrentPosition value is 0 On TH(all-cluster-app) log - - [1686294592.640335][30986:30986] CHIP:DMG: ReportDataMessage = - [1686294592.640348][30986:30986] CHIP:DMG: { - [1686294592.640360][30986:30986] CHIP:DMG: AttributeReportIBs = - [1686294592.640386][30986:30986] CHIP:DMG: [ - [1686294592.640397][30986:30986] CHIP:DMG: AttributeReportIB = - [1686294592.640425][30986:30986] CHIP:DMG: { - [1686294592.640440][30986:30986] CHIP:DMG: AttributeDataIB = - [1686294592.640456][30986:30986] CHIP:DMG: { - [1686294592.640474][30986:30986] CHIP:DMG: DataVersion = 0xbae4056a, - [1686294592.640490][30986:30986] CHIP:DMG: AttributePathIB = - [1686294592.640507][30986:30986] CHIP:DMG: { - [1686294592.640525][30986:30986] CHIP:DMG: Endpoint = 0x1, - [1686294592.640543][30986:30986] CHIP:DMG: Cluster = 0x3b, - [1686294592.640563][30986:30986] CHIP:DMG: Attribute = 0x0000_0001, - [1686294592.640580][30986:30986] CHIP:DMG: } - [1686294592.640602][30986:30986] CHIP:DMG: - [1686294592.640619][30986:30986] CHIP:DMG: Data = 0, - [1686294592.640633][30986:30986] CHIP:DMG: }, - [1686294592.640658][30986:30986] CHIP:DMG: - [1686294592.640668][30986:30986] CHIP:DMG: }, - [1686294592.640690][30986:30986] CHIP:DMG: - [1686294592.640702][30986:30986] CHIP:DMG: ], - [1686294592.640726][30986:30986] CHIP:DMG: - [1686294592.640739][30986:30986] CHIP:DMG: SuppressResponse = true, - [1686294592.640755][30986:30986] CHIP:DMG: InteractionModelRevision = 1 - [1686294592.640768][30986:30986] CHIP:DMG: } - - - Repeat above steps over 1 minute period of time + Verify CurrentPosition value is 0 On DUT(Chip-tool) log + + [1722929193.246] [30917:30919] [DMG] } + [1722929193.247] [30917:30919] [TOO] Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 1761848631 + [1722929193.247] [30917:30919] [TOO] CurrentPosition: 0 + + + Wait 10 seconds + + Repeat above steps over 1 minute period of time and DUT reads attribute CurrentPosition regularly. disabled: true - label: @@ -664,22 +673,32 @@ tests: Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: - [1659624126.646996][8590:8596] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1659624126.647380][8590:8590] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4be58f55 - [1659624126.647438][8590:8590] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1659624126.647480][8590:8590] CHIP:ZCL: SwitchServer: OnInitialPress + [1722929575.814] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722929575.815] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad38 + [1722929575.815] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722929575.815] [29970:29970] [ZCL] SwitchServer: OnInitialPress ./chip-tool switch read-event initial-press 1 1 Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 4 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 29687894 - [1659527630.476887][4774:4779] CHIP:TOO: InitialPress: { - [1659527630.476934][4774:4779] CHIP:TOO: NewPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + [1722929640.653] [31031:31033] [DMG] SuppressResponse = true, + [1722929640.653] [31031:31033] [DMG] InteractionModelRevision = 11 + [1722929640.653] [31031:31033] [DMG] } + [1722929640.655] [31031:31033] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722929640.655] [31031:31033] [TOO] Event number: 65553 + [1722929640.655] [31031:31033] [TOO] Priority: Info + [1722929640.655] [31031:31033] [TOO] Timestamp: 1722929478279 + [1722929640.655] [31031:31033] [TOO] InitialPress: { + [1722929640.655] [31031:31033] [TOO] NewPosition: 0 + [1722929640.655] [31031:31033] [TOO] } + [1722929640.655] [31031:31033] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722929640.655] [31031:31033] [TOO] Event number: 65554 + [1722929640.655] [31031:31033] [TOO] Priority: Info + [1722929640.655] [31031:31033] [TOO] Timestamp: 1722929575815 + [1722929640.655] [31031:31033] [TOO] InitialPress: { + [1722929640.656] [31031:31033] [TOO] NewPosition: 1 + [1722929640.656] [31031:31033] [TOO] } After 0.2 seconds, send this command @@ -687,23 +706,45 @@ tests: Verify ShortRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: - [1659684051.064329][2530:2538] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1659684051.064820][2530:2530] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to ee5e7716 - [1659684051.064904][2530:2530] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1659684051.064994][2530:2530] CHIP:ZCL: SwitchServer: OnShortRelease + [1722929693.191] [29970:29972] [-] Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" + [1722929693.192] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad39 + [1722929693.192] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released:1 + [1722929693.192] [29970:29970] [ZCL] SwitchServer: OnShortRelease + ./chip-tool switch read-event short-release 1 1 Verify ShortRelease event with PreviousPosition set to 1 on DUT(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 5 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 29688000 - [1659527630.476887][4774:4779] CHIP:TOO: ShortRelease: { - [1659527630.476934][4774:4779] CHIP:TOO: PreviousPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } - Repeat above steps over a 1 minute period of time + [1722929736.542] [31062:31064] [DMG] SuppressResponse = true, + [1722929736.542] [31062:31064] [DMG] InteractionModelRevision = 11 + [1722929736.542] [31062:31064] [DMG] } + [1722929736.542] [31062:31064] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722929736.542] [31062:31064] [TOO] Event number: 65546 + [1722929736.542] [31062:31064] [TOO] Priority: Info + [1722929736.542] [31062:31064] [TOO] Timestamp: 1722928571191 + [1722929736.543] [31062:31064] [TOO] ShortRelease: { + [1722929736.543] [31062:31064] [TOO] PreviousPosition: 0 + [1722929736.543] [31062:31064] [TOO] } + [1722929736.543] [31062:31064] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722929736.543] [31062:31064] [TOO] Event number: 65552 + [1722929736.543] [31062:31064] [TOO] Priority: Info + [1722929736.543] [31062:31064] [TOO] Timestamp: 1722929159932 + [1722929736.543] [31062:31064] [TOO] ShortRelease: { + [1722929736.543] [31062:31064] [TOO] PreviousPosition: 1 + [1722929736.543] [31062:31064] [TOO] } + [1722929736.544] [31062:31064] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722929736.544] [31062:31064] [TOO] Event number: 65555 + [1722929736.544] [31062:31064] [TOO] Priority: Info + [1722929736.544] [31062:31064] [TOO] Timestamp: 1722929693192 + [1722929736.544] [31062:31064] [TOO] ShortRelease: { + [1722929736.544] [31062:31064] [TOO] PreviousPosition: 1 + [1722929736.544] [31062:31064] [TOO] } + + + Wait 10 Seconds + + Repeat above steps over a 1 minute period of time. disabled: true - label: @@ -724,68 +765,445 @@ tests: Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: - [1686295316.319181][30986:30989] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1686295316.319478][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae4056b - [1686295316.319509][30986:30986] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1686295316.319518][30986:30986] CHIP:ZCL: SwitchServer: OnInitialPress + [1722929829.295] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722929829.296] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad3a + [1722929829.296] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722929829.296] [29970:29970] [ZCL] SwitchServer: OnInitialPress ./chip-tool switch read-event initial-press 1 1 - Verify InitialPress event with NewPosition set to 1 on TH(chip-tool) log: - - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 4 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 29687000 - [1659527630.476887][4774:4779] CHIP:TOO: InitialPress: { - [1659527630.476934][4774:4779] CHIP:TOO: NewPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: - After 0.75 seconds, send this command + [1722929860.240] [31102:31104] [DMG] SuppressResponse = true, + [1722929860.240] [31102:31104] [DMG] InteractionModelRevision = 11 + [1722929860.240] [31102:31104] [DMG] } + [1722929860.242] [31102:31104] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722929860.242] [31102:31104] [TOO] Event number: 65553 + [1722929860.242] [31102:31104] [TOO] Priority: Info + [1722929860.242] [31102:31104] [TOO] Timestamp: 1722929478279 + [1722929860.242] [31102:31104] [TOO] InitialPress: { + [1722929860.242] [31102:31104] [TOO] NewPosition: 0 + [1722929860.242] [31102:31104] [TOO] } + [1722929860.243] [31102:31104] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722929860.243] [31102:31104] [TOO] Event number: 65554 + [1722929860.243] [31102:31104] [TOO] Priority: Info + [1722929860.243] [31102:31104] [TOO] Timestamp: 1722929575815 + [1722929860.243] [31102:31104] [TOO] InitialPress: { + [1722929860.243] [31102:31104] [TOO] NewPosition: 1 + [1722929860.243] [31102:31104] [TOO] } + [1722929860.243] [31102:31104] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722929860.243] [31102:31104] [TOO] Event number: 65557 + [1722929860.243] [31102:31104] [TOO] Priority: Info + [1722929860.243] [31102:31104] [TOO] Timestamp: 1722929829296 + [1722929860.243] [31102:31104] [TOO] InitialPress: { + [1722929860.243] [31102:31104] [TOO] NewPosition: 1 + [1722929860.243] [31102:31104] [TOO] } + + After 0.75 seconds, send below command echo '{"Name":"LongPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) Verify LongPress event with NewPosition set to 1 on TH(all-cluster-app) log: + [1722929918.639] [29970:29972] [-] Received payload: "{"Name":"LongPress","NewPosition":1}" + [1722929918.640] [29970:29970] [-] The new position when the momentary switch has been pressed for a long time:1 + [1722929918.640] [29970:29970] [ZCL] SwitchServer: OnLongPress + + + ./chip-tool switch read-event long-press 1 1 + + Verify LongPress event with NewPosition set to 1 on DUT(chip-tool) log: + + [1722929958.750] [31129:31132] [DMG] SuppressResponse = true, + [1722929958.750] [31129:31132] [DMG] InteractionModelRevision = 11 + [1722929958.750] [31129:31132] [DMG] } + [1722929958.751] [31129:31132] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0002 + [1722929958.751] [31129:31132] [TOO] Event number: 65547 + [1722929958.751] [31129:31132] [TOO] Priority: Info + [1722929958.751] [31129:31132] [TOO] Timestamp: 1722928724337 + [1722929958.751] [31129:31132] [TOO] LongPress: { + [1722929958.751] [31129:31132] [TOO] NewPosition: 1 + [1722929958.751] [31129:31132] [TOO] } + [1722929958.751] [31129:31132] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0002 + [1722929958.752] [31129:31132] [TOO] Event number: 65558 + [1722929958.752] [31129:31132] [TOO] Priority: Info + [1722929958.752] [31129:31132] [TOO] Timestamp: 1722929918640 + [1722929958.752] [31129:31132] [TOO] LongPress: { + [1722929958.752] [31129:31132] [TOO] NewPosition: 1 + [1722929958.752] [31129:31132] [TOO] } + + After 2 seconds, send below command + + echo '{"Name":"LongRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + + Verify LonglRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: + + [1722930012.664] [29970:29972] [-] Received payload: "{"Name":"LongRelease","PreviousPosition":1}" + [1722930012.664] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad3b + [1722930012.664] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released after having been pressed for a long time:1 + [1722930012.664] [29970:29970] [ZCL] SwitchServer: OnLongRelease + + + ./chip-tool switch read-event long-release 1 1 + + Verify LonglRelease event with PreviousPosition set to 1 on DUT(chip-tool) log: + + [1722930054.350] [31160:31162] [DMG] SuppressResponse = true, + [1722930054.351] [31160:31162] [DMG] InteractionModelRevision = 11 + [1722930054.351] [31160:31162] [DMG] } + [1722930054.351] [31160:31162] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0004 + [1722930054.351] [31160:31162] [TOO] Event number: 65550 + [1722930054.351] [31160:31162] [TOO] Priority: Info + [1722930054.351] [31160:31162] [TOO] Timestamp: 1722928835354 + [1722930054.352] [31160:31162] [TOO] LongRelease: { + [1722930054.352] [31160:31162] [TOO] PreviousPosition: 1 + [1722930054.352] [31160:31162] [TOO] } + [1722930054.352] [31160:31162] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0004 + [1722930054.352] [31160:31162] [TOO] Event number: 65561 + [1722930054.352] [31160:31162] [TOO] Priority: Info + [1722930054.352] [31160:31162] [TOO] Timestamp: 1722930012664 + [1722930054.352] [31160:31162] [TOO] LongRelease: { + [1722930054.352] [31160:31162] [TOO] PreviousPosition: 1 + [1722930054.352] [31160:31162] [TOO] } + + + Wait 8 seconds + + Repeat above steps Over a 1 minute period of time + disabled: true + + - label: + "Step 4d: TH simulates operation of the switch by repeating these + steps (over a 1 minute period) change state (field CurrentPosition) + from 0 to 1, and send the event InitialPress (with field + NewPosition=1) wait 0.2 seconds change state (attribute + CurrentPosition) from 1 to 0, and send the event ShortRelease (with + field PreviousPosition=1) wait 0.2 seconds change state (field + CurrentPosition) from 0 to 1, and send the event InitialPress (with + field NewPosition=1) and event MultiPressOngoing(with field + NewPosition=1 and CurrentNumberOfPressesCounted=2) wait 0.2 seconds + change state (field CurrentPosition) from 1 to 0, and send the event + ShortRelease (with field PreviousPosition=1) wait 2 seconds send the + event MultiPressComplete (with field PreviousPosition=1 and + TotalNumberOfPressesCounted=2)" + PICS: + " SWTCH.C.F01 && SWTCH.C.F04 && !SWTCH.C.F05 && + SWTCH.C.M.SwitchStateEventing " + verification: | + On Raspi platform to trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have capability to generate this event) + + echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + + Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: + [1686295316.319181][30986:30989] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" [1686295316.319478][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae4056b [1686295316.319509][30986:30986] CHIP:-: The new position when the momentary switch starts to be pressed:1 [1686295316.319518][30986:30986] CHIP:ZCL: SwitchServer: OnInitialPress - ./chip-tool switch read-event long-press 1 1 + ./chip-tool switch read-event initial-press 1 1 - Verify LongPress event with NewPosition set to 1 on TH(chip-tool) log: + Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 5 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 29687750 - [1659527630.476887][4774:4779] CHIP:TOO: LongPress: { - [1659527630.476934][4774:4779] CHIP:TOO: NewPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + [1722930199.094] [31214:31216] [DMG] SuppressResponse = true, + [1722930199.094] [31214:31216] [DMG] InteractionModelRevision = 11 + [1722930199.094] [31214:31216] [DMG] } + [1722930199.098] [31214:31216] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722930199.098] [31214:31216] [TOO] Event number: 65562 + [1722930199.098] [31214:31216] [TOO] Priority: Info + [1722930199.098] [31214:31216] [TOO] Timestamp: 1722930190865 + [1722930199.098] [31214:31216] [TOO] InitialPress: { + [1722930199.098] [31214:31216] [TOO] NewPosition: 1 + [1722930199.098] [31214:31216] [TOO] } - After 2 seconds, send this command - echo '{"Name":"LongRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + wait 0.2 seconds - Verify LonglRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: + echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ - [1686295393.569670][30986:30989] CHIP:-: Received payload: "{"Name":"LongRelease","PreviousPosition":1}" - [1686295393.569925][30986:30986] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to bae4056d - [1686295393.569959][30986:30986] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released after having been pressed for a long time:1 - [1686295393.569976][30986:30986] CHIP:ZCL: SwitchServer: OnLongRelease + Verify ShortRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: - ./chip-tool switch read-event long-release 1 1 + [1722930266.048] [29970:29972] [-] Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" + [1722930266.049] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad3d + [1722930266.049] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released:1 + [1722930266.049] [29970:29970] [ZCL] SwitchServer: OnShortRelease - Verify LonglRelease event with PreviousPosition set to 1 on TH(chip-tool) log: - [1659527630.476706][4774:4779] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1659527630.476742][4774:4779] CHIP:TOO: Event number: 6 - [1659527630.476771][4774:4779] CHIP:TOO: Priority: Info - [1659527630.476799][4774:4779] CHIP:TOO: Timestamp: 296889750 - [1659527630.476887][4774:4779] CHIP:TOO: LongRelease: { - [1659527630.476934][4774:4779] CHIP:TOO: PreviousPosition: 1 - [1659527630.476969][4774:4779] CHIP:TOO: } + ./chip-tool switch read-event short-release 1 1 - Repeat above steps Over a 1 minute period of time + Verify ShortRelease event with PreviousPosition set to 1 on DUT(Chip-tool) log: + + [1722930314.978] [31255:31258] [DMG] SuppressResponse = true, + [1722930314.978] [31255:31258] [DMG] InteractionModelRevision = 11 + [1722930314.978] [31255:31258] [DMG] } + [1722930314.982] [31255:31258] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722930314.982] [31255:31258] [TOO] Event number: 65563 + [1722930314.982] [31255:31258] [TOO] Priority: Info + [1722930314.982] [31255:31258] [TOO] Timestamp: 1722930266049 + [1722930314.982] [31255:31258] [TOO] ShortRelease: { + [1722930314.983] [31255:31258] [TOO] PreviousPosition: 1 + [1722930314.983] [31255:31258] [TOO] } + + + wait 0.2 seconds + + echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) + + Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: + + [1722930385.505] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722930385.505] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad3e + [1722930385.505] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722930385.505] [29970:29970] [ZCL] SwitchServer: OnInitialPress + + ./chip-tool switch read-event initial-press 1 1 + + Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: + + [1722930430.195] [31290:31292] [DMG] SuppressResponse = true, + [1722930430.195] [31290:31292] [DMG] InteractionModelRevision = 11 + [1722930430.195] [31290:31292] [DMG] } + [1722930430.200] [31290:31292] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722930430.200] [31290:31292] [TOO] Event number: 65564 + [1722930430.200] [31290:31292] [TOO] Priority: Info + [1722930430.200] [31290:31292] [TOO] Timestamp: 1722930385505 + [1722930430.200] [31290:31292] [TOO] InitialPress: { + [1722930430.200] [31290:31292] [TOO] NewPosition: 1 + [1722930430.200] [31290:31292] [TOO] } + + + echo '{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ + + Verify MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted is 2 on TH(all-cluster-app) log: + + [1722930734.450] [29970:29972] [-] Received payload: "{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}" + [1722930734.450] [29970:29970] [-] The new position when the momentary switch has been pressed in a multi-press sequence:1 + [1722930734.451] [29970:29970] [-] 2 times the momentary switch has been pressed + [1722930734.451] [29970:29970] [ZCL] SwitchServer: OnMultiPressOngoing + + + ./chip-tool switch read-event multi-press-ongoing 1 1 + + Verify MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted is 2 on DUT(Chip-tool) log: + + [1722930652.716] [31360:31362] [DMG] SuppressResponse = true, + [1722930652.716] [31360:31362] [DMG] InteractionModelRevision = 11 + [1722930652.716] [31360:31362] [DMG] } + [1722930652.717] [31360:31362] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0005 + [1722930652.717] [31360:31362] [TOO] Event number: 65565 + [1722930652.717] [31360:31362] [TOO] Priority: Info + [1722930652.717] [31360:31362] [TOO] Timestamp: 1722930534106 + [1722930652.717] [31360:31362] [TOO] MultiPressOngoing: { + [1722930652.717] [31360:31362] [TOO] NewPosition: 1 + [1722930652.717] [31360:31362] [TOO] CurrentNumberOfPressesCounted: 2 + [1722930652.717] [31360:31362] [TOO] } + + + wait 0.2 seconds + + echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ + + Verify ShortRelease event with PreviousPosition set to 1 on TH(all-cluster-app) log: + + [1722930799.722] [29970:29972] [-] Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" + [1722930799.723] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad3f + [1722930799.723] [29970:29970] [-] The the previous value of the CurrentPosition when the momentary switch has been released:1 + [1722930799.723] [29970:29970] [ZCL] SwitchServer: OnShortRelease + + + ./chip-tool switch read-event short-release 1 1 + + Verify ShortRelease event with PreviousPosition set to 1 on DUT(chip-tool) log: + + [1722930819.997] [31413:31415] [DMG] SuppressResponse = true, + [1722930819.997] [31413:31415] [DMG] InteractionModelRevision = 11 + [1722930820.000] [31413:31415] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1722930820.000] [31413:31415] [TOO] Event number: 65567 + [1722930820.000] [31413:31415] [TOO] Priority: Info + [1722930820.000] [31413:31415] [TOO] Timestamp: 1722930799723 + [1722930820.001] [31413:31415] [TOO] ShortRelease: { + [1722930820.001] [31413:31415] [TOO] PreviousPosition: 1 + [1722930820.001] [31413:31415] [TOO] } + + + wait 2 seconds + + echo '{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ + + Verify MultiPressComplete event with PreviousPosition set to 1 AND TotalNumberOfPressesCounted is 2 on TH(all-cluster-app) log: + + [1722930879.026] [29970:29972] [-] Received payload: "{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}" + [1722930879.027] [29970:29970] [-] The previous position when the momentary switch has been pressed in a multi-press sequence:1 + [1722930879.027] [29970:29970] [-] 2 times the momentary switch has been pressed + [1722930879.027] [29970:29970] [ZCL] SwitchServer: OnMultiPressComplete + + + ./chip-tool switch read-event multi-press-complete 1 1 + + Verify MultiPressComplete event with PreviousPosition set to 1 AND TotalNumberOfPressesCounted is 2 on DUT(Chip-tool) log: + + [1722930909.990] [31442:31444] [DMG] SuppressResponse = true, + [1722930909.990] [31442:31444] [DMG] InteractionModelRevision = 11 + [1722930909.990] [31442:31444] [DMG] } + [1722930909.991] [31442:31444] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0006 + [1722930909.991] [31442:31444] [TOO] Event number: 65568 + [1722930909.991] [31442:31444] [TOO] Priority: Info + [1722930909.991] [31442:31444] [TOO] Timestamp: 1722930879027 + [1722930909.991] [31442:31444] [TOO] MultiPressComplete: { + [1722930909.991] [31442:31444] [TOO] PreviousPosition: 1 + [1722930909.992] [31442:31444] [TOO] TotalNumberOfPressesCounted: 2 + [1722930909.992] [31442:31444] [TOO] } + disabled: true + + - label: + "Step 4f: TH simulates operation of the switch by repeating these + steps (over a 1 minute period) change state (field CurrentPosition) + from 0 to 1, and send the event InitialPress (with field + NewPosition=1) wait 0.2 seconds change state (attribute + CurrentPosition) from 1 to 0 wait 0.2 seconds change state (field + CurrentPosition) from 0 to 1 wait 0.2 seconds change state (field + CurrentPosition) from 1 to 0 wait 2 seconds send the event + MultiPressComplete (with field PreviousPosition=1 and + TotalNumberOfPressesCounted=2)" + PICS: + " SWTCH.C.F01 && SWTCH.C.F04 && SWTCH.C.F05 && + SWTCH.C.M.SwitchStateEventing " + verification: | + echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ + + Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: + + [1722931100.930] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722931100.931] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad40 + [1722931100.931] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722931100.931] [29970:29970] [ZCL] SwitchServer: OnInitialPress + + ./chip-tool switch read-event initial-press 1 1 + + Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: + + [1722931135.211] [31498:31500] [DMG] SuppressResponse = true, + [1722931135.211] [31498:31500] [DMG] InteractionModelRevision = 11 + [1722931135.211] [31498:31500] [DMG] } + [1722931135.215] [31498:31500] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722931135.216] [31498:31500] [TOO] Event number: 65569 + [1722931135.216] [31498:31500] [TOO] Priority: Info + [1722931135.216] [31498:31500] [TOO] Timestamp: 1722931100931 + [1722931135.216] [31498:31500] [TOO] InitialPress: { + [1722931135.216] [31498:31500] [TOO] NewPosition: 1 + [1722931135.216] [31498:31500] [TOO] } + + wait 0.2 seconds + + echo '{"Name":"InitialPress","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ + + Verify InitialPress event with NewPosition set to 0 on TH(all-cluster-app) log: + + [1722931220.012] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":0}" + [1722931220.013] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad41 + [1722931220.013] [29970:29970] [-] The new position when the momentary switch starts to be pressed:0 + [1722931220.013] [29970:29970] [ZCL] SwitchServer: OnInitialPress + + ./chip-tool switch read-event initial-press 1 1 + + Verify InitialPress event with NewPosition set to 0 on DUT(chip-tool) log: + + [1722931271.359] [31540:31542] [DMG] SuppressResponse = true, + [1722931271.359] [31540:31542] [DMG] InteractionModelRevision = 11 + [1722931271.364] [31540:31542] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722931271.364] [31540:31542] [TOO] Event number: 65570 + [1722931271.364] [31540:31542] [TOO] Priority: Info + [1722931271.364] [31540:31542] [TOO] Timestamp: 1722931220013 + [1722931271.364] [31540:31542] [TOO] InitialPress: { + [1722931271.364] [31540:31542] [TOO] NewPosition: 0 + [1722931271.365] [31540:31542] [TOO] } + + wait 0.2 seconds + + echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ + + Verify InitialPress event with NewPosition set to 1 on TH(all-cluster-app) log: + + [1722931350.252] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":1}" + [1722931350.253] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad42 + [1722931350.253] [29970:29970] [-] The new position when the momentary switch starts to be pressed:1 + [1722931350.253] [29970:29970] [ZCL] SwitchServer: OnInitialPress + + ./chip-tool switch read-event initial-press 1 1 + + Verify InitialPress event with NewPosition set to 1 on DUT(chip-tool) log: + + [1722931407.399] [31584:31586] [DMG] SuppressResponse = true, + [1722931407.399] [31584:31586] [DMG] InteractionModelRevision = 11 + [1722931407.399] [31584:31586] [DMG] } + [1722931407.406] [31584:31586] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722931407.406] [31584:31586] [TOO] Event number: 65571 + [1722931407.406] [31584:31586] [TOO] Priority: Info + [1722931407.406] [31584:31586] [TOO] Timestamp: 1722931350253 + [1722931407.407] [31584:31586] [TOO] InitialPress: { + [1722931407.407] [31584:31586] [TOO] NewPosition: 1 + [1722931407.407] [31584:31586] [TOO] } + + + wait 0.2 seconds + + echo '{"Name":"InitialPress","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ + + Verify InitialPress event with NewPosition set to 0 on TH(all-cluster-app) log: + + [1722931466.389] [29970:29972] [-] Received payload: "{"Name":"InitialPress","NewPosition":0}" + [1722931466.390] [29970:29970] [DMG] Endpoint 1, Cluster 0x0000_003B update version to 6903ad43 + [1722931466.390] [29970:29970] [-] The new position when the momentary switch starts to be pressed:0 + [1722931466.390] [29970:29970] [ZCL] SwitchServer: OnInitialPress + + + ./chip-tool switch read-event initial-press 1 1 + + Verify InitialPress event with NewPosition set to 0 on DUT(chip-tool) log: + + [1722931577.478] [31634:31636] [DMG] SuppressResponse = true, + [1722931577.478] [31634:31636] [DMG] InteractionModelRevision = 11 + [1722931577.478] [31634:31636] [DMG] } + [1722931577.486] [31634:31636] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 + [1722931577.486] [31634:31636] [TOO] Event number: 65572 + [1722931577.486] [31634:31636] [TOO] Priority: Info + [1722931577.486] [31634:31636] [TOO] Timestamp: 1722931466390 + [1722931577.486] [31634:31636] [TOO] InitialPress: { + [1722931577.486] [31634:31636] [TOO] NewPosition: 0 + [1722931577.486] [31634:31636] [TOO] } + + wait 2 seconds + + echo '{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ + + Verify MultiPressComplete event with PreviousPosition set to 1 AND TotalNumberOfPressesCounted is 2 on TH(all-cluster-app) log: + + [1722931627.894] [29970:29972] [-] Received payload: "{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}" + [1722931627.894] [29970:29970] [-] The previous position when the momentary switch has been pressed in a multi-press sequence:1 + [1722931627.894] [29970:29970] [-] 2 times the momentary switch has been pressed + [1722931627.894] [29970:29970] [ZCL] SwitchServer: OnMultiPressComplete + + ./chip-tool switch read-event multi-press-complete 1 1 + + Verify MultiPressComplete event with PreviousPosition set to 1 AND TotalNumberOfPressesCounted is 2 on DUT(Chip-tool) log: + + [1722931657.607] [31658:31660] [DMG] SuppressResponse = true, + [1722931657.607] [31658:31660] [DMG] InteractionModelRevision = 11 + [1722931657.607] [31658:31660] [DMG] } + [1722931657.608] [31658:31660] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0006 + [1722931657.608] [31658:31660] [TOO] Event number: 65568 + [1722931657.608] [31658:31660] [TOO] Priority: Info + [1722931657.608] [31658:31660] [TOO] Timestamp: 1722930879027 + [1722931657.608] [31658:31660] [TOO] MultiPressComplete: { + [1722931657.608] [31658:31660] [TOO] PreviousPosition: 1 + [1722931657.608] [31658:31660] [TOO] TotalNumberOfPressesCounted: 2 + [1722931657.608] [31658:31660] [TOO] } + [1722931657.609] [31658:31660] [TOO] Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0006 + [1722931657.609] [31658:31660] [TOO] Event number: 65573 + [1722931657.609] [31658:31660] [TOO] Priority: Info + [1722931657.609] [31658:31660] [TOO] Timestamp: 1722931627894 + [1722931657.609] [31658:31660] [TOO] MultiPressComplete: { + [1722931657.609] [31658:31660] [TOO] PreviousPosition: 1 + [1722931657.609] [31658:31660] [TOO] TotalNumberOfPressesCounted: 2 + [1722931657.609] [31658:31660] [TOO] } disabled: true diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index d976d7623244fd..4e054643456b03 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -112,7 +112,6 @@ "Test_TC_OTCCM_3_3" ], "LaundryDryerControl": ["Test_TC_DRYERCTRL_2_1"], - "MediaControl": [ "Test_TC_LOWPOWER_2_1", "Test_TC_KEYPADINPUT_3_2", @@ -149,6 +148,7 @@ "Test_TC_OO_2_1", "Test_TC_OO_2_2", "Test_TC_OO_2_4", + "Test_TC_OO_2_6", "Test_TC_OO_2_7" ], "PowerSource": ["Test_TC_PS_2_1"], From e18f910034b56e62c49c06af8e71aeddc860a423 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 4 Sep 2024 16:44:26 -0400 Subject: [PATCH 55/70] Stop hardcoding the list of signed integer attribute types. (#35412) ZAP has this information. We should just use that instead of duplicating it. Fixes https://github.com/project-chip/connectedhomeip/issues/35147 --- src/app/util/attribute-metadata.h | 6 +-- .../templates/app/attribute-type.zapt | 20 +++++++++ .../app-common/zap-generated/attribute-type.h | 41 +++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/app/util/attribute-metadata.h b/src/app/util/attribute-metadata.h index 1a2b2fd04ed447..5be6916438d48a 100644 --- a/src/app/util/attribute-metadata.h +++ b/src/app/util/attribute-metadata.h @@ -166,11 +166,7 @@ struct EmberAfAttributeMetadata /** * Check wether this attribute is signed based on its type according to the spec. */ - bool IsSignedIntegerAttribute() const - { - return (attributeType >= ZCL_INT8S_ATTRIBUTE_TYPE && attributeType <= ZCL_INT64S_ATTRIBUTE_TYPE) || - attributeType == ZCL_TEMPERATURE_ATTRIBUTE_TYPE; - } + bool IsSignedIntegerAttribute() const { return chip::app::IsSignedAttributeType(attributeType); } /** * Check whether this attribute has a define min and max. diff --git a/src/app/zap-templates/templates/app/attribute-type.zapt b/src/app/zap-templates/templates/app/attribute-type.zapt index bc0e3fb7d2bee2..233cf0a1e46b2a 100644 --- a/src/app/zap-templates/templates/app/attribute-type.zapt +++ b/src/app/zap-templates/templates/app/attribute-type.zapt @@ -3,9 +3,29 @@ // Prevent multiple inclusion #pragma once +#include + // ZCL attribute types enum { {{#zcl_atomics}} {{ident}}ZCL_{{asDelimitedMacro name}}_ATTRIBUTE_TYPE = {{asHex atomicId 2}}, // {{description}} {{/zcl_atomics}} }; + +namespace chip { +namespace app { +inline bool IsSignedAttributeType(uint8_t attributeType) +{ + switch (attributeType) { + {{#zcl_atomics}} + {{#if isSigned}} + case ZCL_{{asDelimitedMacro name}}_ATTRIBUTE_TYPE: + return true; + {{/if}} + {{/zcl_atomics}} + default: + return false; + } +} +} // namespace app +} // namespace chip diff --git a/zzz_generated/app-common/app-common/zap-generated/attribute-type.h b/zzz_generated/app-common/app-common/zap-generated/attribute-type.h index 6f4c3bc90208e2..ae493673fc03f2 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attribute-type.h +++ b/zzz_generated/app-common/app-common/zap-generated/attribute-type.h @@ -20,6 +20,8 @@ // Prevent multiple inclusion #pragma once +#include + // ZCL attribute types enum { @@ -99,3 +101,42 @@ enum ZCL_HWADR_ATTRIBUTE_TYPE = 0xF6, // Hardware Address ZCL_UNKNOWN_ATTRIBUTE_TYPE = 0xFF, // Unknown }; + +namespace chip { +namespace app { +inline bool IsSignedAttributeType(uint8_t attributeType) +{ + switch (attributeType) + { + case ZCL_INT8S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT16S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT24S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT32S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT40S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT48S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT56S_ATTRIBUTE_TYPE: + return true; + case ZCL_INT64S_ATTRIBUTE_TYPE: + return true; + case ZCL_TEMPERATURE_ATTRIBUTE_TYPE: + return true; + case ZCL_POWER_MW_ATTRIBUTE_TYPE: + return true; + case ZCL_AMPERAGE_MA_ATTRIBUTE_TYPE: + return true; + case ZCL_VOLTAGE_MV_ATTRIBUTE_TYPE: + return true; + case ZCL_ENERGY_MWH_ATTRIBUTE_TYPE: + return true; + default: + return false; + } +} +} // namespace app +} // namespace chip From 48df767bcbad2789fe7cd413904f9ce66e751a20 Mon Sep 17 00:00:00 2001 From: Saravana Perumal K <104007654+Saravana-kr22@users.noreply.github.com> Date: Thu, 5 Sep 2024 02:16:17 +0530 Subject: [PATCH 56/70] Updated yaml script as per the Issues raised by SQA (#35193) * Updated yaml script as per the Issues raised by SQA * Restyled by whitespace * Updated the default value of unsupportedNumberOfRinsesValue * Update src/app/tests/suites/certification/Test_TC_DD_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DD_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DD_2_1.yaml Co-authored-by: Leo Rozendaal * Update src/app/tests/suites/certification/Test_TC_DD_2_1.yaml Co-authored-by: Leo Rozendaal * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io Co-authored-by: cjandhyala <68604034+cjandhyala@users.noreply.github.com> Co-authored-by: Justin Wood Co-authored-by: Leo Rozendaal --- .../suites/certification/Test_TC_DD_2_1.yaml | 120 +++++-- .../certification/Test_TC_DESC_2_1.yaml | 326 ++++++++++++------ .../certification/Test_TC_DISHM_1_2.yaml | 83 +++-- .../certification/Test_TC_EEVSEM_1_2.yaml | 106 +++--- .../certification/Test_TC_EEVSEM_2_1.yaml | 2 +- .../suites/certification/Test_TC_I_2_2.yaml | 94 ++--- .../suites/certification/Test_TC_I_3_2.yaml | 12 +- .../suites/certification/Test_TC_LWM_1_2.yaml | 1 - .../suites/certification/Test_TC_MOD_1_3.yaml | 30 ++ .../certification/Test_TC_WASHERCTRL_2_2.yaml | 19 +- 10 files changed, 469 insertions(+), 324 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DD_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DD_2_1.yaml index 94888631f6a143..e0f8386d742b97 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_2_1.yaml @@ -35,13 +35,14 @@ tests: disabled: true - label: - "Step 1: If TH is aware of the DUT's Discovery Capability Bitmask, it + "Step 1: If TH is aware of the DUT’s Discovery Capability Bitmask, it SHALL initiate Device Discovery in any order of priority on all the networking technologies that are supported by both the TH and the DUT - If TH is unaware of the DUT's Discovery Capability Bitmask, it SHALL + If TH is unaware of the DUT’s Discovery Capability Bitmask, it MAY initiate Device Discovery in any order on all the networking - technologies it supports out of Wi-Fi Soft-AP, BLE, and on IP network - discovery." + technologies it supports out of Wi-Fi Soft-AP, Wi-Fi PAF, BLE, and on + IP network discovery, or initiate Device Discovery on a specific + networking technology." verification: | TH selects the DUT's capability bitmask and start the commissiong process accordingly No applicable TH or DUT logs. @@ -137,8 +138,8 @@ tests: disabled: true - label: - "Step 7: TH does not respond to DUT and DUT keeps sending ADVs. TH - waits at least 15 minutes" + "Step 7a: TH waits until T0+ 2 minutes and 45 seconds and confirms + that the DUT is still sending ADVs." PICS: MCORE.COM.BLE verification: | No applicable TH logs. @@ -148,39 +149,94 @@ tests: OR HCIDump (https://ubuntu.com/core/docs/bluez/reference/commands) 2. After DUT has been advertising for 2min59sec (right before the minimum 3min mark), check that the DUT is still advertising over BLE - 3. After DUT has been advertising for 15min, check that the DUT has stopped advertising over BLE disabled: true - - label: "Step 8: TH scans and finds the DUT SSID" - PICS: MCORE.COM.WIFI + - label: + "Step 7b: TH waits until T0+ 15 minutes and checks if the DUT is + sending ADVs." + PICS: MCORE.COM.BLE verification: | - Out of Scope - SoftAP commissioning not currently supported on TH=chip-tool + No applicable TH logs. + + 1. Discover commissionables over BLE using a BLE discovery tool of choice. + Try NRF Connect app (https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop) + OR + HCIDump (https://ubuntu.com/core/docs/bluez/reference/commands) + 2. After DUT has been advertising for 15min(T0+ 15 minutes), check that the DUT has not stopped the advertising over BLE + + Instruction to verify using NRF Connect app: + >open nrfconnect app and scan for the device. + >once the deviceis listed double click on the device to view the ADV data + >Here you can see the advertisement range under the ADV. interval feild Check the advertisement range is grater than 1200ms + if the advertising rate is not 1285ms +/- 10ms, even though this is legal, since 1285ms is a SHOULD in the core specification. + >Click on the raw data option in theselected device, where you can get the 16-bit data + For example, "0xF6FF00050F0000000002" would translate to: + 0xF6, 0xFF= 0xFFF6 = 16-bit Matter UUID assigned by Bluetooth SIG + 0x00 = 0x00 (Commissionable) = Matter BLE OpCode + 0x01, 0x0F = 0x0F01 = 3841 Discriminator + 0x00, 0x00, = 0x0000 = 0 VendorID + 0x00, 0x00 = 0x0000 = 0 Product ID + 0x02 = Additional Data Flag(Extended Announcement) + here check discrimator and the "vendor-id"&"product-id" feild is set to 0 and Extended Data is set to 1 disabled: true - label: - "Step 9: TH scans and finds the DUT SSID TH sends to DUT a 1st power - cycle command (or reset manually) TH sends to DUT a 2nd power cycle - command (or reset manually)" - PICS: MCORE.COM.WIFI + "Step 8a: TH is configured to perform commissioning on Channel 6 in + 2.4GHz band." + PICS: MCORE.COM.WIFI && MCORE.DD.DISCOVERY_PAF + verification: | + [Configuration command to be filled by NXP] + + Configure the AP to the PAF working channel and connect TH to AP + disabled: true + + - label: + "Step 8b: TH is configured to perform commissioning on Channel 44 in + 5GHz band if it is in non-ETSI regulatory domains and on Channel 149 + in 5GHz band if it is in ETSI regulatory domains." + PICS: MCORE.COM.WIFI && !MCORE.COM.BLE && MCORE.DD.DISCOVERY_PAF + verification: | + [Configuration command to be filled by NXP] + + Configure the AP to the PAF working channel and connect TH to AP + disabled: true + + - label: "Step 9: DUT begins sending Wi-Fi PAF Publish messages." + PICS: MCORE.COM.WIFI && MCORE.DD.DISCOVERY_PAF + verification: | + [Verification command to be filled by NXP] + + * 2.4g: + $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=2437 + * 5g, FCC: + $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=5220 + * 5g ETSI: + $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=5745 + disabled: true + + - label: "Step 10: TH scans and finds the DUT SSID" + PICS: MCORE.COM.WIFI && MCORE.DD.DISCOVERY_SOFTAP verification: | Out of Scope SoftAP commissioning not currently supported on TH=chip-tool disabled: true - - label: "Step 10: TH scans and finds the DUT SSID" - PICS: MCORE.COM.WIFI && MCORE.DD.IE + - label: + "Step 11: TTH scans and finds the DUT SSID TH sends to DUT a 1st power + cycle command (or reset manually) TH sends to DUT a 2nd power cycle + command (or reset manually)" + PICS: MCORE.COM.WIFI && MCORE.DD.DISCOVERY_SOFTAP verification: | Out of Scope SoftAP commissioning not currently supported on TH=chip-tool disabled: true - label: - "Step 11: TH and DUT are connected to the same network through + "Step 12: TH and DUT are connected to the same network through vendor-unique means or by commissioning the DUT onto the Matter network and opening a commissioning window. The DUT is sending - mandatory Commissionable Node Discovery service records over - DNS-SD.|DUT is able to be discovered over DNS-SD." + mandatory Commissionable Node Discovery service records over DNS-SD." + PICS: MCORE.COM.WIFI && MCORE.DD.DISCOVERY_SOFTAP verification: | ./chip-all-clusters-app ... @@ -220,7 +276,7 @@ tests: disabled: true - label: - "Step 12a: TH and DUT are connected to the same network and the DUT is + "Step 13a: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_VP @@ -262,7 +318,7 @@ tests: disabled: true - label: - "Step 12b: TH and DUT are connected to the same network and the DUT is + "Step 13b: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_DT @@ -304,7 +360,7 @@ tests: disabled: true - label: - "Step 12c: TH and DUT are connected to the same network and the DUT is + "Step 13c: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_DN @@ -346,7 +402,7 @@ tests: disabled: true - label: - "Step 12d: TH and DUT are connected to the same network and the DUT is + "Step 13d: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_RI @@ -388,7 +444,7 @@ tests: disabled: true - label: - "Step 12e: TH and DUT are connected to the same network and the DUT is + "Step 13e: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_PH @@ -430,7 +486,7 @@ tests: disabled: true - label: - "Step 12f: TH and DUT are connected to the same network and the DUT is + "Step 13f: TH and DUT are connected to the same network and the DUT is sending optional Commissionable Node Discovery service records over DNS-SD." PICS: MCORE.DD.TXT_KEY_PI @@ -471,7 +527,7 @@ tests: txt = ["PI=10" "PH=33" "RI=AB" "CM=0" "D=840" "DN=Test Bulb" "DT=257" "VP=65521+32769"] disabled: true - - label: "Step 13: Place the DUT device into a non-commissionable state" + - label: "Step 14: Place the DUT device into a non-commissionable state" PICS: MCORE.DD.EXTENDED_DISCOVERY verification: | 1. Vendor specific, take DUT out of commissioning mode @@ -484,7 +540,7 @@ tests: disabled: true - label: - "Step 14a: TH and DUT are connected to the same network and the DUT is + "Step 15a: TH and DUT are connected to the same network and the DUT is sending a Commissionable Node Discovery service record over DNS-SD." verification: | ./chip-tool discover commissionables @@ -509,7 +565,7 @@ tests: disabled: true - label: - "Step 14b: Mandatory Commissioning Subtypes: Send a browse request for + "Step 15b: Mandatory Commissioning Subtypes: Send a browse request for '_services._dns-sd._udp' using a DNS-SD records command-line test tool (i.e. 'dns-sd -B _services._dns-sd._udp' or 'avahi-browse _services._dns-sd._udp -r')" @@ -524,7 +580,7 @@ tests: disabled: true - label: - "Step 14c: Optional Commissioning Subtypes: Send a browse request for + "Step 15c: Optional Commissioning Subtypes: Send a browse request for '_services._dns-sd._udp' using a DNS-SD records command-line test tool (i.e. 'dns-sd -B _services._dns-sd._udp' or 'avahi-browse _services._dns-sd._udp -r')" @@ -537,7 +593,7 @@ tests: 11:56:29.770 Add 3 7 . _sub.local. _V65521 disabled: true - - label: "Step 15a: Place the DUT device into Commissioning mode" + - label: "Step 16a: Place the DUT device into Commissioning mode" verification: | $ ./chip-tool discover commissionables Verify in TH as commissioner side: @@ -561,7 +617,7 @@ tests: disabled: true - label: - "Step 15b: Send a browse request for '_matterc._udp' using a DNS-SD + "Step 16b: Send a browse request for '_matterc._udp' using a DNS-SD records command-line test tool (i.e. 'dns-sd -B _matterc._udp' or 'avahi-browse _matterc._udp -r')" verification: | diff --git a/src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml index 2afe448fa99f30..cf47c3fc503a73 100644 --- a/src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DESC_2_1.yaml @@ -42,23 +42,29 @@ tests: PICS: DESC.S.A0000 && DESC.S.A0003 verification: | Send a read request to the DUT using chip-tool to read the partsList attribute in the descriptor cluster on Endpoint 0. - Make a note of all the items(Endpoint id’s) in the list. In the below example there are 2 endpoint id's listed [1,2] + Make a note of all the items(Endpoint id’s) in the list. In the below example there are 4 endpoint id's listed [1, 2, 3, 4] - ./chip-tool descriptor read parts-list 1 0 + ./chip-tool descriptor read parts-list 1 0 Verify "PartsList" attribute is not empty (use this list of endpoints in step 1b) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - [1672919206.069327][33426:33428] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 2847656117 - [1672919206.069380][33426:33428] CHIP:TOO: PartsList: 2 entries - [1672919206.069398][33426:33428] CHIP:TOO: [1]: 1 - [1672919206.069410][33426:33428] CHIP:TOO: [2]: 2 + [1724249918.931] [2996912:2996914] [TOO] Endpoint: 0 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 444270524 + [1724249918.931] [2996912:2996914] [TOO] PartsList: 4 entries + [1724249918.931] [2996912:2996914] [TOO] [1]: 1 + [1724249918.931] [2996912:2996914] [TOO] [2]: 2 + [1724249918.931] [2996912:2996914] [TOO] [3]: 3 + [1724249918.931] [2996912:2996914] [TOO] [4]: 4 + ./chip-tool descriptor read device-type-list 1 0 - on TH (Chip-tool) log, Verify that the DeviceTypeList contains one Root Node Device Type and may only contain other Node Device Types (device types with scope=node, it can be any of the following Power Source, OTA Requestor, OTA Provider) next to the Root Node Device Type. (here DeviceType: 17 is power source ) + on TH (Chip-tool) log, + - Verify that the DeviceTypeList count is at least one. + - Verify that the DeviceTypeList contains one Root Node Device Type and may only contain other Node Device Types (device types with scope=node, it can be any of the following Power Source, OTA Requestor, OTA Provider) next to the Root Node Device Type. (here DeviceType: 17 is power source ) + - Read each element from the DeviceTypeList and check for the following: + DeviceType should be one of the DeviceTypes listed in the PIXIT.DESC.DeviceTypeConformanceList. - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform - [1674552598.748946][21129:21131] CHIP:DMG: } [[1692617243.785786][31325:31327] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_001D Attribute 0x0000_0000 DataVersion: 1437984882 [1692617243.785840][31325:31327] CHIP:TOO: DeviceTypeList: 2 entries [1692617243.785862][31325:31327] CHIP:TOO: [1]: { @@ -89,9 +95,11 @@ tests: ./chip-tool descriptor read device-type-list 1 1 On TH (Chip-tool) log, Verify that the DeviceTypeList count is at least one. - - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. - - Verify the DeviceTypeList does not contain the Root Node Device Type. - - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform + - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. + - Verify the DeviceTypeList does not contain the Root Node Device Type. + - Read each element from the DeviceTypeList and check for the following: + DeviceType should match to the DeviceType listed in the PIXIT.DESC.DeviceTypeConformanceList. + - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform [1674552599.264189][21135:21137] CHIP:DMG: } [1692617790.900384][31584:31586] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_001D Attribute 0x0000_0000 DataVersion: 2832593371 @@ -115,9 +123,11 @@ tests: ./chip-tool descriptor read device-type-list 1 2 On TH (Chip-tool) log, Verify that the DeviceTypeList count is at least one. - - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. - - Verify the DeviceTypeList does not contain the Root Node Device Type. - - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform + - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. + - Verify the DeviceTypeList does not contain the Root Node Device Type. + - Read each element from the DeviceTypeList and check for the following: + DeviceType should match to the DeviceType listed in the PIXIT.DESC.DeviceTypeConformanceList. + - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform [1692618454.794870][31669:31671] CHIP:TOO: Endpoint: 2 Cluster: 0x0000_001D Attribute 0x0000_0000 DataVersion: 1103199808 [1692618454.794946][31669:31671] CHIP:TOO: DeviceTypeList: 2 entries @@ -129,6 +139,57 @@ tests: [1692618454.795072][31669:31671] CHIP:TOO: DeviceType: 17 [1692618454.795080][31669:31671] CHIP:TOO: Revision: 1 [1692618454.795089][31669:31671] CHIP:TOO: } + + + ./chip-tool descriptor read parts-list 1 3 + + Verify parts-list response contains 0 entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1724250097.366] [2998028:2998030] [DMG] } + [1724250097.367] [2998028:2998030] [TOO] Endpoint: 3 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 816387248 + [1724250097.367] [2998028:2998030] [TOO] PartsList: 0 entries + + ./chip-tool descriptor read device-type-list 1 3 + + On TH (Chip-tool) log, Verify that the DeviceTypeList count is at least one. + - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. + - Verify the DeviceTypeList does not contain the Root Node Device Type. + - Read each element from the DeviceTypeList and check for the following: + DeviceType should match to the DeviceType listed in the PIXIT.DESC.DeviceTypeConformanceList. + - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform + + [1724250131.542] [2998254:2998256] [DMG] } + [1724250131.542] [2998254:2998256] [TOO] Endpoint: 3 Cluster: 0x0000_001D Attribute 0x0000_0000 DataVersion: 816387248 + [1724250131.543] [2998254:2998256] [TOO] DeviceTypeList: 1 entries + [1724250131.543] [2998254:2998256] [TOO] [1]: { + [1724250131.543] [2998254:2998256] [TOO] DeviceType: 15 + [1724250131.543] [2998254:2998256] [TOO] Revision: 3 + [1724250131.543] [2998254:2998256] [TOO] } + + ./chip-tool descriptor read parts-list 1 4 + + Verify parts-list response contains 0 entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1724250163.361] [2998451:2998453] [DMG] } + [1724250163.361] [2998451:2998453] [TOO] Endpoint: 4 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 3394934309 + [1724250163.361] [2998451:2998453] [TOO] PartsList: 0 entries + + ./chip-tool descriptor read device-type-list 1 4 + + On TH (Chip-tool) log, Verify that the DeviceTypeList count is at least one. + - If the DeviceTypeList contains more than one Application Device Type, verify that all the Application Device Types are part of the same superset. + - Verify the DeviceTypeList does not contain the Root Node Device Type. + - Read each element from the DeviceTypeList and check for the following: + DeviceType should match to the DeviceType listed in the PIXIT.DESC.DeviceTypeConformanceList. + - Revision value is not less than 1 and it should match the Revision of the DeviceType and below is the sample log provided for the raspi platform + + [1724250191.099] [2998617:2998619] [DMG] } + [1724250191.099] [2998617:2998619] [TOO] Endpoint: 4 Cluster: 0x0000_001D Attribute 0x0000_0000 DataVersion: 3394934309 + [1724250191.099] [2998617:2998619] [TOO] DeviceTypeList: 1 entries + [1724250191.099] [2998617:2998619] [TOO] [1]: { + [1724250191.099] [2998617:2998619] [TOO] DeviceType: 15 + [1724250191.099] [2998617:2998619] [TOO] Revision: 3 + [1724250191.099] [2998617:2998619] [TOO] } disabled: true - label: "Step 2: TH reads 'ServerList' attribute." @@ -142,95 +203,121 @@ tests: Verify ServerList entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, - [1707996554.409850][20755:20757] [DMG] } - [1707996554.410814][20755:20757] [TOO] Endpoint: 1 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 3583190746 - [1707996554.410955][20755:20757] [TOO] ServerList: 71 entries - [1707996554.410990][20755:20757] [TOO] [1]: 3 (Identify) - [1707996554.411002][20755:20757] [TOO] [2]: 4 (Groups) - [1707996554.411013][20755:20757] [TOO] [3]: 6 (OnOff) - [1707996554.411024][20755:20757] [TOO] [4]: 7 (OnOffSwitchConfiguration) - [1707996554.411034][20755:20757] [TOO] [5]: 8 (LevelControl) - [1707996554.411045][20755:20757] [TOO] [6]: 15 (BinaryInputBasic) - [1707996554.411056][20755:20757] [TOO] [7]: 29 (Descriptor) - [1707996554.411067][20755:20757] [TOO] [8]: 30 (Binding) - [1707996554.411078][20755:20757] [TOO] [9]: 37 (Actions) - [1707996554.411092][20755:20757] [TOO] [10]: 47 (PowerSource) - [1707996554.411103][20755:20757] [TOO] [11]: 59 (Switch) - [1707996554.411113][20755:20757] [TOO] [12]: 64 (FixedLabel) - [1707996554.411124][20755:20757] [TOO] [13]: 65 (UserLabel) - [1707996554.411135][20755:20757] [TOO] [14]: 69 (BooleanState) - [1707996554.411146][20755:20757] [TOO] [15]: 72 (OvenCavityOperationalState) - [1707996554.411156][20755:20757] [TOO] [16]: 73 (OvenMode) - [1707996554.411167][20755:20757] [TOO] [17]: 74 (LaundryDryerControls) - [1707996554.411177][20755:20757] [TOO] [18]: 80 (ModeSelect) - [1707996554.411188][20755:20757] [TOO] [19]: 81 (LaundryWasherMode) - [1707996554.411199][20755:20757] [TOO] [20]: 82 (RefrigeratorAndTemperatureControlledCabinetMode) - [1707996554.411209][20755:20757] [TOO] [21]: 83 (LaundryWasherControls) - [1707996554.411220][20755:20757] [TOO] [22]: 84 (RvcRunMode) - [1707996554.411231][20755:20757] [TOO] [23]: 85 (RvcCleanMode) - [1707996554.411240][20755:20757] [TOO] [24]: 86 (TemperatureControl) - [1707996554.411251][20755:20757] [TOO] [25]: 87 (RefrigeratorAlarm) - [1707996554.411261][20755:20757] [TOO] [26]: 89 (DishwasherMode) - [1707996554.411271][20755:20757] [TOO] [27]: 91 (AirQuality) - [1707996554.411282][20755:20757] [TOO] [28]: 92 (SmokeCoAlarm) - [1707996554.411293][20755:20757] [TOO] [29]: 93 (DishwasherAlarm) - [1707996554.411303][20755:20757] [TOO] [30]: 94 (MicrowaveOvenMode) - [1707996554.411313][20755:20757] [TOO] [31]: 96 (OperationalState) - [1707996554.411323][20755:20757] [TOO] [32]: 97 (RvcOperationalState) - [1707996554.411334][20755:20757] [TOO] [33]: 98 (ScenesManagement) - [1707996554.411345][20755:20757] [TOO] [34]: 113 (HepaFilterMonitoring) - [1707996554.411355][20755:20757] [TOO] [35]: 114 (ActivatedCarbonFilterMonitoring) - [1707996554.411367][20755:20757] [TOO] [36]: 128 (BooleanStateConfiguration) - [1707996554.411376][20755:20757] [TOO] [37]: 129 (ValveConfigurationAndControl) - [1707996554.411387][20755:20757] [TOO] [38]: 144 (ElectricalPowerMeasurement) - [1707996554.411396][20755:20757] [TOO] [39]: 145 (ElectricalEnergyMeasurement) - [1707996554.411406][20755:20757] [TOO] [40]: 152 (DeviceEnergyManagement) - [1707996554.411417][20755:20757] [TOO] [41]: 153 (EnergyEvse) - [1707996554.411427][20755:20757] [TOO] [42]: 157 (EnergyEvseMode) - [1707996554.411437][20755:20757] [TOO] [43]: 159 (DeviceEnergyManagementMode) - [1707996554.411449][20755:20757] [TOO] [44]: 258 (WindowCovering) - [1707996554.411459][20755:20757] [TOO] [45]: 259 (BarrierControl) - [1707996554.411469][20755:20757] [TOO] [46]: 512 (PumpConfigurationAndControl) - [1707996554.411480][20755:20757] [TOO] [47]: 513 (Thermostat) - [1707996554.411490][20755:20757] [TOO] [48]: 514 (FanControl) - [1707996554.411500][20755:20757] [TOO] [49]: 516 (ThermostatUserInterfaceConfiguration) - [1707996554.411511][20755:20757] [TOO] [50]: 768 (ColorControl) - [1707996554.411521][20755:20757] [TOO] [51]: 769 (BallastConfiguration) - [1707996554.411532][20755:20757] [TOO] [52]: 1024 (IlluminanceMeasurement) - [1707996554.411559][20755:20757] [TOO] [53]: 1026 (TemperatureMeasurement) - [1707996554.411562][20755:20757] [TOO] [54]: 1027 (PressureMeasurement) - [1707996554.411565][20755:20757] [TOO] [55]: 1028 (FlowMeasurement) - [1707996554.411568][20755:20757] [TOO] [56]: 1029 (RelativeHumidityMeasurement) - [1707996554.411571][20755:20757] [TOO] [57]: 1030 (OccupancySensing) - [1707996554.411575][20755:20757] [TOO] [58]: 1036 (CarbonMonoxideConcentrationMeasurement) - [1707996554.411578][20755:20757] [TOO] [59]: 1037 (CarbonDioxideConcentrationMeasurement) - [1707996554.411581][20755:20757] [TOO] [60]: 1043 (NitrogenDioxideConcentrationMeasurement) - [1707996554.411584][20755:20757] [TOO] [61]: 1045 (OzoneConcentrationMeasurement) - [1707996554.411587][20755:20757] [TOO] [62]: 1066 (Pm25ConcentrationMeasurement) - [1707996554.411589][20755:20757] [TOO] [63]: 1067 (FormaldehydeConcentrationMeasurement) - [1707996554.411592][20755:20757] [TOO] [64]: 1068 (Pm1ConcentrationMeasurement) - [1707996554.411595][20755:20757] [TOO] [65]: 1069 (Pm10ConcentrationMeasurement) - [1707996554.411598][20755:20757] [TOO] [66]: 1070 (TotalVolatileOrganicCompoundsConcentrationMeasurement) - [1707996554.411601][20755:20757] [TOO] [67]: 1071 (RadonConcentrationMeasurement) - [1707996554.411604][20755:20757] [TOO] [68]: 1283 (WakeOnLan) - [1707996554.411607][20755:20757] [TOO] [69]: 1288 (LowPower) - [1707996554.411610][20755:20757] [TOO] [70]: 2820 (ElectricalMeasurement) - [1707996554.411613][20755:20757] [TOO] [71]: 4294048773 (UnitTesting) + 1724250318.422] [2999432:2999434] [TOO] Endpoint: 1 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 753901911 + [1724250318.422] [2999432:2999434] [TOO] ServerList: 75 entries + [1724250318.422] [2999432:2999434] [TOO] [1]: 3 + [1724250318.422] [2999432:2999434] [TOO] [2]: 4 + [1724250318.422] [2999432:2999434] [TOO] [3]: 6 + [1724250318.422] [2999432:2999434] [TOO] [4]: 7 + [1724250318.422] [2999432:2999434] [TOO] [5]: 8 + [1724250318.422] [2999432:2999434] [TOO] [6]: 15 + [1724250318.422] [2999432:2999434] [TOO] [7]: 29 + [1724250318.422] [2999432:2999434] [TOO] [8]: 30 + [1724250318.422] [2999432:2999434] [TOO] [9]: 37 + [1724250318.422] [2999432:2999434] [TOO] [10]: 47 + [1724250318.423] [2999432:2999434] [TOO] [11]: 59 + [1724250318.423] [2999432:2999434] [TOO] [12]: 64 + [1724250318.423] [2999432:2999434] [TOO] [13]: 65 + [1724250318.423] [2999432:2999434] [TOO] [14]: 69 + [1724250318.423] [2999432:2999434] [TOO] [15]: 72 + [1724250318.423] [2999432:2999434] [TOO] [16]: 73 + [1724250318.423] [2999432:2999434] [TOO] [17]: 74 + [1724250318.423] [2999432:2999434] [TOO] [18]: 80 + [1724250318.423] [2999432:2999434] [TOO] [19]: 81 + [1724250318.423] [2999432:2999434] [TOO] [20]: 82 + [1724250318.423] [2999432:2999434] [TOO] [21]: 83 + [1724250318.423] [2999432:2999434] [TOO] [22]: 84 + [1724250318.423] [2999432:2999434] [TOO] [23]: 85 + [1724250318.423] [2999432:2999434] [TOO] [24]: 86 + [1724250318.423] [2999432:2999434] [TOO] [25]: 87 + [1724250318.423] [2999432:2999434] [TOO] [26]: 89 + [1724250318.423] [2999432:2999434] [TOO] [27]: 91 + [1724250318.423] [2999432:2999434] [TOO] [28]: 92 + [1724250318.423] [2999432:2999434] [TOO] [29]: 93 + [1724250318.423] [2999432:2999434] [TOO] [30]: 94 + [1724250318.423] [2999432:2999434] [TOO] [31]: 96 + [1724250318.423] [2999432:2999434] [TOO] [32]: 97 + [1724250318.423] [2999432:2999434] [TOO] [33]: 98 + [1724250318.423] [2999432:2999434] [TOO] [34]: 113 + [1724250318.423] [2999432:2999434] [TOO] [35]: 114 + [1724250318.423] [2999432:2999434] [TOO] [36]: 128 + [1724250318.424] [2999432:2999434] [TOO] [37]: 129 + [1724250318.424] [2999432:2999434] [TOO] [38]: 144 + [1724250318.424] [2999432:2999434] [TOO] [39]: 145 + [1724250318.424] [2999432:2999434] [TOO] [40]: 148 + [1724250318.424] [2999432:2999434] [TOO] [41]: 152 + [1724250318.424] [2999432:2999434] [TOO] [42]: 153 + [1724250318.424] [2999432:2999434] [TOO] [43]: 155 + [1724250318.424] [2999432:2999434] [TOO] [44]: 156 + [1724250318.424] [2999432:2999434] [TOO] [45]: 157 + [1724250318.424] [2999432:2999434] [TOO] [46]: 158 + [1724250318.424] [2999432:2999434] [TOO] [47]: 159 + [1724250318.424] [2999432:2999434] [TOO] [48]: 258 + [1724250318.424] [2999432:2999434] [TOO] [49]: 259 + [1724250318.424] [2999432:2999434] [TOO] [50]: 512 + [1724250318.424] [2999432:2999434] [TOO] [51]: 513 + [1724250318.424] [2999432:2999434] [TOO] [52]: 514 + [1724250318.424] [2999432:2999434] [TOO] [53]: 516 + [1724250318.424] [2999432:2999434] [TOO] [54]: 768 + [1724250318.424] [2999432:2999434] [TOO] [55]: 769 + [1724250318.424] [2999432:2999434] [TOO] [56]: 1024 + [1724250318.424] [2999432:2999434] [TOO] [57]: 1026 + [1724250318.424] [2999432:2999434] [TOO] [58]: 1027 + [1724250318.424] [2999432:2999434] [TOO] [59]: 1028 + [1724250318.425] [2999432:2999434] [TOO] [60]: 1029 + [1724250318.425] [2999432:2999434] [TOO] [61]: 1030 + [1724250318.425] [2999432:2999434] [TOO] [62]: 1036 + [1724250318.425] [2999432:2999434] [TOO] [63]: 1037 + [1724250318.425] [2999432:2999434] [TOO] [64]: 1043 + [1724250318.425] [2999432:2999434] [TOO] [65]: 1045 + [1724250318.425] [2999432:2999434] [TOO] [66]: 1066 + [1724250318.425] [2999432:2999434] [TOO] [67]: 1067 + [1724250318.425] [2999432:2999434] [TOO] [68]: 1068 + [1724250318.425] [2999432:2999434] [TOO] [69]: 1069 + [1724250318.425] [2999432:2999434] [TOO] [70]: 1070 + [1724250318.425] [2999432:2999434] [TOO] [71]: 1071 + [1724250318.425] [2999432:2999434] [TOO] [72]: 1283 + [1724250318.425] [2999432:2999434] [TOO] [73]: 1288 + [1724250318.425] [2999432:2999434] [TOO] [74]: 2820 + [1724250318.425] [2999432:2999434] [TOO] [75]: 4294048773 ./chip-tool descriptor read server-list 1 2 Verify ServerList entries on TH (Chip-tool) Log and below is the sample log provided for the raspi platform, Here ServerList entries are 7. - [1692618559.962829][31688:31690] [TOO] Endpoint: 2 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 1103199808 - [1692618559.962884][31688:31690] [TOO] ServerList: 7 entries - [1692618559.962910][31688:31690] [TOO] [1]: 3 (Identify) - [1692618559.962922][31688:31690] [TOO] [2]: 4 (Groups) - [1692618559.962933][31688:31690] [TOO] [3]: 5 (Unknown) - [1692618559.962945][31688:31690] [TOO] [4]: 6 (OnOff) - [1692618559.962955][31688:31690] [TOO] [5]: 29 (Descriptor) - [1692618559.962966][31688:31690] [TOO] [6]: 47 (PowerSource) - [1692618559.962978][31688:31690] [TOO] [7]: 1030 (OccupancySensing) + [1712128823.483245][6638:6640] CHIP:DMG: } + [1712128823.483490][6638:6640] CHIP:TOO: Endpoint: 2 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 3376044082 + [1712128823.483556][6638:6640] CHIP:TOO: ServerList: 7 entries + [1712128823.483582][6638:6640] CHIP:TOO: [1]: 3 + [1712128823.483595][6638:6640] CHIP:TOO: [2]: 4 + [1712128823.483606][6638:6640] CHIP:TOO: [3]: 6 + [1712128823.483617][6638:6640] CHIP:TOO: [4]: 29 + [1712128823.483628][6638:6640] CHIP:TOO: [5]: 47 + [1712128823.483639][6638:6640] CHIP:TOO: [6]: 98 + [1712128823.483650][6638:6640] CHIP:TOO: [7]: 1030 + + ./chip-tool descriptor read server-list 1 3 + + Verify ServerList entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, + + [1724250405.960] [2999967:2999969] [DMG] } + [1724250405.960] [2999967:2999969] [TOO] Endpoint: 3 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 816387248 + [1724250405.960] [2999967:2999969] [TOO] ServerList: 3 entries + [1724250405.960] [2999967:2999969] [TOO] [1]: 3 + [1724250405.960] [2999967:2999969] [TOO] [2]: 29 + [1724250405.960] [2999967:2999969] [TOO] [3]: 59 + + ./chip-tool descriptor read server-list 1 4 + + Verify ServerList entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, + + [1724250445.115] [3000229:3000231] [DMG] } + [1724250445.116] [3000229:3000231] [TOO] Endpoint: 4 Cluster: 0x0000_001D Attribute 0x0000_0001 DataVersion: 3394934309 + [1724250445.116] [3000229:3000231] [TOO] ServerList: 3 entries + [1724250445.116] [3000229:3000231] [TOO] [1]: 3 + [1724250445.116] [3000229:3000231] [TOO] [2]: 29 + [1724250445.116] [3000229:3000231] [TOO] [3]: 59 disabled: true - label: "Step 3: TH reads 'ClientList' attribute" @@ -244,30 +331,51 @@ tests: Verify client list entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, Here ClientList entries are 1. - [1676367470.160199][9805:9807] [DMG] } - [1676367470.160268][9805:9807] [TOO] Endpoint: 1 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 3336430903 - [1676367470.160282][9805:9807] [TOO] ClientList: 1 entries - [1676367470.160289][9805:9807] [TOO] [1]: 6 (OnOff) + [1676367470.160199][9805:9807] CHIP:DMG: } + [1676367470.160268][9805:9807] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 3336430903 + [1676367470.160282][9805:9807] CHIP:TOO: ClientList: 1 entries + [1676367470.160289][9805:9807] CHIP:TOO: [1]: 6 ./chip-tool descriptor read client-list 1 2 Verify client list entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, Here ClientList entries are 0. - [1660146160.390200][46818:46823] [TOO] Endpoint: 2 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 1051414887 - [1660146160.390211][46818:46823] [TOO] ClientList: 0 entries + [1660146160.390200][46818:46823] CHIP:TOO: Endpoint: 2 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 1051414887 + [1660146160.390211][46818:46823] CHIP:TOO: ClientList: 0 entries + + ./chip-tool descriptor read client-list 1 3 + + Verify client list entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, Here ClientList entries are 0. + + [1724250500.160] [3000560:3000563] [DMG] } + [1724250500.160] [3000560:3000563] [TOO] Endpoint: 3 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 816387248 + [1724250500.160] [3000560:3000563] [TOO] ClientList: 0 entries + + ./chip-tool descriptor read client-list 1 4 + + Verify client list entries on the TH (Chip-tool) and below is the sample log provided for the raspi platform, Here ClientList entries are 0. + + [1724250523.972] [3000725:3000727] [DMG] } + [1724250523.973] [3000725:3000727] [TOO] Endpoint: 4 Cluster: 0x0000_001D Attribute 0x0000_0002 DataVersion: 3394934309 + [1724250523.973] [3000725:3000727] [TOO] ClientList: 0 entries disabled: true - label: "Step 4: TH reads 'PartsList' attribute." PICS: DESC.S.A0003 verification: | - ./chip-tool descriptor read parts-list 1 0 + ./chip-tool descriptor read parts-list 1 0 + + Verify PartsList response greater than 0 and Endpoint is in the range of 1 to 65534 on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - Verify PartsList response greater than 0 and Endpoint is in the range of 1 to 65534 on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + [1724250727.129] [3001992:3001994] [DMG] } + [1724250727.130] [3001992:3001994] [TOO] Endpoint: 0 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 444270524 + [1724250727.130] [3001992:3001994] [TOO] PartsList: 4 entries + [1724250727.130] [3001992:3001994] [TOO] [1]: 1 + [1724250727.130] [3001992:3001994] [TOO] [2]: 2 + [1724250727.130] [3001992:3001994] [TOO] [3]: 3 + [1724250727.130] [3001992:3001994] [TOO] [4]: 4 - [1672919326.178697][33468:33470] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_001D Attribute 0x0000_0003 DataVersion: 2847656117 - [1672919326.178739][33468:33470] CHIP:TOO: PartsList: 2 entries - [1672919326.178765][33468:33470] CHIP:TOO: [1]: 1 - [1672919326.178777][33468:33470] CHIP:TOO: [2]: 2 + Repeat Steps 1b to 4 in a recursive manner for the Endpoints read in this step (i.e. recursively walk all the Endpoints encountered in all PartsLists) disabled: true - label: "Step 5: TH reads from the DUT the 'TagList' attribute." diff --git a/src/app/tests/suites/certification/Test_TC_DISHM_1_2.yaml b/src/app/tests/suites/certification/Test_TC_DISHM_1_2.yaml index 0bb760685297ef..20b2d348617635 100644 --- a/src/app/tests/suites/certification/Test_TC_DISHM_1_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_DISHM_1_2.yaml @@ -36,49 +36,48 @@ tests: verification: | ./chip-tool dishwashermode read supported-modes 1 1 - Verify that the DUT response contains list of ModeOptionsStruct entries. - - Verify that the list has at least 2 and at most 255 entries - - Verify that each ModeOptionsStruct entry has a unique Mode field value and Label field value. - - If ModeOptionsStruct entry’s ModeTags field is not empty, then Verify the values of the Value fields that are not larger than 16 bits, for each Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a defined cluster-derived tag value (Normal, Heavy, Light) or in the MfgTags (0x8000 to 0xBFFF) range. - - If the Value field is in the MfgTags (0x8000 to 0xBFFF) range, the TagName field is a string with a length between 1 and 64 - - Verify that at least one ModeOptionsStruct entry includes the Normal mode tag - - Save the Mode field values as supported_modes_dut on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + Verify that the DUT response contains list of ModeOptionsStruct entries. + - Verify that the list has at least 2 and at most 255 entries + - Verify that each ModeOptionsStruct entry has a unique Mode field value and Label field value. + - If ModeOptionsStruct entry’s ModeTags field is not empty, then Verify the values of the Value fields that are not larger than 16 bits, for each Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a defined cluster-derived tag value (Normal, Heavy, Light) or in the MfgTags (0x8000 to 0xBFFF) range. + - Verify that at least one ModeOptionsStruct entry includes the Normal mode tag + - Save the Mode field values as supported_modes_dut on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - [1689997453.610123][360094:360096] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 1427220838 - [1689997453.610169][360094:360096] CHIP:TOO: SupportedModes: 3 entries - [1689997453.610483][360094:360096] CHIP:TOO: [1]: { - [1689997453.610503][360094:360096] CHIP:TOO: Label: Normal - [1689997453.610530][360094:360096] CHIP:TOO: Mode: 0 - [1689997453.610536][360094:360096] CHIP:TOO: ModeTags: 1 entries - [1689997453.610540][360094:360096] CHIP:TOO: [1]: { - [1689997453.610542][360094:360096] CHIP:TOO: Value: 16384 - [1689997453.610551][360094:360096] CHIP:TOO: } - [1689997453.610553][360094:360096] CHIP:TOO: } - [1689997453.610559][360094:360096] CHIP:TOO: [2]: { - [1689997453.610571][360094:360096] CHIP:TOO: Label: Heavy - [1689997453.610574][360094:360096] CHIP:TOO: Mode: 1 - [1689997453.610577][360094:360096] CHIP:TOO: ModeTags: 2 entries - [1689997453.610580][360094:360096] CHIP:TOO: [1]: { - [1689997453.610582][360094:360096] CHIP:TOO: Value: 7 - [1689997453.610583][360094:360096] CHIP:TOO: } - [1689997453.610585][360094:360096] CHIP:TOO: [2]: { - [1689997453.610587][360094:360096] CHIP:TOO: Value: 16385 - [1689997453.610588][360094:360096] CHIP:TOO: } - [1689997453.610590][360094:360096] CHIP:TOO: } - [1689997453.610594][360094:360096] CHIP:TOO: [3]: { - [1689997453.610595][360094:360096] CHIP:TOO: Label: Light - [1689997453.610597][360094:360096] CHIP:TOO: Mode: 2 - [1689997453.610600][360094:360096] CHIP:TOO: ModeTags: 3 entries - [1689997453.610602][360094:360096] CHIP:TOO: [1]: { - [1689997453.610604][360094:360096] CHIP:TOO: Value: 16386 - [1689997453.610605][360094:360096] CHIP:TOO: } - [1689997453.610607][360094:360096] CHIP:TOO: [2]: { - [1689997453.610609][360094:360096] CHIP:TOO: Value: 8 - [1689997453.610610][360094:360096] CHIP:TOO: } - [1689997453.610612][360094:360096] CHIP:TOO: [3]: { - [1689997453.610614][360094:360096] CHIP:TOO: Value: 2 - [1689997453.610615][360094:360096] CHIP:TOO: } - [1689997453.610617][360094:360096] CHIP:TOO: } + [1689997453.610123][360094:360096] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 1427220838 + [1689997453.610169][360094:360096] CHIP:TOO: SupportedModes: 3 entries + [1689997453.610483][360094:360096] CHIP:TOO: [1]: { + [1689997453.610503][360094:360096] CHIP:TOO: Label: Normal + [1689997453.610530][360094:360096] CHIP:TOO: Mode: 0 + [1689997453.610536][360094:360096] CHIP:TOO: ModeTags: 1 entries + [1689997453.610540][360094:360096] CHIP:TOO: [1]: { + [1689997453.610542][360094:360096] CHIP:TOO: Value: 16384 + [1689997453.610551][360094:360096] CHIP:TOO: } + [1689997453.610553][360094:360096] CHIP:TOO: } + [1689997453.610559][360094:360096] CHIP:TOO: [2]: { + [1689997453.610571][360094:360096] CHIP:TOO: Label: Heavy + [1689997453.610574][360094:360096] CHIP:TOO: Mode: 1 + [1689997453.610577][360094:360096] CHIP:TOO: ModeTags: 2 entries + [1689997453.610580][360094:360096] CHIP:TOO: [1]: { + [1689997453.610582][360094:360096] CHIP:TOO: Value: 7 + [1689997453.610583][360094:360096] CHIP:TOO: } + [1689997453.610585][360094:360096] CHIP:TOO: [2]: { + [1689997453.610587][360094:360096] CHIP:TOO: Value: 16385 + [1689997453.610588][360094:360096] CHIP:TOO: } + [1689997453.610590][360094:360096] CHIP:TOO: } + [1689997453.610594][360094:360096] CHIP:TOO: [3]: { + [1689997453.610595][360094:360096] CHIP:TOO: Label: Light + [1689997453.610597][360094:360096] CHIP:TOO: Mode: 2 + [1689997453.610600][360094:360096] CHIP:TOO: ModeTags: 3 entries + [1689997453.610602][360094:360096] CHIP:TOO: [1]: { + [1689997453.610604][360094:360096] CHIP:TOO: Value: 16386 + [1689997453.610605][360094:360096] CHIP:TOO: } + [1689997453.610607][360094:360096] CHIP:TOO: [2]: { + [1689997453.610609][360094:360096] CHIP:TOO: Value: 8 + [1689997453.610610][360094:360096] CHIP:TOO: } + [1689997453.610612][360094:360096] CHIP:TOO: [3]: { + [1689997453.610614][360094:360096] CHIP:TOO: Value: 2 + [1689997453.610615][360094:360096] CHIP:TOO: } + [1689997453.610617][360094:360096] CHIP:TOO: } disabled: true - label: "Step 3: TH reads from the DUT the CurrentMode attribute." diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_1_2.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_1_2.yaml index 642dc5f09912dd..adfd864b9b4fd7 100644 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_1_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_EEVSEM_1_2.yaml @@ -24,62 +24,68 @@ config: endpoint: 1 tests: - - label: "Step 1: TH reads from the DUT the SupportedModes attribute" + - label: + "Step 1: Commission DUT to TH (can be skipped if done in a preceding + test)." + verification: | + + disabled: true + + - label: "Step 2: TH reads from the DUT the SupportedModes attribute" PICS: EEVSEM.S.A0000 verification: | ./chip-tool energyevsemode read supported-modes 1 1 - - Verify that the DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has at least 2 and at most 255 entries - - Verify that each ModeOptionsStruct entry has a unique Mode field value - - Verify that each ModeOptionsStruct entry has a unique Label field value - - Verify that each ModeOptionsStruct entry’s ModeTags field has: - at least one entry the values of the Value fields that are not larger than 16 bits - - for each Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a defined cluster-derived tag value (Manual, Time of Use, (T_SOLAR_CHARGING)) or in the MfgTags (0x8000 to 0xBFFF) range - - for at least one Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a derived cluster value (Bake(0x4000), Convection(0x4001), Grill(0x4002), Roast(0x4003), Clean(0x4004), Convection Bake(0x4005), Convection Roast(0x4006), Warming(0x4007), Proofing(0x4008)) - - if the Value field is in the MfgTags (0x8000 to 0xBFFF) range, the TagName field is a string with a length between 1 and 64 - - Verify that at least one ModeOptionsStruct entry includes the Manual mode tag - - Save the Mode field values as supported_modes_dut on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + - Verify that the DUT response contains a list of ModeOptionsStruct entries + - Verify that the list has at least 2 and at most 255 entries + - Verify that each ModeOptionsStruct entry has a unique Mode field value + - Verify that each ModeOptionsStruct entry has a unique Label field value + - Verify that each ModeOptionsStruct entry’s ModeTags field has: + at least one entry the values of the Value fields that are not larger than 16 bits + - for each Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a defined cluster-derived tag value (Manual, Time of Use, (T_SOLAR_CHARGING)) or in the MfgTags (0x8000 to 0xBFFF) range + - for at least one Value field: Is the mode tag value a defined common tag value (Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a derived cluster value (Bake(0x4000), Convection(0x4001), Grill(0x4002), Roast(0x4003), Clean(0x4004), Convection Bake(0x4005), Convection Roast(0x4006), Warming(0x4007), Proofing(0x4008)) + - Verify that at least one ModeOptionsStruct entry includes the Manual mode tag + - Save the Mode field values as supported_modes_dut on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - [1705995452.973731][7546:7548] CHIP:DMG: } - [1705995452.973843][7546:7548] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_009D Attribute 0x0000_0000 DataVersion: 1324786556 - [1705995452.973865][7546:7548] CHIP:TOO: SupportedModes: 4 entries - [1705995452.973883][7546:7548] CHIP:TOO: [1]: { - [1705995452.973886][7546:7548] CHIP:TOO: Label: Manual - [1705995452.973892][7546:7548] CHIP:TOO: Mode: 0 - [1705995452.973898][7546:7548] CHIP:TOO: ModeTags: 1 entries - [1705995452.973903][7546:7548] CHIP:TOO: [1]: { - [1705995452.973906][7546:7548] CHIP:TOO: Value: 16384 - [1705995452.973909][7546:7548] CHIP:TOO: } - [1705995452.973912][7546:7548] CHIP:TOO: } - [1705995452.973918][7546:7548] CHIP:TOO: [2]: { - [1705995452.973921][7546:7548] CHIP:TOO: Label: Auto-scheduled - [1705995452.973923][7546:7548] CHIP:TOO: Mode: 1 - [1705995452.973926][7546:7548] CHIP:TOO: ModeTags: 1 entries - [1705995452.973930][7546:7548] CHIP:TOO: [1]: { - [1705995452.973933][7546:7548] CHIP:TOO: Value: 16385 - [1705995452.973935][7546:7548] CHIP:TOO: } - [1705995452.973938][7546:7548] CHIP:TOO: } - [1705995452.973943][7546:7548] CHIP:TOO: [3]: { - [1705995452.973946][7546:7548] CHIP:TOO: Label: Solar - [1705995452.973948][7546:7548] CHIP:TOO: Mode: 2 - [1705995452.973951][7546:7548] CHIP:TOO: ModeTags: 1 entries - [1705995452.973955][7546:7548] CHIP:TOO: [1]: { - [1705995452.973957][7546:7548] CHIP:TOO: Value: 16386 - [1705995452.973960][7546:7548] CHIP:TOO: } - [1705995452.973962][7546:7548] CHIP:TOO: } - [1705995452.973968][7546:7548] CHIP:TOO: [4]: { - [1705995452.973971][7546:7548] CHIP:TOO: Label: Auto-scheduled with Solar charging - [1705995452.973973][7546:7548] CHIP:TOO: Mode: 3 - [1705995452.973977][7546:7548] CHIP:TOO: ModeTags: 2 entries - [1705995452.973981][7546:7548] CHIP:TOO: [1]: { - [1705995452.973983][7546:7548] CHIP:TOO: Value: 16385 - [1705995452.973986][7546:7548] CHIP:TOO: } - [1705995452.973989][7546:7548] CHIP:TOO: [2]: { - [1705995452.973992][7546:7548] CHIP:TOO: Value: 16386 - [1705995452.973994][7546:7548] CHIP:TOO: } - [1705995452.973996][7546:7548] CHIP:TOO: } + [1705995452.973731][7546:7548] CHIP:DMG: } + [1705995452.973843][7546:7548] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_009D Attribute 0x0000_0000 DataVersion: 1324786556 + [1705995452.973865][7546:7548] CHIP:TOO: SupportedModes: 4 entries + [1705995452.973883][7546:7548] CHIP:TOO: [1]: { + [1705995452.973886][7546:7548] CHIP:TOO: Label: Manual + [1705995452.973892][7546:7548] CHIP:TOO: Mode: 0 + [1705995452.973898][7546:7548] CHIP:TOO: ModeTags: 1 entries + [1705995452.973903][7546:7548] CHIP:TOO: [1]: { + [1705995452.973906][7546:7548] CHIP:TOO: Value: 16384 + [1705995452.973909][7546:7548] CHIP:TOO: } + [1705995452.973912][7546:7548] CHIP:TOO: } + [1705995452.973918][7546:7548] CHIP:TOO: [2]: { + [1705995452.973921][7546:7548] CHIP:TOO: Label: Auto-scheduled + [1705995452.973923][7546:7548] CHIP:TOO: Mode: 1 + [1705995452.973926][7546:7548] CHIP:TOO: ModeTags: 1 entries + [1705995452.973930][7546:7548] CHIP:TOO: [1]: { + [1705995452.973933][7546:7548] CHIP:TOO: Value: 16385 + [1705995452.973935][7546:7548] CHIP:TOO: } + [1705995452.973938][7546:7548] CHIP:TOO: } + [1705995452.973943][7546:7548] CHIP:TOO: [3]: { + [1705995452.973946][7546:7548] CHIP:TOO: Label: Solar + [1705995452.973948][7546:7548] CHIP:TOO: Mode: 2 + [1705995452.973951][7546:7548] CHIP:TOO: ModeTags: 1 entries + [1705995452.973955][7546:7548] CHIP:TOO: [1]: { + [1705995452.973957][7546:7548] CHIP:TOO: Value: 16386 + [1705995452.973960][7546:7548] CHIP:TOO: } + [1705995452.973962][7546:7548] CHIP:TOO: } + [1705995452.973968][7546:7548] CHIP:TOO: [4]: { + [1705995452.973971][7546:7548] CHIP:TOO: Label: Auto-scheduled with Solar charging + [1705995452.973973][7546:7548] CHIP:TOO: Mode: 3 + [1705995452.973977][7546:7548] CHIP:TOO: ModeTags: 2 entries + [1705995452.973981][7546:7548] CHIP:TOO: [1]: { + [1705995452.973983][7546:7548] CHIP:TOO: Value: 16385 + [1705995452.973986][7546:7548] CHIP:TOO: } + [1705995452.973989][7546:7548] CHIP:TOO: [2]: { + [1705995452.973992][7546:7548] CHIP:TOO: Value: 16386 + [1705995452.973994][7546:7548] CHIP:TOO: } + [1705995452.973996][7546:7548] CHIP:TOO: } disabled: true - label: "Step 2: TH reads from the DUT the CurrentMode attribute" diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_2_1.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_2_1.yaml index b5f483f62fe2d9..2a238e703637ce 100644 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_EEVSEM_2_1.yaml @@ -147,7 +147,7 @@ tests: - label: "Step 9: Manually put the device in a state from which it will SUCCESSFULLY transition to PIXIT.EEVSEM.MODE_CHANGE_OK" - PICS: PICS_SKIP_SAMPLE_APP + PICS: PICS_SKIP_SAMPLE_APP && EEVSEM.S.M.CAN_MANUALLY_CONTROLLED verification: | Manual operation required cluster: "LogCommands" diff --git a/src/app/tests/suites/certification/Test_TC_I_2_2.yaml b/src/app/tests/suites/certification/Test_TC_I_2_2.yaml index 09a2d6bd0610ac..3101690e95d318 100644 --- a/src/app/tests/suites/certification/Test_TC_I_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_2_2.yaml @@ -54,6 +54,22 @@ tests: - name: "IdentifyTime" value: 60 + - label: + "Verify that the device enters its identification state using the + IdentifyType from Step 1b, in order to indicate to an observer which + of several nodes and/or endpoints it is." + verification: | + Verify that the device enters its identification state using the IdentifyType from step1b, Here the Identifytype is 2(VisibleIndicator) which can be a small led that indicates the device is in identification state. This IdentifyType can vary to device ref: 1.2.5.1 in spec for the IdentifyTypeEnum of the particular DUT + cluster: "LogCommands" + command: "UserPrompt" + PICS: PICS_USER_PROMPT && I.S.A0001 + arguments: + values: + - name: "message" + value: "Please enter 'y' for success" + - name: "expectedValue" + value: "y" + - label: "Step 2b: TH reads immediately IdentifyTime attribute from DUT" PICS: I.S.A0000 command: "readAttribute" @@ -82,24 +98,8 @@ tests: minValue: 42 maxValue: 58 - # - label: - # "Step 3: TH sends IdentifyQuery command to DUT and Verify - # IdentifyQueryResponse command to TH,with the Timeout field set to a - # value in the range 0x0000 to 0x0032" - # verification: | - # IdentifyQuery is not supported by Matter - # cluster: "LogCommands" - # command: "UserPrompt" - # PICS: PICS_USER_PROMPT && I.S.C01.Rsp && I.S.C00.Tx - # arguments: - # values: - # - name: "message" - # value: "Please enter 'y' for success" - # - name: "expectedValue" - # value: "y" - - label: - "Step 4a: Before 60 seconds expire, TH sends Identify command to DUT, + "Step 3a: Before 60 seconds expire, TH sends Identify command to DUT, with the identify time field set to 0x0000 (stop identifying)." PICS: I.S.C00.Rsp command: "Identify" @@ -108,35 +108,28 @@ tests: - name: "IdentifyTime" value: 0 - - label: "Step 4b: TH reads immediately IdentifyTime attribute from DUT" + - label: "Step 3b: TH reads immediately IdentifyTime attribute from DUT" PICS: I.S.A0000 command: "readAttribute" attribute: "IdentifyTime" response: value: 0 - # disabled due to IdentifyQuery not supported for matter V1.0 - #- label: "Step 5: TH sends IdentifyQuery command to DUT " - # verification: | - # IdentifyQuery is not supported by Matter - # cluster: "LogCommands" - # command: "UserPrompt" - # PICS: PICS_USER_PROMPT && I.S.C01.Rsp && I.S.C00.Tx - # arguments: - # values: - # - name: "message" - # value: "Please enter 'y' for success" - # - name: "expectedValue" - # value: "y" + - label: + "Step 4a: TH writes a value of 0x000f (15s) to IdentifyTime attribute + of DUT" + PICS: I.S.A0000 + command: "writeAttribute" + attribute: "IdentifyTime" + arguments: + value: 15 - label: - "Step 6a: Verify that the device enters its identification state using - the IdentifyType from Step 1b, in order to indicate to an observer - which of several nodes and/or endpoints it is." + "Verify that the device enters its identification state using the + IdentifyType from Step 1b, in order to indicate to an observer which + of several nodes and/or endpoints it is." verification: | - Verify that the device enters its identification state using the IdentifyType from step1b, - Here the Identifytype is 2(VisibleIndicator) which can be a small led that indicates the device is in identification state. - This IdentifyType can vary to device ref: 1.2.5.1 in spec for the IdentifyTypeEnum of the particular DUT + Verify that the device enters its identification state using the IdentifyType from step1b, Here the Identifytype is 2(VisibleIndicator) which can be a small led that indicates the device is in identification state. This IdentifyType can vary to device ref: 1.2.5.1 in spec for the IdentifyTypeEnum of the particular DUT cluster: "LogCommands" command: "UserPrompt" PICS: PICS_USER_PROMPT && I.S.A0001 @@ -147,15 +140,6 @@ tests: - name: "expectedValue" value: "y" - - label: - "Step 6a: TH writes a value of 0x000f (15s) to IdentifyTime attribute - of DUT" - PICS: I.S.A0000 - command: "writeAttribute" - attribute: "IdentifyTime" - arguments: - value: 15 - - label: "Wait 15000ms" cluster: "DelayCommands" command: "WaitForMs" @@ -165,7 +149,7 @@ tests: value: 15000 - label: - "Step 6b: After 15 seconds, the TH reads IdentifyTime attribute from + "Step 4b: After 15 seconds, the TH reads IdentifyTime attribute from DUT" PICS: I.S.A0000 command: "readAttribute" @@ -174,19 +158,3 @@ tests: constraints: minValue: 0 maxValue: 5 - - - label: - "Step 6b: Verify that the device terminates its identification state" - verification: | - Verify that the identification state is terminated in the DUT. - Here the Identifytype is 2(VisibleIndicator) which can be a small led that indicates the device is in identification state. - This IdentifyType can vary to device ref: 1.2.5.1 in spec for the IdentifyTypeEnum of the particular DUT - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT && I.S.A0001 - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" diff --git a/src/app/tests/suites/certification/Test_TC_I_3_2.yaml b/src/app/tests/suites/certification/Test_TC_I_3_2.yaml index adedbb3c0566cc..2b3bcd59de0151 100644 --- a/src/app/tests/suites/certification/Test_TC_I_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_3_2.yaml @@ -70,15 +70,7 @@ tests: disabled: true - label: - "Step 2: DUT issues an IdentifyQuery command to the Test Harness. - Note: IdentifyQuery is not supported by Matter." - PICS: I.C.C01.Tx - verification: | - IdentifyQuery is not supported by Matter - disabled: true - - - label: - "Step 3: DUT issues an Identify command to the Test Harness, with the + "Step 2: DUT issues an Identify command to the Test Harness, with the IdentifyTime argument set to 0x0000 (Stop)." PICS: I.C.C00.Tx verification: | @@ -116,7 +108,7 @@ tests: disabled: true - label: - "Step 4: DUT sends a TriggerEffect command to the Test Harness, with + "Step 3: DUT sends a TriggerEffect command to the Test Harness, with any supported EffectIdentifier argument and EffectVariant set to 0." PICS: I.C.C40.Tx verification: | diff --git a/src/app/tests/suites/certification/Test_TC_LWM_1_2.yaml b/src/app/tests/suites/certification/Test_TC_LWM_1_2.yaml index fc9a0211fb7caf..52310a3cc86cf3 100644 --- a/src/app/tests/suites/certification/Test_TC_LWM_1_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_LWM_1_2.yaml @@ -40,7 +40,6 @@ tests: - Verify that the list has at least 2 and at most 255 entries - Verify that each ModeOptionsStruct entry has a unique Mode field value and Label field value - If ModeOptionsStruct entry’s ModeTags field is not empty, then Verify the values of the Value fields that are not larger than 16 bits, for each Value field: Is the mode tag value a defined common tag value ( Auto(0x0000), Quick(0x0001), Quiet(0x0002), LowNoise(0x0003), LowEnergy(0x0004), Vacation(0x0005), Min(0x0006), Max(0x0007), Night(0x0008), Day(0x0009)) or a defined cluster derived tag value ( Normal, Delicate, Heavy, Whites) or in the MfgTags (0x8000 to 0xBFFF) range - - If the Value field is in the MfgTags (0x8000 to 0xBFFF) range, the TagName field is a string with a length between 1 and 64 - Verify that at least one ModeOptionsStruct entry includes the Normal mode tag - Save the Mode field values as supported_modes_dut on the TH (Chip-tool) and below is the sample log provided for the raspi platform: diff --git a/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml b/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml index b2c5355ece71eb..51f389b6afaffc 100644 --- a/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml @@ -251,6 +251,36 @@ tests: time in a manufacturer specific order" PICS: MOD.C.AO-READ verification: | + ./chip-tool modeselect read on-mode 1 1 + + Verify the "OnMode response" on the TH (all-cluster-app) log: + + [1666940828.515256][9718:9718] CHIP:DMG: ReportDataMessage = + [1666940828.515259][9718:9718] CHIP:DMG: { + [1666940828.515261][9718:9718] CHIP:DMG: AttributeReportIBs = + [1666940828.515265][9718:9718] CHIP:DMG: [ + [1666940828.515267][9718:9718] CHIP:DMG: AttributeReportIB = + [1666940828.515272][9718:9718] CHIP:DMG: { + [1666940828.515275][9718:9718] CHIP:DMG: AttributeDataIB = + [1666940828.515277][9718:9718] CHIP:DMG: { + [1666940828.515280][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, + [1666940828.515282][9718:9718] CHIP:DMG: AttributePathIB = + [1666940828.515285][9718:9718] CHIP:DMG: { + [1666940828.515288][9718:9718] CHIP:DMG: Endpoint = 0x1, + [1666940828.515290][9718:9718] CHIP:DMG: Cluster = 0x50, + [1666940828.515293][9718:9718] CHIP:DMG: Attribute = 0x0000_0005, + [1666940828.515295][9718:9718] CHIP:DMG: } + [1666940828.515298][9718:9718] CHIP:DMG: + [1666940828.515301][9718:9718] CHIP:DMG: Data = NULL + [1666940828.515304][9718:9718] CHIP:DMG: }, + [1666940828.515307][9718:9718] CHIP:DMG: + [1666940828.515309][9718:9718] CHIP:DMG: }, + [1666940828.515312][9718:9718] CHIP:DMG: + [1666940828.515314][9718:9718] CHIP:DMG: ], + [1666940828.515317][9718:9718] CHIP:DMG: + [1666940828.515320][9718:9718] CHIP:DMG: SuppressResponse = true, + [1666940828.515322][9718:9718] CHIP:DMG: InteractionModelRevision = 1 + ./chip-tool modeselect read start-up-mode 1 1 Verify the "StartUpMode response" on the TH (all-cluster-app) log: diff --git a/src/app/tests/suites/certification/Test_TC_WASHERCTRL_2_2.yaml b/src/app/tests/suites/certification/Test_TC_WASHERCTRL_2_2.yaml index be22b8bc5e4121..c1089959ad0b32 100644 --- a/src/app/tests/suites/certification/Test_TC_WASHERCTRL_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_WASHERCTRL_2_2.yaml @@ -27,7 +27,7 @@ config: defaultValue: 1 unsupportedNumberOfRinsesValue: type: enum8 - defaultValue: 5 + defaultValue: 4 tests: - label: "Step 1: Commission DUT to TH" @@ -83,23 +83,10 @@ tests: response: value: NumberOfRinsesValue - - label: "Step 6: Operate device to set the condition to read only" - verification: | - Manual operation required - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP && WASHERCTRL.S.M.ManuallyControlled - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - label: - "Step 7: TH writes an unsupported NumberOfRinses attribute to DUT + "Step 6: TH writes an unsupported NumberOfRinses attribute to DUT while DUT is not in a valid state." - PICS: WASHERCTRL.S.M.ManuallyControlled && WASHERCTRL.S.A0002 + PICS: WASHERCTRL.S.A0002 command: "writeAttribute" attribute: "NumberOfRinses" arguments: From 6fa2914b1f9e1ff020835ece10ec724c6b075e6f Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:07:00 -0400 Subject: [PATCH 57/70] [Bugfix] Waterleakdetector ScenesManagement build issue (#35406) * Fixed default SceneTableSize value in waterleakdetector and improved the ifdef detection of the define * Removed Scenes Management from waterleak detector and template --- ...otnode_waterleakdetector_0b067acfa3.matter | 182 ------------ .../rootnode_waterleakdetector_0b067acfa3.zap | 275 +----------------- examples/chef/devices/template.zap | 273 +---------------- .../clusters/scenes-server/SceneTableImpl.h | 2 +- 4 files changed, 14 insertions(+), 718 deletions(-) diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter index a75da3800cd9de..e41e0b8b65d521 100644 --- a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter @@ -1357,162 +1357,6 @@ cluster BooleanState = 69 { readonly attribute int16u clusterRevision = 65533; } -/** Attributes and commands for scene configuration and manipulation. */ -provisional cluster ScenesManagement = 98 { - revision 1; - - bitmap CopyModeBitmap : bitmap8 { - kCopyAllScenes = 0x1; - } - - bitmap Feature : bitmap32 { - kSceneNames = 0x1; - } - - struct AttributeValuePairStruct { - attrib_id attributeID = 0; - optional int8u valueUnsigned8 = 1; - optional int8s valueSigned8 = 2; - optional int16u valueUnsigned16 = 3; - optional int16s valueSigned16 = 4; - optional int32u valueUnsigned32 = 5; - optional int32s valueSigned32 = 6; - optional int64u valueUnsigned64 = 7; - optional int64s valueSigned64 = 8; - } - - struct ExtensionFieldSet { - cluster_id clusterID = 0; - AttributeValuePairStruct attributeValueList[] = 1; - } - - fabric_scoped struct SceneInfoStruct { - int8u sceneCount = 0; - fabric_sensitive int8u currentScene = 1; - fabric_sensitive group_id currentGroup = 2; - fabric_sensitive boolean sceneValid = 3; - int8u remainingCapacity = 4; - fabric_idx fabricIndex = 254; - } - - readonly attribute optional nullable node_id lastConfiguredBy = 0; - readonly attribute int16u sceneTableSize = 1; - readonly attribute SceneInfoStruct fabricSceneInfo[] = 2; - readonly attribute command_id generatedCommandList[] = 65528; - readonly attribute command_id acceptedCommandList[] = 65529; - readonly attribute event_id eventList[] = 65530; - readonly attribute attrib_id attributeList[] = 65531; - readonly attribute bitmap32 featureMap = 65532; - readonly attribute int16u clusterRevision = 65533; - - request struct AddSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - int32u transitionTime = 2; - char_string sceneName = 3; - ExtensionFieldSet extensionFieldSets[] = 4; - } - - response struct AddSceneResponse = 0 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct ViewSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct ViewSceneResponse = 1 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - optional int32u transitionTime = 3; - optional char_string sceneName = 4; - optional ExtensionFieldSet extensionFieldSets[] = 5; - } - - request struct RemoveSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct RemoveSceneResponse = 2 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct RemoveAllScenesRequest { - group_id groupID = 0; - } - - response struct RemoveAllScenesResponse = 3 { - status status = 0; - group_id groupID = 1; - } - - request struct StoreSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct StoreSceneResponse = 4 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct RecallSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - optional nullable int32u transitionTime = 2; - } - - request struct GetSceneMembershipRequest { - group_id groupID = 0; - } - - response struct GetSceneMembershipResponse = 6 { - status status = 0; - nullable int8u capacity = 1; - group_id groupID = 2; - optional int8u sceneList[] = 3; - } - - request struct CopySceneRequest { - CopyModeBitmap mode = 0; - group_id groupIdentifierFrom = 1; - int8u sceneIdentifierFrom = 2; - group_id groupIdentifierTo = 3; - int8u sceneIdentifierTo = 4; - } - - response struct CopySceneResponse = 64 { - status status = 0; - group_id groupIdentifierFrom = 1; - int8u sceneIdentifierFrom = 2; - } - - /** Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' */ - fabric command access(invoke: manage) AddScene(AddSceneRequest): AddSceneResponse = 0; - /** Retrieves the requested scene entry from its Scene table. */ - fabric command ViewScene(ViewSceneRequest): ViewSceneResponse = 1; - /** Removes the requested scene entry, corresponding to the value of the GroupID field, from its Scene Table */ - fabric command access(invoke: manage) RemoveScene(RemoveSceneRequest): RemoveSceneResponse = 2; - /** Remove all scenes, corresponding to the value of the GroupID field, from its Scene Table */ - fabric command access(invoke: manage) RemoveAllScenes(RemoveAllScenesRequest): RemoveAllScenesResponse = 3; - /** Adds the scene entry into its Scene Table along with all extension field sets corresponding to the current state of other clusters on the same endpoint */ - fabric command access(invoke: manage) StoreScene(StoreSceneRequest): StoreSceneResponse = 4; - /** Set the attributes and corresponding state for each other cluster implemented on the endpoint accordingly to the resquested scene entry in the Scene Table */ - fabric command RecallScene(RecallSceneRequest): DefaultSuccess = 5; - /** Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group */ - fabric command GetSceneMembership(GetSceneMembershipRequest): GetSceneMembershipResponse = 6; - /** Allows a client to efficiently copy scenes from one group/scene identifier pair to another group/scene identifier pair. */ - fabric command CopyScene(CopySceneRequest): CopySceneResponse = 64; -} - /** This cluster is used to configure a boolean sensor. */ cluster BooleanStateConfiguration = 128 { revision 1; @@ -1818,32 +1662,6 @@ endpoint 1 { ram attribute clusterRevision default = 1; } - server cluster ScenesManagement { - ram attribute lastConfiguredBy; - ram attribute sceneTableSize; - callback attribute fabricSceneInfo; - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 1; - ram attribute clusterRevision default = 6; - - handle command AddScene; - handle command AddSceneResponse; - handle command ViewScene; - handle command ViewSceneResponse; - handle command RemoveScene; - handle command RemoveSceneResponse; - handle command RemoveAllScenes; - handle command RemoveAllScenesResponse; - handle command StoreScene; - handle command StoreSceneResponse; - handle command RecallScene; - handle command GetSceneMembership; - handle command GetSceneMembershipResponse; - } - server cluster BooleanStateConfiguration { callback attribute generatedCommandList; callback attribute acceptedCommandList; diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap index dad5608b6c6384..d2f3e341907a7d 100644 --- a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.zap @@ -643,7 +643,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -659,7 +659,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -756,7 +756,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -772,7 +772,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -788,7 +788,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -804,7 +804,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -820,7 +820,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2746,267 +2746,6 @@ } ] }, - { - "name": "Scenes Management", - "code": 98, - "mfgCode": null, - "define": "SCENES_CLUSTER", - "side": "server", - "enabled": 1, - "apiMaturity": "provisional", - "commands": [ - { - "name": "AddScene", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "AddSceneResponse", - "code": 0, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "ViewScene", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ViewSceneResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveScene", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveSceneResponse", - "code": 2, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenes", - "code": 3, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenesResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "StoreScene", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "StoreSceneResponse", - "code": 4, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RecallScene", - "code": 5, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembership", - "code": 6, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembershipResponse", - "code": 6, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "LastConfiguredBy", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "node_id", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "SceneTableSize", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FabricSceneInfo", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "6", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] - }, { "name": "Boolean State Configuration", "code": 128, diff --git a/examples/chef/devices/template.zap b/examples/chef/devices/template.zap index c0bc9ae53991a6..82c175c74fc289 100644 --- a/examples/chef/devices/template.zap +++ b/examples/chef/devices/template.zap @@ -756,7 +756,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -772,7 +772,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -788,7 +788,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -804,7 +804,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -820,7 +820,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2623,267 +2623,6 @@ "reportableChange": 0 } ] - }, - { - "name": "Scenes Management", - "code": 98, - "mfgCode": null, - "define": "SCENES_CLUSTER", - "side": "server", - "enabled": 1, - "apiMaturity": "provisional", - "commands": [ - { - "name": "AddScene", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "AddSceneResponse", - "code": 0, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "ViewScene", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ViewSceneResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveScene", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveSceneResponse", - "code": 2, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenes", - "code": 3, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenesResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "StoreScene", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "StoreSceneResponse", - "code": 4, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RecallScene", - "code": 5, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembership", - "code": 6, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembershipResponse", - "code": 6, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "LastConfiguredBy", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "node_id", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "SceneTableSize", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FabricSceneInfo", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "6", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] } ] } @@ -2906,4 +2645,4 @@ "parentEndpointIdentifier": null } ] -} +} \ No newline at end of file diff --git a/src/app/clusters/scenes-server/SceneTableImpl.h b/src/app/clusters/scenes-server/SceneTableImpl.h index d77e957f5c32d2..a4259911c37b01 100644 --- a/src/app/clusters/scenes-server/SceneTableImpl.h +++ b/src/app/clusters/scenes-server/SceneTableImpl.h @@ -29,7 +29,7 @@ namespace chip { namespace scenes { -#ifdef SCENES_MANAGEMENT_TABLE_SIZE +#if defined(SCENES_MANAGEMENT_TABLE_SIZE) && SCENES_MANAGEMENT_TABLE_SIZE static constexpr uint16_t kMaxScenesPerEndpoint = SCENES_MANAGEMENT_TABLE_SIZE; #else static constexpr uint16_t kMaxScenesPerEndpoint = CHIP_CONFIG_MAX_SCENES_TABLE_SIZE; From 0661d7aa75f87cb2ef8e6173d5d3c039abd45661 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 4 Sep 2024 17:22:00 -0400 Subject: [PATCH 58/70] Make DM provider and ember encode errors the same (#35338) * The flag of CONFIG_BUILD_FOR_HOST_UNIT_TEST is not actually tied to unit testing. Implement a separate flag to control if we crash on errors for IM/DM checks or not. * Update src/app/common_flags.gni Co-authored-by: Boris Zbarsky * make the flag name singular * Add unit test cluster members * Modified zap and made these attributes optional * Zap regen * Attributes MUST be up to 0x4FFF so needed to switch codes * Update ids enabling * Move around things and add unit test * Update to run unit tests with enforced DM checking * Comment describing the updated options * Fix unit test * Restyle * Kotlin format since it seems different eforcement is going on here * Update src/app/zap-templates/zcl/data-model/chip/test-cluster.xml Co-authored-by: Boris Zbarsky * Update examples/all-clusters-app/linux/main-common.cpp Co-authored-by: Boris Zbarsky * Remove redundant using * Simplify/shorten code * Move base to 0x3000 for the new attributes for test cluster testing * Restyle * Fix python unit test * Fix all clusters app * Fix unused import in python * Zap regen * Fix cirque * Fix hardcoded paths in TestTimeSyncTrustedtimeSourceRunner.py * Typo fix * Remove extra spacing * Update text * Fix app path --------- Co-authored-by: Andrei Litvin Co-authored-by: Boris Zbarsky --- .github/workflows/tests.yaml | 12 +- .../all-clusters-app.matter | 4 + .../all-clusters-common/all-clusters-app.zap | 32 +++ .../all-clusters-app/linux/main-common.cpp | 30 +- .../all-clusters-minimal-app.matter | 2 + .../rootnode_contactsensor_27f76aeaf5.matter | 2 + scripts/build/build/targets.py | 1 + scripts/build/builders/host.py | 6 + .../build/testdata/all_targets_linux_x64.txt | 2 +- .../TestTimeSyncTrustedTimeSourceRunner.py | 49 ++-- .../util/ember-compatibility-functions.cpp | 28 +- .../zcl/data-model/chip/test-cluster.xml | 8 + .../data_model/controller-clusters.matter | 2 + .../chip/devicecontroller/ChipClusters.java | 72 +++++ .../devicecontroller/ClusterIDMapping.java | 2 + .../devicecontroller/ClusterReadMapping.java | 22 ++ .../devicecontroller/ClusterWriteMapping.java | 44 +++ .../cluster/clusters/UnitTestingCluster.kt | 264 +++++++++++++++++ .../src/matter/controller/ICDClientInfo.kt | 3 +- .../CHIPAttributeTLVValueDecoder.cpp | 32 +++ .../python/chip/clusters/CHIPClusters.py | 14 + .../python/chip/clusters/Objects.py | 36 +++ .../test/test_scripts/cluster_objects.py | 2 + .../MTRAttributeSpecifiedCheck.mm | 6 + .../MTRAttributeTLVValueDecoder.mm | 22 ++ .../CHIP/zap-generated/MTRBaseClusters.h | 16 ++ .../CHIP/zap-generated/MTRBaseClusters.mm | 128 +++++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 2 + .../CHIP/zap-generated/MTRClusterNames.mm | 8 + .../CHIP/zap-generated/MTRClusters.h | 8 + .../CHIP/zap-generated/MTRClusters.mm | 32 +++ .../TestUnitTestingErrorPath.py | 102 +++++++ .../zap-generated/attributes/Accessors.cpp | 92 ++++++ .../zap-generated/attributes/Accessors.h | 12 + .../zap-generated/cluster-objects.cpp | 4 + .../zap-generated/cluster-objects.h | 28 +- .../app-common/zap-generated/ids/Attributes.h | 8 + .../zap-generated/cluster/Commands.h | 10 + .../cluster/logging/DataModelLogger.cpp | 10 + .../cluster/logging/EntryToText.cpp | 4 + .../zap-generated/cluster/Commands.h | 265 ++++++++++++++++++ 41 files changed, 1388 insertions(+), 38 deletions(-) create mode 100644 src/python_testing/TestUnitTestingErrorPath.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 8d8b0064202c9d..3a9bca19317216 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -475,11 +475,17 @@ jobs: mkdir objdir-clone || true - name: Build Python REPL and example apps + # NOTE: the data-mode-check + check-failure-die is not 100% perfect as different + # encoding sizes for data that keeps changing may alter over time (e.g. anything relating to time + # or resources such as packet counts or other similar counters) + # + # This may result in invalid errors, however for most purposes of our testing, we are unlikely to + # hit such cases so we remain very strict on testing here. run: | scripts/run_in_build_env.sh './scripts/build_python.sh --install_virtual_env out/venv' ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py \ - --target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test \ + --target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test-data-model-check-check-failure-die \ --target linux-x64-lock-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-lit-icd-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-energy-management-ipv6only-no-ble-no-wifi-tsan-clang-test \ @@ -496,7 +502,7 @@ jobs: - name: Generate an argument environment file run: | echo -n "" >/tmp/test_env.yaml - echo "ALL_CLUSTERS_APP: out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app" >> /tmp/test_env.yaml + echo "ALL_CLUSTERS_APP: out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test-data-model-check-check-failure-die/chip-all-clusters-app" >> /tmp/test_env.yaml echo "CHIP_LOCK_APP: out/linux-x64-lock-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-lock-app" >> /tmp/test_env.yaml echo "ENERGY_MANAGEMENT_APP: out/linux-x64-energy-management-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-energy-management-app" >> /tmp/test_env.yaml echo "LIT_ICD_APP: out/linux-x64-lit-icd-ipv6only-no-ble-no-wifi-tsan-clang-test/lit-icd-app" >> /tmp/test_env.yaml @@ -515,7 +521,7 @@ jobs: mkdir -p out/trace_data scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/controller/python/test/test_scripts/mobile-device-test.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/execute_python_tests.py --env-file /tmp/test_env.yaml --search-directory src/python_testing' - scripts/run_in_python_env.sh out/venv './scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py --all-clusters out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test-data-model-check-check-failure-die/chip-all-clusters-app' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingDeviceType.py' 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 1f8bc5463d8a9d..9769afdc262ba0 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 @@ -7307,6 +7307,8 @@ internal cluster UnitTesting = 4294048773 { attribute TestGlobalEnum globalEnum = 51; attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; + attribute optional int8u readFailureCode = 12288; + attribute optional int32u failureInt32U = 12289; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; attribute nullable Bitmap16MaskMap nullableBitmap16 = 16386; @@ -9546,6 +9548,8 @@ endpoint 1 { callback attribute clusterErrorBoolean; ram attribute globalEnum; callback attribute globalStruct; + ram attribute readFailureCode default = 1; + callback attribute failureInt32U default = 0; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; 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 00f525cf1710ae..0140adbbd9a461 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 @@ -23327,6 +23327,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "readFailureCode", + "code": 12288, + "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": "failureInt32U", + "code": 12289, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index 42df91b845a610..b62d154f0d58f7 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -21,6 +21,7 @@ #include "ValveControlDelegate.h" #include "WindowCoveringManager.h" #include "air-quality-instance.h" +#include "app-common/zap-generated/ids/Clusters.h" #include "device-energy-management-modes.h" #include "dishwasher-mode.h" #include "energy-evse-modes.h" @@ -39,6 +40,7 @@ #include "tcc-mode.h" #include "thermostat-delegate-impl.h" #include "water-heater-mode.h" + #include #include #include @@ -54,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -72,6 +73,8 @@ using namespace chip; using namespace chip::app; using namespace chip::DeviceLayer; +using chip::Protocols::InteractionModel::Status; + namespace { constexpr char kChipEventFifoPathPrefix[] = "/tmp/chip_all_clusters_fifo_"; @@ -336,3 +339,28 @@ void emberAfThermostatClusterInitCallback(EndpointId endpoint) SetDefaultDelegate(endpoint, &delegate); } + +Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, + uint16_t maxReadLength) +{ + + VerifyOrReturnValue(clusterId == Clusters::UnitTesting::Id, Status::Failure); + VerifyOrReturnValue(attributeMetadata != nullptr, Status::Failure); + + if (attributeMetadata->attributeId == Clusters::UnitTesting::Attributes::FailureInt32U::Id) + { + uint8_t forced_code = 0; + Status status; + + status = Clusters::UnitTesting::Attributes::ReadFailureCode::Get(endpoint, &forced_code); + if (status == Status::Success) + { + status = static_cast(forced_code); + } + return status; + } + + // Finally we just do not support external attributes in all-clusters at this point + return Status::Failure; +} diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 49be7047972beb..9424fab0a17c1c 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -5898,6 +5898,8 @@ internal cluster UnitTesting = 4294048773 { attribute TestGlobalEnum globalEnum = 51; attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; + attribute optional int8u readFailureCode = 12288; + attribute optional int32u failureInt32U = 12289; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; attribute nullable Bitmap16MaskMap nullableBitmap16 = 16386; diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index d10dce747c4695..830abb4079edae 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -1908,6 +1908,8 @@ internal cluster UnitTesting = 4294048773 { attribute TestGlobalEnum globalEnum = 51; attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; + attribute optional int8u readFailureCode = 12288; + attribute optional int32u failureInt32U = 12289; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; attribute nullable Bitmap16MaskMap nullableBitmap16 = 16386; diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 378a286f5bf5a4..7cd7c157a54403 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -196,6 +196,7 @@ def BuildHostTarget(): target.AppendModifier('data-model-check', data_model_interface="check").ExceptIfRe('-data-model-(enabled|disabled)') target.AppendModifier('data-model-disabled', data_model_interface="disabled").ExceptIfRe('-data-model-(check|enabled)') target.AppendModifier('data-model-enabled', data_model_interface="enabled").ExceptIfRe('-data-model-(check|disabled)') + target.AppendModifier('check-failure-die', data_model_interface="enabled").OnlyIfRe('-data-model-check') return target diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 01b35c7a01185f..12d21fbe8ba62e 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -323,6 +323,7 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, enable_dnssd_tests: Optional[bool] = None, chip_casting_simplified: Optional[bool] = None, data_model_interface: Optional[bool] = None, + chip_data_model_check_die_on_failure: Optional[bool] = None, ): super(HostBuilder, self).__init__( root=os.path.join(root, 'examples', app.ExamplePath()), @@ -421,6 +422,11 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, self.extra_gn_options.append('chip_build_tests=true') self.extra_gn_options.append('chip_data_model_check_die_on_failure=true') self.build_command = 'check' + elif chip_data_model_check_die_on_failure is not None: + if chip_data_model_check_die_on_failure: + self.extra_gn_options.append('chip_data_model_check_die_on_failure=true') + else: + self.extra_gn_options.append('chip_data_model_check_die_on_failure=false') if app == HostApp.EFR32_TEST_RUNNER: self.build_command = 'runner' diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 07b409c75b3b53..6639429b31bb75 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -9,7 +9,7 @@ efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,b esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing] genio-lighting-app linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang] -linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled] +linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled][-check-failure-die] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] diff --git a/scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py b/scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py index 32f0b9bf61a2cf..567bf146c7b772 100755 --- a/scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py +++ b/scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import argparse import logging import os import signal @@ -21,30 +22,32 @@ import sys import time -DEFAULT_CHIP_ROOT = os.path.abspath( - os.path.join(os.path.dirname(__file__), '..', '..')) +DEFAULT_CHIP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) + +DEFAULT_ALL_CLUSTERS = os.path.join( + DEFAULT_CHIP_ROOT, + 'out', + 'linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test', + 'chip-all-clusters-app') +DEFAULT_TEST_RUNNER = os.path.join(DEFAULT_CHIP_ROOT, 'scripts', 'tests', 'run_python_test.py') +DEFAULT_TEST_SCRIPT = os.path.join(DEFAULT_CHIP_ROOT, 'src', 'python_testing', 'TestTimeSyncTrustedTimeSource.py') class TestDriver: - def __init__(self): - self.app_path = os.path.abspath(os.path.join(DEFAULT_CHIP_ROOT, 'out', - 'linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test', 'chip-all-clusters-app')) - self.run_python_test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'run_python_test.py')) + def __init__(self, all_clusters: str, test_runner: str, test_script: str): + self.app_path = all_clusters + self.run_python_test_path = test_runner + self.script_path = test_script - self.script_path = os.path.abspath(os.path.join( - DEFAULT_CHIP_ROOT, 'src', 'python_testing', 'TestTimeSyncTrustedTimeSource.py')) if not os.path.exists(self.app_path): - msg = 'chip-all-clusters-app not found' - logging.error(msg) - raise FileNotFoundError(msg) + logging.error('%s not found', self.app_path) + raise FileNotFoundError(self.app_path) if not os.path.exists(self.run_python_test_path): - msg = 'run_python_test.py script not found' - logging.error(msg) - raise FileNotFoundError(msg) + logging.error('%s not found', self.run_python_test_path) + raise FileNotFoundError(self.run_python_test_path) if not os.path.exists(self.script_path): - msg = 'TestTimeSyncTrustedTimeSource.py script not found' - logging.error(msg) - raise FileNotFoundError(msg) + logging.error('%s not found', self.script_path) + raise FileNotFoundError(self.script_path) def get_base_run_python_cmd(self, run_python_test_path, app_path, app_args, script_path, script_args): return f'{str(run_python_test_path)} --app {str(app_path)} --app-args "{app_args}" --script {str(script_path)} --script-args "{script_args}"' @@ -78,7 +81,17 @@ def main(): base_script_args = '--storage-path admin_storage.json --discriminator 1234 --passcode 20202021' script_args = base_script_args + ' --commissioning-method on-network --commission-only' - driver = TestDriver() + parser = argparse.ArgumentParser('TimeSyncTrustedTimeSource runner', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--all-clusters', default=DEFAULT_ALL_CLUSTERS, help="All clusters application.") + parser.add_argument('--test-runner', default=DEFAULT_TEST_RUNNER, help="the run_python_test.py script.") + parser.add_argument('--test-script', default=DEFAULT_TEST_SCRIPT, help="The path to the TimeSyncTrustedTimeSource test.") + args = parser.parse_args() + + driver = TestDriver( + all_clusters=args.all_clusters, + test_runner=args.test_runner, + test_script=args.test_script, + ) ret = driver.run_test_section(app_args, script_args, factory_reset_all=True) if ret != 0: return ret diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 7dadac8695fd63..00f06dd32a858d 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -329,6 +329,21 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b } // Read attribute using Ember, if it doesn't have an override. + + EmberAfAttributeSearchRecord record; + record.endpoint = aPath.mEndpointId; + record.clusterId = aPath.mClusterId; + record.attributeId = aPath.mAttributeId; + Status status = emAfReadOrWriteAttribute(&record, &attributeMetadata, gEmberAttributeIOBufferSpan.data(), + static_cast(gEmberAttributeIOBufferSpan.size()), + /* write = */ false); + + if (status != Status::Success) + { + return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); + } + + // data available, return the corresponding record AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport(); ReturnErrorOnFailure(aAttributeReports.GetError()); @@ -349,19 +364,6 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b .EndOfAttributePathIB(); ReturnErrorOnFailure(err); - EmberAfAttributeSearchRecord record; - record.endpoint = aPath.mEndpointId; - record.clusterId = aPath.mClusterId; - record.attributeId = aPath.mAttributeId; - Status status = emAfReadOrWriteAttribute(&record, &attributeMetadata, gEmberAttributeIOBufferSpan.data(), - static_cast(gEmberAttributeIOBufferSpan.size()), - /* write = */ false); - - if (status != Status::Success) - { - return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); - } - TLV::TLVWriter * writer = attributeDataIBBuilder.GetWriter(); VerifyOrReturnError(writer != nullptr, CHIP_NO_ERROR); diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index c289ee9f1c4338..258c7cba5106df 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -203,6 +203,14 @@ limitations under the License. global_enum global_struct + + readFailureCode + failureInt32U + + nullable_boolean nullable_bitmap8 nullable_bitmap16 diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 42086a2caa93c5..cbe81c4d2e6a04 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9809,6 +9809,8 @@ internal cluster UnitTesting = 4294048773 { attribute TestGlobalEnum globalEnum = 51; attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; + attribute optional int8u readFailureCode = 12288; + attribute optional int32u failureInt32U = 12289; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; attribute nullable Bitmap16MaskMap nullableBitmap16 = 16386; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index fd792a14bb2e4f..9001413960dff3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -65170,6 +65170,8 @@ public static class UnitTestingCluster extends BaseChipCluster { private static final long GLOBAL_ENUM_ATTRIBUTE_ID = 51L; private static final long GLOBAL_STRUCT_ATTRIBUTE_ID = 52L; private static final long UNSUPPORTED_ATTRIBUTE_ID = 255L; + private static final long READ_FAILURE_CODE_ATTRIBUTE_ID = 12288L; + private static final long FAILURE_INT32_U_ATTRIBUTE_ID = 12289L; private static final long NULLABLE_BOOLEAN_ATTRIBUTE_ID = 16384L; private static final long NULLABLE_BITMAP8_ATTRIBUTE_ID = 16385L; private static final long NULLABLE_BITMAP16_ATTRIBUTE_ID = 16386L; @@ -68330,6 +68332,76 @@ public void onSuccess(byte[] tlv) { }, UNSUPPORTED_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readReadFailureCodeAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, READ_FAILURE_CODE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, READ_FAILURE_CODE_ATTRIBUTE_ID, true); + } + + public void writeReadFailureCodeAttribute(DefaultClusterCallback callback, Integer value) { + writeReadFailureCodeAttribute(callback, value, 0); + } + + public void writeReadFailureCodeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), READ_FAILURE_CODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeReadFailureCodeAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, READ_FAILURE_CODE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, READ_FAILURE_CODE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFailureInt32UAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FAILURE_INT32_U_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FAILURE_INT32_U_ATTRIBUTE_ID, true); + } + + public void writeFailureInt32UAttribute(DefaultClusterCallback callback, Long value) { + writeFailureInt32UAttribute(callback, value, 0); + } + + public void writeFailureInt32UAttribute(DefaultClusterCallback callback, Long value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), FAILURE_INT32_U_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeFailureInt32UAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FAILURE_INT32_U_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FAILURE_INT32_U_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readNullableBooleanAttribute( NullableBooleanAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_BOOLEAN_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index b48f4029b62237..e0099ccf4c87dc 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -17775,6 +17775,8 @@ public enum Attribute { GlobalEnum(51L), GlobalStruct(52L), Unsupported(255L), + ReadFailureCode(12288L), + FailureInt32U(12289L), NullableBoolean(16384L), NullableBitmap8(16385L), NullableBitmap16(16386L), diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 6baa71c6886c6e..b09c89302d33b6 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -20857,6 +20857,28 @@ private static Map readUnitTestingInteractionInfo() { readUnitTestingUnsupportedCommandParams ); result.put("readUnsupportedAttribute", readUnitTestingUnsupportedAttributeInteractionInfo); + Map readUnitTestingReadFailureCodeCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingReadFailureCodeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readReadFailureCodeAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readUnitTestingReadFailureCodeCommandParams + ); + result.put("readReadFailureCodeAttribute", readUnitTestingReadFailureCodeAttributeInteractionInfo); + Map readUnitTestingFailureInt32UCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingFailureInt32UAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readFailureInt32UAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readUnitTestingFailureInt32UCommandParams + ); + result.put("readFailureInt32UAttribute", readUnitTestingFailureInt32UAttributeInteractionInfo); Map readUnitTestingNullableBooleanCommandParams = new LinkedHashMap(); InteractionInfo readUnitTestingNullableBooleanAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 93a48d76bf61dc..0a59b42a9ffe34 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -4871,6 +4871,50 @@ public Map> getWriteAttributeMap() { writeUnitTestingUnsupportedCommandParams ); writeUnitTestingInteractionInfo.put("writeUnsupportedAttribute", writeUnitTestingUnsupportedAttributeInteractionInfo); + Map writeUnitTestingReadFailureCodeCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingreadFailureCodeCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeUnitTestingReadFailureCodeCommandParams.put( + "value", + unitTestingreadFailureCodeCommandParameterInfo + ); + InteractionInfo writeUnitTestingReadFailureCodeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeReadFailureCodeAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingReadFailureCodeCommandParams + ); + writeUnitTestingInteractionInfo.put("writeReadFailureCodeAttribute", writeUnitTestingReadFailureCodeAttributeInteractionInfo); + Map writeUnitTestingFailureInt32UCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingfailureInt32UCommandParameterInfo = + new CommandParameterInfo( + "value", + Long.class, + Long.class + ); + writeUnitTestingFailureInt32UCommandParams.put( + "value", + unitTestingfailureInt32UCommandParameterInfo + ); + InteractionInfo writeUnitTestingFailureInt32UAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeFailureInt32UAttribute( + (DefaultClusterCallback) callback, + (Long) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingFailureInt32UCommandParams + ); + writeUnitTestingInteractionInfo.put("writeFailureInt32UAttribute", writeUnitTestingFailureInt32UAttributeInteractionInfo); Map writeUnitTestingNullableBooleanCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingnullableBooleanCommandParameterInfo = new CommandParameterInfo( diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt index 74402b19dcfdf3..c48686cd74599a 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt @@ -8779,6 +8779,270 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } + suspend fun readReadFailureCodeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 12288u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Readfailurecode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeReadFailureCodeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 12288u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeReadFailureCodeAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 12288u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Readfailurecode attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFailureInt32UAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 12289u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Failureint32u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeFailureInt32UAttribute(value: UInt, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 12289u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeFailureInt32UAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 12289u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Failureint32u attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UIntSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { val ATTRIBUTE_ID: UInt = 16384u diff --git a/src/controller/java/src/matter/controller/ICDClientInfo.kt b/src/controller/java/src/matter/controller/ICDClientInfo.kt index a1c543a044bacc..9ad3757ad32d28 100644 --- a/src/controller/java/src/matter/controller/ICDClientInfo.kt +++ b/src/controller/java/src/matter/controller/ICDClientInfo.kt @@ -28,5 +28,6 @@ data class ICDClientInfo( val icdAesKey: ByteArray, val icdHmacKey: ByteArray ) { - override fun toString(): String = "$peerNodeId/$checkInNodeId/$startCounter/$offset/$monitoredSubject" + override fun toString(): String = + "$peerNodeId/$checkInNodeId/$startCounter/$offset/$monitoredSubject" } diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index b6f8a6364105c0..771d026771d39d 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -47560,6 +47560,38 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } + case Attributes::ReadFailureCode::Id: { + using TypeInfo = Attributes::ReadFailureCode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::FailureInt32U::Id: { + using TypeInfo = Attributes::FailureInt32U::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } case Attributes::NullableBoolean::Id: { using TypeInfo = Attributes::NullableBoolean::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 356d3b43569ea2..a26555e58dd517 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -14837,6 +14837,20 @@ class ChipClusters: "reportable": True, "writable": True, }, + 0x00003000: { + "attributeName": "ReadFailureCode", + "attributeId": 0x00003000, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00003001: { + "attributeName": "FailureInt32U", + "attributeId": 0x00003001, + "type": "int", + "reportable": True, + "writable": True, + }, 0x00004000: { "attributeName": "NullableBoolean", "attributeId": 0x00004000, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index a5988bbf54e71a..482fe33f61c2c1 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -50211,6 +50211,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="globalEnum", Tag=0x00000033, Type=Globals.Enums.TestGlobalEnum), ClusterObjectFieldDescriptor(Label="globalStruct", Tag=0x00000034, Type=Globals.Structs.TestGlobalStruct), ClusterObjectFieldDescriptor(Label="unsupported", Tag=0x000000FF, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="readFailureCode", Tag=0x00003000, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="failureInt32U", Tag=0x00003001, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="nullableBoolean", Tag=0x00004000, Type=typing.Union[Nullable, bool]), ClusterObjectFieldDescriptor(Label="nullableBitmap8", Tag=0x00004001, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="nullableBitmap16", Tag=0x00004002, Type=typing.Union[Nullable, uint]), @@ -50306,6 +50308,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: globalEnum: 'Globals.Enums.TestGlobalEnum' = None globalStruct: 'Globals.Structs.TestGlobalStruct' = None unsupported: 'typing.Optional[bool]' = None + readFailureCode: 'typing.Optional[uint]' = None + failureInt32U: 'typing.Optional[uint]' = None nullableBoolean: 'typing.Union[Nullable, bool]' = None nullableBitmap8: 'typing.Union[Nullable, uint]' = None nullableBitmap16: 'typing.Union[Nullable, uint]' = None @@ -52151,6 +52155,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[bool]' = None + @dataclass + class ReadFailureCode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00003000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class FailureInt32U(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00003001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + @dataclass class NullableBoolean(ClusterAttributeDescriptor): @ChipUtility.classproperty diff --git a/src/controller/python/test/test_scripts/cluster_objects.py b/src/controller/python/test/test_scripts/cluster_objects.py index 37f6819cbe66a4..10c2ad2e268c30 100644 --- a/src/controller/python/test/test_scripts/cluster_objects.py +++ b/src/controller/python/test/test_scripts/cluster_objects.py @@ -38,6 +38,8 @@ Clusters.Objects.UnitTesting.Attributes.GeneralErrorBoolean), (1, Clusters.Objects.UnitTesting, Clusters.Objects.UnitTesting.Attributes.ClusterErrorBoolean), + (1, Clusters.Objects.UnitTesting, + Clusters.Objects.UnitTesting.Attributes.FailureInt32U), ] diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 3f8df9ea33d334..b2da0cf9db04ad 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -6684,6 +6684,12 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::Unsupported::Id: { return YES; } + case Attributes::ReadFailureCode::Id: { + return YES; + } + case Attributes::FailureInt32U::Id: { + return YES; + } case Attributes::NullableBoolean::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index f26c5e29e39bf8..de61e4dd22cf7d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -19717,6 +19717,28 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value = [NSNumber numberWithBool:cppValue]; return value; } + case Attributes::ReadFailureCode::Id: { + using TypeInfo = Attributes::ReadFailureCode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + case Attributes::FailureInt32U::Id: { + using TypeInfo = Attributes::FailureInt32U::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedInt:cppValue]; + return value; + } case Attributes::NullableBoolean::Id: { using TypeInfo = Attributes::NullableBoolean::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index bedf8161036583..9360e68c590fcd 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -16729,6 +16729,22 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeUnsupportedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeReadFailureCodeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeReadFailureCodeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeReadFailureCodeWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeReadFailureCodeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeReadFailureCodeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFailureInt32UWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeFailureInt32UWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeFailureInt32UWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFailureInt32UWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFailureInt32UWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeNullableBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 453ec72508abce..696d1f8058b3ed 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -120041,6 +120041,134 @@ + (void)readAttributeUnsupportedWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } +- (void)readAttributeReadFailureCodeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::ReadFailureCode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeReadFailureCodeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeReadFailureCodeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeReadFailureCodeWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::ReadFailureCode::TypeInfo; + TypeInfo::Type cppValue; + cppValue = value.unsignedCharValue; + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeReadFailureCodeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::ReadFailureCode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeReadFailureCodeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::ReadFailureCode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFailureInt32UWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::FailureInt32U::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeFailureInt32UWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeFailureInt32UWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeFailureInt32UWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::FailureInt32U::TypeInfo; + TypeInfo::Type cppValue; + cppValue = value.unsignedIntValue; + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeFailureInt32UWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::FailureInt32U::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFailureInt32UWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::FailureInt32U::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeNullableBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitTesting::Attributes::NullableBoolean::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 3ceca84ced8163..1ffa3ecc58db7a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -5766,6 +5766,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID MTR_PROVISIONALLY_AVAILABLE = 0x00000033, MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00000034, MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x000000FF, + MTRAttributeIDTypeClusterUnitTestingAttributeReadFailureCodeID MTR_PROVISIONALLY_AVAILABLE = 0x00003000, + MTRAttributeIDTypeClusterUnitTestingAttributeFailureInt32UID MTR_PROVISIONALLY_AVAILABLE = 0x00003001, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004000, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBitmap8ID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004001, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBitmap16ID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004002, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 894f8399c7e3c7..69ec92c0e5217a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -9171,6 +9171,14 @@ result = @"Unsupported"; break; + case MTRAttributeIDTypeClusterUnitTestingAttributeReadFailureCodeID: + result = @"ReadFailureCode"; + break; + + case MTRAttributeIDTypeClusterUnitTestingAttributeFailureInt32UID: + result = @"FailureInt32U"; + break; + case MTRAttributeIDTypeClusterUnitTestingAttributeNullableBooleanID: result = @"NullableBoolean"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index b4153ecf56db86..a717868edf09fc 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -7648,6 +7648,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeReadFailureCodeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeReadFailureCodeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeReadFailureCodeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFailureInt32UWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeFailureInt32UWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeFailureInt32UWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeNullableBooleanWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNullableBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNullableBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 780c3a49d70521..6f6db16eb72210 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -22543,6 +22543,38 @@ - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataV [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } +- (NSDictionary * _Nullable)readAttributeReadFailureCodeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeReadFailureCodeID) params:params]; +} + +- (void)writeAttributeReadFailureCodeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeReadFailureCodeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeReadFailureCodeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeReadFailureCodeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeFailureInt32UWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeFailureInt32UID) params:params]; +} + +- (void)writeAttributeFailureInt32UWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeFailureInt32UWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeFailureInt32UWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeFailureInt32UID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeNullableBooleanWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableBooleanID) params:params]; diff --git a/src/python_testing/TestUnitTestingErrorPath.py b/src/python_testing/TestUnitTestingErrorPath.py new file mode 100644 index 00000000000000..c26e6afc13229b --- /dev/null +++ b/src/python_testing/TestUnitTestingErrorPath.py @@ -0,0 +1,102 @@ +# +# 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. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + +""" Integration test for error path returns via the UnitTesting cluster. +""" + + +class TestUnitTestingErrorPath(MatterBaseTest): + + @async_test_body + async def test_unit_test_error_read(self): + endpoint_id = 1 + attributes = Clusters.UnitTesting.Attributes + + self.print_step(0, "Commissioning - already done") + + self.print_step(1, "Set error to 'Failure' for all subsequent reads of FailureInt32U.") + await self.default_controller.WriteAttribute( + nodeid=self.dut_node_id, + attributes=[(endpoint_id, attributes.ReadFailureCode(int(Status.Failure)))], + ) + + self.print_step(2, "Expect that reading FailureInt32U returns the previously set 'Failure' code.") + try: + data = await self.default_controller.ReadAttribute( + self.dut_node_id, [(endpoint_id, attributes.FailureInt32U)] + ) + result = data[endpoint_id][Clusters.UnitTesting][attributes.FailureInt32U] + + asserts.assert_true( + isinstance(result, Clusters.Attribute.ValueDecodeFailure), + "Expect a decode error for reading the failure attribute" + ) + asserts.assert_equal(result.Reason.status, Status.Failure, "Failure state is the default for the failure read.") + except InteractionModelError: + asserts.fail("Failure reading") + + self.print_step(3, "Set error to 'ResourceExhausted' for all subsequent reads of FailureInt32U.") + await self.default_controller.WriteAttribute( + nodeid=self.dut_node_id, + attributes=[(endpoint_id, attributes.ReadFailureCode(int(Status.ResourceExhausted)))], + ) + + self.print_step(4, "Expect that reading FailureInt32U returns the previously set 'ResourceExhausted' code.") + try: + data = await self.default_controller.ReadAttribute( + self.dut_node_id, [(endpoint_id, attributes.FailureInt32U)] + ) + result = data[endpoint_id][Clusters.UnitTesting][attributes.FailureInt32U] + + asserts.assert_true( + isinstance(result, Clusters.Attribute.ValueDecodeFailure), + "Expect a decode error for reading the failure attribute" + ) + asserts.assert_true(result.Reason.status, Status.ResourceExhausted, "Set failure is ResourceExhausted") + except InteractionModelError: + asserts.fail("Failure reading") + + self.print_step(5, "Reset ReadFailureCode error to default 'Failure' code.") + await self.default_controller.WriteAttribute( + nodeid=self.dut_node_id, + attributes=[(1, attributes.ReadFailureCode(int(Status.Failure)))], + ) + + logging.info("Test completed") + + +if __name__ == "__main__": + default_matter_test_main() 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 ebd5339fd079a7..ed3e70fb6c9d1a 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 @@ -45518,6 +45518,98 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) } // namespace Unsupported +namespace ReadFailureCode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +} // namespace ReadFailureCode + +namespace FailureInt32U { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +} // namespace FailureInt32U + namespace NullableBoolean { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) 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 5537692d6908d4..80b542dbf0c190 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 @@ -6904,6 +6904,18 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace Unsupported +namespace ReadFailureCode { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +} // namespace ReadFailureCode + +namespace FailureInt32U { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // int32u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FailureInt32U + namespace NullableBoolean { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // boolean Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 4be7782087f3d6..354eb75feb77de 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -31889,6 +31889,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, globalStruct); case Attributes::Unsupported::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, unsupported); + case Attributes::ReadFailureCode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, readFailureCode); + case Attributes::FailureInt32U::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, failureInt32U); case Attributes::NullableBoolean::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, nullableBoolean); case Attributes::NullableBitmap8::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 78022f3ac6ce11..e96a078ea28f58 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -46794,6 +46794,30 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace Unsupported +namespace ReadFailureCode { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ReadFailureCode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ReadFailureCode +namespace FailureInt32U { +struct TypeInfo +{ + using Type = uint32_t; + using DecodableType = uint32_t; + using DecodableArgType = uint32_t; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::FailureInt32U::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace FailureInt32U namespace NullableBoolean { struct TypeInfo { @@ -47344,7 +47368,9 @@ struct TypeInfo Attributes::ClusterErrorBoolean::TypeInfo::DecodableType clusterErrorBoolean = static_cast(0); Attributes::GlobalEnum::TypeInfo::DecodableType globalEnum = static_cast(0); Attributes::GlobalStruct::TypeInfo::DecodableType globalStruct; - Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); + Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); + Attributes::ReadFailureCode::TypeInfo::DecodableType readFailureCode = static_cast(0); + Attributes::FailureInt32U::TypeInfo::DecodableType failureInt32U = static_cast(0); Attributes::NullableBoolean::TypeInfo::DecodableType nullableBoolean; Attributes::NullableBitmap8::TypeInfo::DecodableType nullableBitmap8; Attributes::NullableBitmap16::TypeInfo::DecodableType nullableBitmap16; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 6cb26b63d9912c..6e19a4c970df77 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -8304,6 +8304,14 @@ namespace Unsupported { static constexpr AttributeId Id = 0x000000FF; } // namespace Unsupported +namespace ReadFailureCode { +static constexpr AttributeId Id = 0x00003000; +} // namespace ReadFailureCode + +namespace FailureInt32U { +static constexpr AttributeId Id = 0x00003001; +} // namespace FailureInt32U + namespace NullableBoolean { static constexpr AttributeId Id = 0x00004000; } // namespace NullableBoolean diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index f50b5721bce5d5..5e6f77d66bde82 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -14222,6 +14222,8 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * GlobalEnum | 0x0033 | | * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | +| * ReadFailureCode | 0x3000 | +| * FailureInt32U | 0x3001 | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | | * NullableBitmap16 | 0x4002 | @@ -27702,6 +27704,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // + make_unique(Id, "read-failure-code", Attributes::ReadFailureCode::Id, credsIssuerConfig), // + make_unique(Id, "failure-int32u", Attributes::FailureInt32U::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap16", Attributes::NullableBitmap16::Id, credsIssuerConfig), // @@ -27856,6 +27860,10 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * Id, "global-struct", Attributes::GlobalStruct::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "unsupported", 0, 1, Attributes::Unsupported::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>(Id, "read-failure-code", 0, UINT8_MAX, Attributes::ReadFailureCode::Id, + WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>(Id, "failure-int32u", 0, UINT32_MAX, Attributes::FailureInt32U::Id, + WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "nullable-boolean", 0, 1, Attributes::NullableBoolean::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique< @@ -28021,6 +28029,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // + make_unique(Id, "read-failure-code", Attributes::ReadFailureCode::Id, credsIssuerConfig), // + make_unique(Id, "failure-int32u", Attributes::FailureInt32U::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap16", Attributes::NullableBitmap16::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 0efe192f7b59aa..b61e6e9bae9232 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -19189,6 +19189,16 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("unsupported", 1, value); } + case UnitTesting::Attributes::ReadFailureCode::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("readFailureCode", 1, value); + } + case UnitTesting::Attributes::FailureInt32U::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("failureInt32U", 1, value); + } case UnitTesting::Attributes::NullableBoolean::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index 3909bbec0d8746..07bac4319c7c61 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -4904,6 +4904,10 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GlobalStruct"; case chip::app::Clusters::UnitTesting::Attributes::Unsupported::Id: return "Unsupported"; + case chip::app::Clusters::UnitTesting::Attributes::ReadFailureCode::Id: + return "ReadFailureCode"; + case chip::app::Clusters::UnitTesting::Attributes::FailureInt32U::Id: + return "FailureInt32U"; case chip::app::Clusters::UnitTesting::Attributes::NullableBoolean::Id: return "NullableBoolean"; case chip::app::Clusters::UnitTesting::Attributes::NullableBitmap8::Id: diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index a77ea1f918b90b..7fdfb6f9689c01 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -177044,6 +177044,8 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * GlobalEnum | 0x0033 | | * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | +| * ReadFailureCode | 0x3000 | +| * FailureInt32U | 0x3001 | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | | * NullableBitmap16 | 0x4002 | @@ -185567,6 +185569,259 @@ class SubscribeAttributeUnitTestingUnsupported : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ReadFailureCode + */ +class ReadUnitTestingReadFailureCode : public ReadAttribute { +public: + ReadUnitTestingReadFailureCode() + : ReadAttribute("read-failure-code") + { + } + + ~ReadUnitTestingReadFailureCode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::ReadFailureCode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeReadFailureCodeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.ReadFailureCode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting ReadFailureCode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingReadFailureCode : public WriteAttribute { +public: + WriteUnitTestingReadFailureCode() + : WriteAttribute("read-failure-code") + { + AddArgument("attr-name", "read-failure-code"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingReadFailureCode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::ReadFailureCode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue]; + + [cluster writeAttributeReadFailureCodeWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting ReadFailureCode write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint8_t mValue; +}; + +class SubscribeAttributeUnitTestingReadFailureCode : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingReadFailureCode() + : SubscribeAttribute("read-failure-code") + { + } + + ~SubscribeAttributeUnitTestingReadFailureCode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::ReadFailureCode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeReadFailureCodeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.ReadFailureCode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FailureInt32U + */ +class ReadUnitTestingFailureInt32U : public ReadAttribute { +public: + ReadUnitTestingFailureInt32U() + : ReadAttribute("failure-int32u") + { + } + + ~ReadUnitTestingFailureInt32U() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::FailureInt32U::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFailureInt32UWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.FailureInt32U response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting FailureInt32U read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingFailureInt32U : public WriteAttribute { +public: + WriteUnitTestingFailureInt32U() + : WriteAttribute("failure-int32u") + { + AddArgument("attr-name", "failure-int32u"); + AddArgument("attr-value", 0, UINT32_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingFailureInt32U() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::FailureInt32U::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue]; + + [cluster writeAttributeFailureInt32UWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting FailureInt32U write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint32_t mValue; +}; + +class SubscribeAttributeUnitTestingFailureInt32U : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingFailureInt32U() + : SubscribeAttribute("failure-int32u") + { + } + + ~SubscribeAttributeUnitTestingFailureInt32U() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::FailureInt32U::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFailureInt32UWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.FailureInt32U response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute NullableBoolean */ @@ -198971,6 +199226,16 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // From f02df8965089a2e893123b643ccbc42e2d11ea04 Mon Sep 17 00:00:00 2001 From: Harshith-GRL <145322529+Harshith-GRL@users.noreply.github.com> Date: Thu, 5 Sep 2024 03:06:25 +0530 Subject: [PATCH 59/70] Updated DoorLock Python scripts and DRLK_2_1 yaml. (#35182) * Updated DoorLock Python scripts and DRLK_2_1 yaml. * TC_DRLK_2_X.py - updated as per latest test plan * TC_BOOLCFG_3_1.py - Test description is changed. * TC_PWRTL_2_1.py - Added missing step for subset check as per latest test plan. * Test_TC_DRLK_2_1.yaml - Script is updated with latest changes from test plan. * Restyled by whitespace * Restyled by prettier-yaml * Restyled by autopep8 * Lint errors are fixed * ednpoint will be taken from command line args * Teardown function added for all scripts --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_DRLK_2_1.yaml | 192 ++++++++---------- src/python_testing/TC_BOOLCFG_3_1.py | 2 +- src/python_testing/TC_DRLK_2_12.py | 7 +- src/python_testing/TC_DRLK_2_13.py | 4 +- src/python_testing/TC_DRLK_2_2.py | 7 +- src/python_testing/TC_DRLK_2_3.py | 7 +- src/python_testing/TC_PWRTL_2_1.py | 19 +- src/python_testing/drlk_2_x_common.py | 178 +++++++++------- 8 files changed, 223 insertions(+), 193 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml index 38465c434078bb..8954d44a658d97 100755 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml @@ -35,8 +35,35 @@ tests: - name: "nodeId" value: nodeId - - label: "Precondition: Create new user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: "Step 1a: TH reads LockState attribute from DUT" + PICS: DRLK.S.A0000 + command: "readAttribute" + attribute: "LockState" + response: + saveAs: LockStateValue + constraints: + type: enum8 + minValue: 0 + maxValue: 3 + + - label: "Step 1b: TH writes LockState attribute as 1" + PICS: DRLK.S.A0000 + command: "writeAttribute" + attribute: "LockState" + arguments: + value: 1 + response: + error: UNSUPPORTED_WRITE + + - label: "Step 1c: TH reads LockState attribute from DUT" + PICS: DRLK.S.A0000 + command: "readAttribute" + attribute: "LockState" + response: + value: LockStateValue + + - label: "Step 1d: TH sends SetUser Command to DUT" + PICS: DRLK.S.F08 && DRLK.S.C1a.Rsp command: "SetUser" timedInteractionTimeoutMs: 1000 arguments: @@ -56,38 +83,34 @@ tests: - name: "CredentialRule" value: 0 - - label: "Precondition: Read the user back and verify its fields" - PICS: DRLK.S.F00 && DRLK.S.F07 - command: "GetUser" - arguments: - values: - - name: "UserIndex" - value: 1 + - label: + "Step 1e: TH reads MinPINCodeLength attribute and saves the value as + min_pin_code_length" + PICS: DRLK.S.F08 && DRLK.S.F00 + command: "readAttribute" + attribute: "MinPINCodeLength" response: - values: - - name: "UserIndex" - value: 1 - - name: "UserName" - value: "xxx" - - name: "UserUniqueID" - value: 6452 - - name: "UserStatus" - value: 1 - - name: "UserType" - value: 0 - - name: "CredentialRule" - value: 0 - - name: "Credentials" - value: [] - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextUserIndex" - value: null + saveAs: min_pin_code_length + constraints: + type: int8u + minValue: 0 + maxValue: 255 - - label: "Precondition: Create new PIN credential and lock/unlock user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: + "Step 1f: TH reads MaxPINCodeLength attribute and saves the value as + max_pin_code_length" + PICS: DRLK.S.F08 && DRLK.S.F00 + command: "readAttribute" + attribute: "MaxPINCodeLength" + response: + saveAs: max_pin_code_length + constraints: + type: int8u + minValue: 0 + maxValue: 255 + + - label: "Step 1g: TH sends SetCredential Command" + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C22.Rsp && DRLK.S.C23.Tx command: "SetCredential" timedInteractionTimeoutMs: 1000 arguments: @@ -104,64 +127,9 @@ tests: value: null - name: "UserType" value: null - response: - values: - - name: "Status" - value: 0 - - name: "UserIndex" - value: null - - name: "NextCredentialIndex" - value: 2 - - - label: "Precondition: Verify created PIN credential" - PICS: DRLK.S.F00 && DRLK.S.F07 - command: "GetCredentialStatus" - arguments: - values: - - name: "Credential" - value: { CredentialType: 1, CredentialIndex: 1 } - response: - values: - - name: "CredentialExists" - value: true - - name: "UserIndex" - value: 1 - - name: "CreatorFabricIndex" - value: 1 - - name: "LastModifiedFabricIndex" - value: 1 - - name: "NextCredentialIndex" - value: null - - - label: "Step 1a: TH reads LockState attribute from DUT" - PICS: DRLK.S.A0000 - command: "readAttribute" - attribute: "LockState" - response: - saveAs: LockStateValue - constraints: - type: enum8 - minValue: 0 - maxValue: 3 - - - label: "Step 1b: TH writes LockState attribute as 1" - PICS: DRLK.S.A0000 - command: "writeAttribute" - attribute: "LockState" - arguments: - value: 1 - response: - error: UNSUPPORTED_WRITE - - - label: "Step 1c: TH reads LockState attribute from DUT" - PICS: DRLK.S.A0000 - command: "readAttribute" - attribute: "LockState" - response: - value: LockStateValue - label: - "Step 1d: TH sends a Lock Door command to the DUT. If DRLK.S.F00(PIN) + "Step 1h: TH sends a Lock Door command to the DUT. If DRLK.S.F00(PIN) & DRLK.S.F07(COTA), include a Valid PINCode in the Lock Door command." PICS: DRLK.S.C00.Rsp && DRLK.S.F00 && DRLK.S.F07 && DRLK.S.A0000 command: "LockDoor" @@ -171,7 +139,8 @@ tests: - name: "PINCode" value: "123456" - - label: "Step 1d: TH sends a Lock Door command to the DUT." + - label: + "Step 1h: TH sends a Lock Door command to the DUT without pin_code." PICS: DRLK.S.C00.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 command: "LockDoor" timedInteractionTimeoutMs: 1000 @@ -184,23 +153,16 @@ tests: values: - name: "ms" value: WaitAfterLockAandUnlockDoor - - - label: "Step 1d: TH reads LockState attribute from DUT" + - label: "Step 1h: TH reads LockState attribute from DUT" PICS: DRLK.S.A0000 command: "readAttribute" attribute: "LockState" response: value: 1 - - label: - "Step 1e: TH sends a Unlock Door command to the DUT. If + "Step 1i: TH sends a Unlock Door command to the DUT. If DRLK.S.F00(PIN) & DRLK.S.F07(COTA), include a Valid PINCode in the Unlock Door command" - PICS: DRLK.S.C01.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 - command: "UnlockDoor" - timedInteractionTimeoutMs: 1000 - - - label: "Step 1e: TH sends a Unlock Door command to the DUT." PICS: DRLK.S.C01.Rsp && DRLK.S.F00 && DRLK.S.F07 && DRLK.S.A0000 command: "UnlockDoor" timedInteractionTimeoutMs: 1000 @@ -209,6 +171,12 @@ tests: - name: "PINCode" value: "123456" + - label: + "Step 1i: TH sends a Unlock Door command to the DUT without pincode." + PICS: DRLK.S.C01.Rsp && !DRLK.S.F00 && !DRLK.S.F07 && DRLK.S.A0000 + command: "UnlockDoor" + timedInteractionTimeoutMs: 1000 + - label: "Wait after Unlock Door" PICS: DRLK.S.C00.Rsp cluster: "DelayCommands" @@ -218,14 +186,14 @@ tests: - name: "ms" value: WaitAfterLockAandUnlockDoor - - label: "Step 1e: TH reads LockState attribute from DUT" + - label: "Step 1i: TH reads LockState attribute from DUT" PICS: DRLK.S.A0000 command: "readAttribute" attribute: "LockState" response: value: 2 - - label: "Step 1f: Simulate a not fully locked scenario on the DUT." + - label: "Step 1j: Simulate a not fully locked scenario on the DUT." PICS: DRLK.S.A0000 && DRLK.S.M.SimulateNotFullyLocked && PICS_SKIP_SAMPLE_APP @@ -1366,6 +1334,26 @@ tests: response: value: Current_WrongCode_EntryLimit + - label: "Step 31b: TH writes WrongCodeEntryLimit attribute as 8" + PICS: + " ( DRLK.S.F00 || DRLK.S.F01 ) && DRLK.S.A0030 && + DRLK.S.M.WrongCodeEntryLimitAttributeWritable " + command: "writeAttribute" + attribute: "WrongCodeEntryLimit" + arguments: + value: 8 + + - label: "Step 31b: TH writes WrongCodeEntryLimit attribute as 8" + PICS: + " ( DRLK.S.F00 || DRLK.S.F01 ) && DRLK.S.A0030 && + !DRLK.S.M.WrongCodeEntryLimitAttributeWritable " + command: "writeAttribute" + attribute: "WrongCodeEntryLimit" + arguments: + value: 8 + response: + error: UNSUPPORTED_WRITE + - label: "Step 32a: TH reads UserCodeTemporary DisableTime attribute from DUT TH saves the values as Current_UserCode TemporaryDisableTime" @@ -1552,7 +1540,7 @@ tests: value: NumberOfCredentialsSupportedPerUserValue - label: "Step 36: TH sends ClearCredential Command to DUT" - PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp + PICS: DRLK.S.F00 && DRLK.S.F08 && DRLK.S.C26.Rsp command: "ClearCredential" timedInteractionTimeoutMs: 1000 arguments: @@ -1562,7 +1550,7 @@ tests: - label: "Step 37: TH sends ClearUser Command to DUT with the UserIndex as 1" - PICS: DRLK.S.F07 && DRLK.S.C1d.Rsp + PICS: DRLK.S.F08 && DRLK.S.C1d.Rsp command: "ClearUser" timedInteractionTimeoutMs: 1000 arguments: diff --git a/src/python_testing/TC_BOOLCFG_3_1.py b/src/python_testing/TC_BOOLCFG_3_1.py index 8e42140b35424c..7446afd4b49715 100644 --- a/src/python_testing/TC_BOOLCFG_3_1.py +++ b/src/python_testing/TC_BOOLCFG_3_1.py @@ -45,7 +45,7 @@ def steps_TC_BOOLCFG_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep("2a", "Read FeatureMap attribute"), - TestStep("2b", "Verify SENS feature is supported"), + TestStep("2b", "Verify SENSLVL feature is supported"), TestStep("2c", "Read AttributeList attribute"), TestStep(3, "Read SupportedSensitivityLevels attribute"), TestStep(4, "Read DefaultSensitivityLevel attribute, if supported"), diff --git a/src/python_testing/TC_DRLK_2_12.py b/src/python_testing/TC_DRLK_2_12.py index 4578aa01cd2ba0..3321ea303bf3f3 100644 --- a/src/python_testing/TC_DRLK_2_12.py +++ b/src/python_testing/TC_DRLK_2_12.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_12(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_12(self) -> list[str]: return ["DRLK.S.F0c"] diff --git a/src/python_testing/TC_DRLK_2_13.py b/src/python_testing/TC_DRLK_2_13.py index 5e1cdf6dcf6601..78f6ef0a0cae68 100644 --- a/src/python_testing/TC_DRLK_2_13.py +++ b/src/python_testing/TC_DRLK_2_13.py @@ -23,7 +23,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === import logging @@ -357,7 +357,7 @@ async def test_TC_DRLK_2_13(self): self.groupIdentifier = bytes.fromhex("89d085fc302ca53e279bfcdecdf3c4ad") self.groupResolvingKey = bytes.fromhex("89d0859bfcdecdf3c4adfc302ca53e27") self.common_cluster_endpoint = 0 - self.app_cluster_endpoint = 1 + self.app_cluster_endpoint = self.matter_test_config.endpoint self.alirouser = "AliroUser" self.alirocredentialissuerkey = bytes.fromhex( "047a4c882d753924cdf3779a3c84fec2debaa6f0b3084450878acc7ddcce7856ae57b1ebbe2561015103dd7474c2a183675378ec55f1e465ac3436bf3dd5ca54d4") diff --git a/src/python_testing/TC_DRLK_2_2.py b/src/python_testing/TC_DRLK_2_2.py index e7f3e6fa8e421e..9a04e9d5fd1904 100644 --- a/src/python_testing/TC_DRLK_2_2.py +++ b/src/python_testing/TC_DRLK_2_2.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_2(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_2(self) -> list[str]: return ["DRLK.S"] diff --git a/src/python_testing/TC_DRLK_2_3.py b/src/python_testing/TC_DRLK_2_3.py index 8c6f40f19c5449..3171ed28b4f9ad 100644 --- a/src/python_testing/TC_DRLK_2_3.py +++ b/src/python_testing/TC_DRLK_2_3.py @@ -31,6 +31,8 @@ from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main # Configurable parameters: +# - userIndex: userIndex to use when creating a user on the DUT for testing purposes +# defaults to 1. Add `--int-arg user_index:` to command line to override # - CredentialIndex: CredentialIndex to use when creating a Credential on the DUT for testing purposes # defaults to 1. Add `--int-arg credential_index:` to command line to override # - UserCodeTemporaryDisableTime: Value used to configure DUT for testing purposes. @@ -42,14 +44,15 @@ class TC_DRLK_2_3(MatterBaseTest, DRLK_COMMON): - def setup_class(self): - return super().setup_class() @async_test_body async def teardown_test(self): await self.teardown() return super().teardown_test() + def setup_class(self): + return super().setup_class() + def pics_TC_DRLK_2_3(self) -> list[str]: return ["DRLK.S"] diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py index 7216031a9374f4..579398642a5320 100644 --- a/src/python_testing/TC_PWRTL_2_1.py +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -30,7 +30,6 @@ import logging import chip.clusters as Clusters -from chip.clusters.Types import NullValue from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -56,13 +55,8 @@ async def test_TC_PWRTL_2_1(self): self.print_step(2, "Read AvailableAttributes attribute") available_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.AvailableEndpoints) - if available_endpoints == NullValue: - logging.info("AvailableEndpoints is null") - else: - logging.info("AvailableEndpoints: %s" % (available_endpoints)) - - asserts.assert_less_equal(len(available_endpoints), 21, - "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) + asserts.assert_less_equal(len(available_endpoints), 20, + "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) if not self.check_pics("PWRTL.S.A0001"): logging.info("Test skipped because PICS PWRTL.S.A0001 is not set") @@ -71,10 +65,11 @@ async def test_TC_PWRTL_2_1(self): self.print_step(3, "Read ActiveEndpoints attribute") active_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.ActiveEndpoints) logging.info("ActiveEndpoints: %s" % (active_endpoints)) - - if available_endpoints == NullValue: - asserts.assert_true(active_endpoints == NullValue, - "ActiveEndpoints should be null when AvailableEndpoints is null: %s" % active_endpoints) + asserts.assert_less_equal(len(active_endpoints), 20, + "ActiveEndpoints length %d must be less than 21!" % len(active_endpoints)) + # Verify that ActiveEndpoints is a subset of AvailableEndpoints + asserts.assert_true(set(active_endpoints).issubset(set(available_endpoints)), + "ActiveEndpoints should be a subset of AvailableEndpoints") if __name__ == "__main__": diff --git a/src/python_testing/drlk_2_x_common.py b/src/python_testing/drlk_2_x_common.py index a8368c5cc96507..c25365bf993d8f 100644 --- a/src/python_testing/drlk_2_x_common.py +++ b/src/python_testing/drlk_2_x_common.py @@ -73,33 +73,60 @@ async def send_clear_credential_cmd(self, credential) -> None: await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.ClearCredential(credential=credential), endpoint=self.endpoint, timedRequestTimeoutMs=1000) - ret = await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.GetCredentialStatus(credential=self.createdCredential), + ret = await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.GetCredentialStatus(credential=credential), endpoint=self.endpoint) asserts.assert_true(type_matches(ret, Clusters.Objects.DoorLock.Commands.GetCredentialStatusResponse), "Unexpected return type for GetCredentialStatus") asserts.assert_false(ret.credentialExists, "Error clearing Credential (credentialExists==True)") - async def cleanup_users_and_credentials(self): - self.print_step("Cleanup", "Clear created User and Credential on the DUT") - if self.createdCredential: - await self.send_clear_credential_cmd(self.createdCredential) - logging.info("Credential cleared at CredentialIndex %d" % (self.createdCredential.credentialIndex)) - self.createdCredential = None - - async def generate_pincode(self, maxPincodeLength): - return ''.join(random.choices(string.digits, k=maxPincodeLength)) + async def cleanup_users_and_credentials(self, user_clear_step, clear_credential_step, credentials, userIndex): + if (self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F08") + and self.check_pics("DRLK.S.C26.Rsp")): + if clear_credential_step: + self.print_step(clear_credential_step, "TH sends ClearCredential Command to DUT") + await self.send_clear_credential_cmd(credentials) + if self.check_pics("DRLK.S.C1d.Rsp") and self.check_pics("DRLK.S.F08"): + if user_clear_step: + self.print_step(user_clear_step, "TH sends ClearUser Command to DUT with the UserIndex as 1") + await self.send_drlk_cmd_expect_success( + command=Clusters.Objects.DoorLock.Commands.ClearUser(userIndex=userIndex)) + self.clear_credential_and_user_flag = False + + async def set_user_command(self): + await self.send_single_cmd(cmd=Clusters.Objects.DoorLock.Commands.SetUser( + operationType=Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, + userIndex=self.user_index, + userName="xxx", + userUniqueID=6452, + userStatus=Clusters.DoorLock.Enums.UserStatusEnum.kOccupiedEnabled, + credentialRule=Clusters.DoorLock.Enums.CredentialRuleEnum.kSingle + ), + endpoint=self.endpoint, + timedRequestTimeoutMs=1000 + ) + + async def read_and_verify_pincode_length(self, attribute, failure_message: str, min_range=0, max_range=255): + pin_code_length = await self.read_drlk_attribute_expect_success(attribute=attribute) + verify_pin_code_length = True if min_range <= pin_code_length <= max_range else False + asserts.assert_true(verify_pin_code_length, f"{failure_message}, got value {pin_code_length}") + return pin_code_length + + async def generate_pincode(self, maxPincodeLength, minPincodeLength): + length_of_pincode = random.randint(minPincodeLength, maxPincodeLength) + return ''.join(random.choices(string.digits, k=length_of_pincode)) async def teardown(self): - await self.cleanup_users_and_credentials() + if self.clear_credential_and_user_flag: + await self.cleanup_users_and_credentials(user_clear_step=None, clear_credential_step=None, + credentials=self.createdCredential, userIndex=self.user_index) async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lockUnlockText, doAutoRelockTest): is_ci = self.check_pics('PICS_SDK_CI_ONLY') - - self.createdCredential = None - - self.endpoint = self.user_params.get("endpoint", 1) + self.clear_credential_and_user_flag = True # Allow for user overrides of these values + self.user_index = self.user_params.get("user_index", 1) + self.endpoint = self.user_params.get("endpoint", 1) credentialIndex = self.user_params.get("credential_index", 1) userCodeTemporaryDisableTime = self.user_params.get("user_code_temporary_disable_time", 15) wrongCodeEntryLimit = self.user_params.get("wrong_code_entry_limit", 3) @@ -110,40 +137,12 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo cluster = Clusters.Objects.DoorLock attributes = Clusters.DoorLock.Attributes - validPincode = None + pin_code = None invalidPincode = None - + credential = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, + credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) + self.createdCredential = credential self.print_step(0, "Commissioning, already done") - - if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): - self.print_step("Preconditions.1a", - "TH reads MaxPINCodeLength attribute from DUT and generates a valid PINCode") - maxPincodeLength_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.MaxPINCodeLength) - logging.info("MaxPINCodeLength value is %s" % (maxPincodeLength_dut)) - - validPincodeString = await self.generate_pincode(maxPincodeLength_dut) - while True: - invalidPincodeString = await self.generate_pincode(maxPincodeLength_dut) - if invalidPincodeString != validPincodeString: - break - logging.info("Valid PinCode=%s, Invalid PinCode=%s" % (validPincodeString, invalidPincodeString)) - - validPincode = bytes(validPincodeString, 'ascii') - invalidPincode = bytes(invalidPincodeString, 'ascii') - - self.print_step("Preconditions.1b", - "TH sends SetCredential command to DUT to set up User and Credential at CredentialIndex {}".format(str(credentialIndex))) - credential = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, - credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) - ret = await self.send_set_credential_cmd(Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, - credential, - validPincode, - NullValue, - NullValue, - NullValue) - logging.info("Credential created at CredentialIndex %d, UserIndex %d." % (credentialIndex, ret.userIndex)) - self.createdCredential = credential - requirePinForRemoteOperation_dut = False if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): self.print_step("1", "TH writes the RequirePINforRemoteOperation attribute value as false on the DUT") @@ -174,13 +173,44 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) else: await self.send_drlk_cmd_expect_success(command=command) - - self.print_step("4", "TH sends %s Command to the DUT with valid PINCode" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) - await self.send_drlk_cmd_expect_success(command=command) else: asserts.assert_true(False, "%sResponse is a mandatory command response and must be supported in PICS" % lockUnlockText) + if self.check_pics("DRLK.S.F08"): + if self.check_pics("DRLK.S.C1a.Rsp"): + self.print_step("4a", "TH writes the RequirePINforRemoteOperation attribute value as true on the DUT") + await self.set_user_command() + if self.check_pics("DRLK.S.F00"): + self.print_step("4b", "TH reads MinPINCodeLength attribute and saves the value") + min_pin_code_length = await self.read_and_verify_pincode_length( + attribute=Clusters.DoorLock.Attributes.MinPINCodeLength, + failure_message="MinPINCodeLength attribute must be between 0 to 255" + ) + self.print_step("4c", "TH reads MaxPINCodeLength attribute and saves the value") + max_pin_code_length = await self.read_and_verify_pincode_length( + attribute=Clusters.DoorLock.Attributes.MaxPINCodeLength, + failure_message="MinPINCodeLength attribute must be between 0 to 255" + ) + self.print_step("4d", "Generate credential data and store as pin_code,Th sends SetCredential command" + "using pin_code") + credential_data_generated = await self.generate_pincode(max_pin_code_length, min_pin_code_length) + pin_code = bytes(credential_data_generated, "ascii") + if self.check_pics("DRLK.S.C22.Rsp") and self.check_pics("DRLK.S.C23.Tx"): + set_cred_response = await self.send_set_credential_cmd(userIndex=self.user_index, + operationType=Clusters.DoorLock.Enums.DataOperationTypeEnum.kAdd, + credential=credential, + credentialData=pin_code, + userStatus=NullValue, + userType=NullValue + ) + asserts.assert_true( + type_matches(set_cred_response, Clusters.Objects.DoorLock.Commands.SetCredentialResponse), + "Unexpected return type for SetCredential") + self.print_step("4e", f"TH sends {lockUnlockText} Command to the DUT with PINCode as pin_code.") + if self.check_pics(lockUnlockCmdRspPICS): + command = lockUnlockCommand(PINCode=pin_code) + await self.send_drlk_cmd_expect_success(command=command) + if self.check_pics("DRLK.S.F00") and self.check_pics("DRLK.S.F07"): self.print_step("5", "TH writes the RequirePINforRemoteOperation attribute value as true on the DUT") attribute = attributes.RequirePINforRemoteOperation(True) @@ -197,7 +227,13 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics("DRLK.S.M.RequirePINForRemoteOperationAttributeWritable"): self.print_step("6a", "TH verifies that RequirePINforRemoteOperation is TRUE") asserts.assert_true(requirePinForRemoteOperation_dut, "RequirePINforRemoteOperation is expected to be TRUE") - + # generate InvalidPincode + while True: + invalidPincodeString = await self.generate_pincode(max_pin_code_length, min_pin_code_length) + invalidPincode = bytes(invalidPincodeString, "ascii") + if invalidPincodeString != pin_code: + break + logging.info(" pin_code=%s, Invalid PinCode=%s" % (pin_code, invalidPincodeString)) if self.check_pics("DRLK.S.F00") and self.check_pics(lockUnlockCmdRspPICS) and self.check_pics("DRLK.S.A0033"): self.print_step("7", "TH sends %s Command to the DUT with an invalid PINCode" % lockUnlockText) command = lockUnlockCommand(PINCode=invalidPincode) @@ -212,7 +248,7 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics(lockUnlockCmdRspPICS) and self.check_pics("DRLK.S.A0033"): self.print_step("9", "TH sends %s Command to the DUT with valid PINCode" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) if self.check_pics("DRLK.S.F00") or self.check_pics("DRLK.S.F01"): @@ -248,7 +284,7 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) self.print_step("13", "TH sends %s Command to the DUT with valid PINCode. Verify failure or no response" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_error(command=command, error=Status.Failure) if self.check_pics("DRLK.S.A0031"): @@ -257,9 +293,14 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if not doAutoRelockTest: self.print_step("15", "Send %s with valid Pincode and verify success" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + credentials = cluster.Structs.CredentialStruct(credentialIndex=credentialIndex, + credentialType=Clusters.DoorLock.Enums.CredentialTypeEnum.kPin) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) + await self.cleanup_users_and_credentials(user_clear_step="17", clear_credential_step="16", + credentials=credentials, userIndex=self.user_index) + if doAutoRelockTest: if self.check_pics("DRLK.S.A0023"): self.print_step("15", "TH writes the AutoRelockTime attribute value on the DUT") @@ -275,22 +316,19 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo if self.check_pics(lockUnlockCmdRspPICS): self.print_step("17", "Send %s with valid Pincode and verify success" % lockUnlockText) - command = lockUnlockCommand(PINCode=validPincode) + command = lockUnlockCommand(PINCode=pin_code) await self.send_drlk_cmd_expect_success(command=command) - - if self.check_pics("DRLK.S.A0023"): - self.print_step("18a", "Wait for AutoRelockTime seconds") - # Add additional wait time buffer for motor movement, etc. - time.sleep(autoRelockTime_dut + 5) - - if self.check_pics("DRLK.S.A0000"): - self.print_step("18b", "TH reads LockState attribute after AutoRelockTime Expires") - lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) - logging.info("Current LockState is %s" % (lockstate_dut)) - asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, - "LockState expected to be value==Locked") - - await self.cleanup_users_and_credentials() + # Add additional wait time buffer for motor movement, etc. + time.sleep(autoRelockTime_dut + 5) + + if self.check_pics("DRLK.S.A0000"): + self.print_step("18", "TH reads LockState attribute after AutoRelockTime Expires") + lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) + logging.info("Current LockState is %s" % (lockstate_dut)) + asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, + "LockState expected to be value==Locked") + await self.cleanup_users_and_credentials(user_clear_step="20", clear_credential_step="19", + credentials=credential, userIndex=1) async def run_drlk_test_2_2(self): await self.run_drlk_test_common(lockUnlockCommand=Clusters.Objects.DoorLock.Commands.LockDoor, From 17dafaa6360904f36fb30b22f2881c4945b7e597 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Wed, 4 Sep 2024 18:04:37 -0400 Subject: [PATCH 60/70] Address follow-up PR comments for fabric-admin UniqueIdGetter (#35405) --------- Co-authored-by: Restyled.io Co-authored-by: saurabhst --- examples/fabric-admin/BUILD.gn | 4 +- .../device_manager/DeviceSynchronization.cpp | 63 +++++++++++-------- .../device_manager/DeviceSynchronization.h | 6 +- .../{UidGetter.cpp => UniqueIdGetter.cpp} | 24 +++---- .../{UidGetter.h => UniqueIdGetter.h} | 20 ++++-- 5 files changed, 71 insertions(+), 46 deletions(-) rename examples/fabric-admin/device_manager/{UidGetter.cpp => UniqueIdGetter.cpp} (80%) rename examples/fabric-admin/device_manager/{UidGetter.h => UniqueIdGetter.h} (73%) diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index 36ba7ec4e15d51..d1add205f8826c 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -88,8 +88,8 @@ static_library("fabric-admin-utils") { "device_manager/DeviceSubscriptionManager.h", "device_manager/DeviceSynchronization.cpp", "device_manager/DeviceSynchronization.h", - "device_manager/UidGetter.cpp", - "device_manager/UidGetter.h", + "device_manager/UniqueIdGetter.cpp", + "device_manager/UniqueIdGetter.h", ] deps = [ "${chip_root}/src/app:events" ] diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index bc3e9b31fe6b1b..6cc1cea690df2f 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -136,15 +136,11 @@ void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) #if defined(PW_RPC_ENABLED) if (mState == State::ReceivedResponse && !DeviceMgr().IsCurrentBridgeDevice(mCurrentDeviceData.node_id)) { - auto * device = DeviceMgr().FindDeviceByNode(mCurrentDeviceData.node_id); - if (!mCurrentDeviceData.has_unique_id && device) + GetUniqueId(); + if (mState == State::GettingUid) { - GetUid(device->GetEndpointId()); - if (mState == State::GettingUid) - { - // GetUid was successful and we rely on callback to call SynchronizationCompleteAddDevice. - return; - } + // GetUniqueId was successful and we rely on callback to call SynchronizationCompleteAddDevice. + return; } SynchronizationCompleteAddDevice(); } @@ -211,32 +207,49 @@ void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceCont MoveToState(State::Connecting); } -void DeviceSynchronizer::GetUid(EndpointId remoteEndpointIdOfInterest) +void DeviceSynchronizer::GetUniqueId() { VerifyOrDie(mState == State::ReceivedResponse); VerifyOrDie(mController); + + // If we have a UniqueId we can return leaving state in ReceivedResponse. + VerifyOrReturn(!mCurrentDeviceData.has_unique_id, ChipLogDetail(NotSpecified, "We already have UniqueId")); + + auto * device = DeviceMgr().FindDeviceByNode(mCurrentDeviceData.node_id); + // If there is no associated remote Fabric Sync Aggregator there is no other place for us to try + // getting the UniqueId from and can return leaving the state in ReceivedResponse. + VerifyOrReturn(device, ChipLogDetail(NotSpecified, "No remote Fabric Sync Aggregator to get UniqueId from")); + + // Because device is not-null we expect IsFabricSyncReady to be true. IsFabricSyncReady indicates we have a + // connection to the remote Fabric Sync Aggregator. VerifyOrDie(DeviceMgr().IsFabricSyncReady()); - auto remoteBridgeNodeId = DeviceMgr().GetRemoteBridgeNodeId(); - - CHIP_ERROR err = mUidGetter.GetUid( - [this](std::optional aUniqueId) { - if (aUniqueId.has_value()) - { - this->mCurrentDeviceData.has_unique_id = true; - memcpy(this->mCurrentDeviceData.unique_id, aUniqueId.value().data(), aUniqueId.value().size()); - } - else - { - ChipLogError(NotSpecified, "We expected to get UniqueId from remote fabric sync bridge"); - } - this->SynchronizationCompleteAddDevice(); - }, - *mController, remoteBridgeNodeId, remoteEndpointIdOfInterest); + auto remoteBridgeNodeId = DeviceMgr().GetRemoteBridgeNodeId(); + EndpointId remoteEndpointIdOfInterest = device->GetEndpointId(); + + ChipLogDetail(NotSpecified, "Attempting to get UniqueId from remote Fabric Sync Aggregator") CHIP_ERROR err = + mUniqueIdGetter.GetUniqueId( + [this](std::optional aUniqueId) { + if (aUniqueId.has_value()) + { + this->mCurrentDeviceData.has_unique_id = true; + memcpy(this->mCurrentDeviceData.unique_id, aUniqueId.value().data(), aUniqueId.value().size()); + } + else + { + ChipLogError(NotSpecified, "We expected to get UniqueId from remote Fabric Sync Aggregator, but failed"); + } + this->SynchronizationCompleteAddDevice(); + }, + *mController, remoteBridgeNodeId, remoteEndpointIdOfInterest); if (err == CHIP_NO_ERROR) { MoveToState(State::GettingUid); } + else + { + ChipLogDetail(NotSpecified, "Failed to get UniqueId from remote Fabric Sync Aggregator") + } } void DeviceSynchronizer::SynchronizationCompleteAddDevice() diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.h b/examples/fabric-admin/device_manager/DeviceSynchronization.h index 495fecd60bd4b5..11b640236268dd 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.h +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.h @@ -17,7 +17,7 @@ */ #pragma once -#include "UidGetter.h" +#include "UniqueIdGetter.h" #include #include @@ -77,7 +77,7 @@ class DeviceSynchronizer : public chip::app::ReadClient::Callback GettingUid, ///< We are getting UniqueId from the remote fabric sync bridge. }; - void GetUid(chip::EndpointId endpointId); + void GetUniqueId(); void SynchronizationCompleteAddDevice(); void MoveToState(const State targetState); @@ -93,5 +93,5 @@ class DeviceSynchronizer : public chip::app::ReadClient::Callback // mState != Idle). chip::Controller::DeviceController * mController = nullptr; chip_rpc_SynchronizedDevice mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; - UidGetter mUidGetter; + UniqueIdGetter mUniqueIdGetter; }; diff --git a/examples/fabric-admin/device_manager/UidGetter.cpp b/examples/fabric-admin/device_manager/UniqueIdGetter.cpp similarity index 80% rename from examples/fabric-admin/device_manager/UidGetter.cpp rename to examples/fabric-admin/device_manager/UniqueIdGetter.cpp index baeaba6a02498c..3aba21752d9c67 100644 --- a/examples/fabric-admin/device_manager/UidGetter.cpp +++ b/examples/fabric-admin/device_manager/UniqueIdGetter.cpp @@ -16,7 +16,7 @@ * */ -#include "UidGetter.h" +#include "UniqueIdGetter.h" using namespace ::chip; using namespace ::chip::app; @@ -26,12 +26,12 @@ namespace { void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) { - reinterpret_cast(context)->OnDeviceConnected(exchangeMgr, sessionHandle); + reinterpret_cast(context)->OnDeviceConnected(exchangeMgr, sessionHandle); } void OnDeviceConnectionFailureWrapper(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) { - reinterpret_cast(context)->OnDeviceConnectionFailure(peerId, error); + reinterpret_cast(context)->OnDeviceConnectionFailure(peerId, error); } bool SuccessOrLog(CHIP_ERROR err, const char * name) @@ -48,13 +48,13 @@ bool SuccessOrLog(CHIP_ERROR err, const char * name) } // namespace -UidGetter::UidGetter() : +UniqueIdGetter::UniqueIdGetter() : mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) {} -CHIP_ERROR UidGetter::GetUid(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, chip::NodeId nodeId, - chip::EndpointId endpointId) +CHIP_ERROR UniqueIdGetter::GetUniqueId(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, + chip::NodeId nodeId, chip::EndpointId endpointId) { assertChipStackLockedByCurrentThread(); VerifyOrDie(!mCurrentlyGettingUid); @@ -74,7 +74,7 @@ CHIP_ERROR UidGetter::GetUid(OnDoneCallback onDoneCallback, chip::Controller::De return err; } -void UidGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +void UniqueIdGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) { VerifyOrDie(path.mClusterId == Clusters::BridgedDeviceBasicInformation::Id); @@ -95,23 +95,23 @@ void UidGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLV } } -void UidGetter::OnReportEnd() +void UniqueIdGetter::OnReportEnd() { // We will call mOnDoneCallback in OnDone. } -void UidGetter::OnError(CHIP_ERROR error) +void UniqueIdGetter::OnError(CHIP_ERROR error) { ChipLogProgress(NotSpecified, "Error Getting UID: %" CHIP_ERROR_FORMAT, error.Format()); } -void UidGetter::OnDone(ReadClient * apReadClient) +void UniqueIdGetter::OnDone(ReadClient * apReadClient) { mCurrentlyGettingUid = false; mOnDoneCallback(mUniqueIdHasValue ? std::make_optional(mUniqueId) : std::nullopt); } -void UidGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +void UniqueIdGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) { VerifyOrDie(mCurrentlyGettingUid); mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr, *this /* callback */, @@ -137,7 +137,7 @@ void UidGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, cons } } -void UidGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +void UniqueIdGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) { VerifyOrDie(mCurrentlyGettingUid); ChipLogError(NotSpecified, "DeviceSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); diff --git a/examples/fabric-admin/device_manager/UidGetter.h b/examples/fabric-admin/device_manager/UniqueIdGetter.h similarity index 73% rename from examples/fabric-admin/device_manager/UidGetter.h rename to examples/fabric-admin/device_manager/UniqueIdGetter.h index 5f99c75198c5dc..6680adf5bdfc97 100644 --- a/examples/fabric-admin/device_manager/UidGetter.h +++ b/examples/fabric-admin/device_manager/UniqueIdGetter.h @@ -24,15 +24,27 @@ #include #include -class UidGetter : public chip::app::ReadClient::Callback +/** + * @brief Class used to get UniqueID from Bridged Device Basic Information Cluster + * + * When syncing a device from another fabric that does not have a UniqueID, spec + * dictates: + * When a Fabric Synchronizing Administrator commissions a Synchronized Device, + * it SHALL persist and maintain an association with the UniqueID in the Bridged + * Device Basic Information Cluster exposed by another Fabric Synchronizing + * Administrator. + * + * This class assists in retrieving the UniqueId in the above situation. + */ +class UniqueIdGetter : public chip::app::ReadClient::Callback { public: using OnDoneCallback = std::function)>; - UidGetter(); + UniqueIdGetter(); - CHIP_ERROR GetUid(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, chip::NodeId nodeId, - chip::EndpointId endpointId); + CHIP_ERROR GetUniqueId(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, chip::NodeId nodeId, + chip::EndpointId endpointId); /////////////////////////////////////////////////////////////// // ReadClient::Callback implementation From 55a37e2b39debdb5bc1aa354c64bfa37d8d8b27c Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 18:10:34 -0400 Subject: [PATCH 61/70] TC-ACL-2.11: Add top level PICS (#35415) Without this, the TH is going to select this test for every device and every device except the MACL devices will fail. --- src/python_testing/TC_ACL_2_11.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python_testing/TC_ACL_2_11.py b/src/python_testing/TC_ACL_2_11.py index 5fb897f8c5b379..a9f63b22d5c798 100644 --- a/src/python_testing/TC_ACL_2_11.py +++ b/src/python_testing/TC_ACL_2_11.py @@ -74,6 +74,9 @@ class TC_ACL_2_11(MatterBaseTest): Clusters.Descriptor.Attributes.EventList.attribute_id ] + def pics_TC_ACL_2_11(self) -> list[str]: + return ['ACL.S.F01'] + def desc_TC_ACL_2_11(self) -> str: return "[TC-ACL-2.11] Verification of Managed Device feature" From 5c062aa815d8397a7dac8833e8fc79af41b12f8f Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 19:33:52 -0400 Subject: [PATCH 62/70] Basic comp tests: add fix for pre-commissioned devices (#35409) * Basic comp tests: add fix for pre-commissioned devices * add check to CI --- src/python_testing/TC_DeviceBasicComposition.py | 8 +++++++- src/python_testing/basic_composition_support.py | 4 +++- src/python_testing/matter_testing_support.py | 11 ++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index 24a336e0b001e9..a4ab495114a245 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -19,7 +19,7 @@ # for details about the block below. # # === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: run1 run2 run3 run4 run5 run6 run7 +# test-runner-runs: run1 run2 run3 run4 run5 run6 run7 run8 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True @@ -61,6 +61,12 @@ # test-runner-run/run7/quiet: True # test-runner-run/run7/app-args: --discriminator 1234 --KVS kvs1 # test-runner-run/run7/script-args: --storage-path admin_storage.json --discriminator 1234 --passcode 20202021 --commissioning-method on-network +# +# test-runner-run/run8/app: ${CHIP_LOCK_APP} +# test-runner-run/run8/factoryreset: False +# test-runner-run/run8/quiet: True +# test-runner-run/run8/app-args: --discriminator 1234 --KVS kvs1 +# test-runner-run/run8/script-args: --storage-path admin_storage.json # === END CI TEST ARGUMENTS === # Run 1: runs through all tests diff --git a/src/python_testing/basic_composition_support.py b/src/python_testing/basic_composition_support.py index c09d78ef3027d8..5401b1fad04f9d 100644 --- a/src/python_testing/basic_composition_support.py +++ b/src/python_testing/basic_composition_support.py @@ -104,6 +104,8 @@ def get_code(self, dev_ctrl): created_codes.append(dev_ctrl.CreateManualCode(discriminator, self.matter_test_config.setup_passcodes[idx])) setup_codes = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code + created_codes + if not setup_codes: + return None asserts.assert_equal(len(setup_codes), 1, "Require exactly one of either --qr-code, --manual-code or (--discriminator and --passcode).") return setup_codes[0] @@ -132,7 +134,7 @@ async def setup_class_helper(self, allow_pase: bool = True): node_id = self.dut_node_id task_list = [] - if allow_pase: + if allow_pase and self.get_code(dev_ctrl): setup_code = self.get_code(dev_ctrl) pase_future = dev_ctrl.EstablishPASESession(setup_code, self.dut_node_id) task_list.append(asyncio.create_task(pase_future)) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 7c1ac60fd3910a..c5d46e2306dae2 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -1744,6 +1744,12 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf device_descriptors = config.qr_code_content + config.manual_code + config.discriminators + if not config.dut_node_ids: + config.dut_node_ids = [_DEFAULT_DUT_NODE_ID] + + if args.commissioning_method is None: + return True + if len(config.dut_node_ids) > len(device_descriptors): print("error: More node IDs provided than discriminators") return False @@ -1751,8 +1757,6 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf if len(config.dut_node_ids) < len(device_descriptors): # We generate new node IDs sequentially from the last one seen for all # missing NodeIDs when commissioning many nodes at once. - if not config.dut_node_ids: - config.dut_node_ids = [_DEFAULT_DUT_NODE_ID] missing = len(device_descriptors) - len(config.dut_node_ids) for i in range(missing): config.dut_node_ids.append(config.dut_node_ids[-1] + 1) @@ -1765,9 +1769,6 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf print("error: Duplicate value in discriminator list") return False - if args.commissioning_method is None: - return True - if args.discriminators == [] and (args.qr_code == [] and args.manual_code == []): print("error: Missing --discriminator when no --qr-code/--manual-code present!") return False From 7fdfc88383676eeecd022e047ae1c5a8ce1b9b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Josefsen?= <69624991+ReneJosefsen@users.noreply.github.com> Date: Thu, 5 Sep 2024 02:30:23 +0200 Subject: [PATCH 63/70] [TC-LVL-2.3] Minor adjustments from Test Plan feedback (#35215) * Minor adjustments from TP feedback * Update src/python_testing/TC_LVL_2_3.py --- src/python_testing/TC_LVL_2_3.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/python_testing/TC_LVL_2_3.py b/src/python_testing/TC_LVL_2_3.py index d0ac4c8c1ff893..dcb2e8d65df168 100644 --- a/src/python_testing/TC_LVL_2_3.py +++ b/src/python_testing/TC_LVL_2_3.py @@ -43,11 +43,11 @@ def steps_TC_LVL_2_3(self) -> list[TestStep]: THRead = "TH reads" THcommand = "TH sends the command" return [TestStep(1, test_plan_support.commission_if_required(), is_commissioning=True), - TestStep(2, f"{THRead} FeatureMap attribute and the AttributeList value"), + TestStep(2, f"{THRead} FeatureMap attribute and the AttributeList value", test_plan_support.verify_success()), TestStep( "3a", f"If the MaxLevel attribute is in the AttributeList, {THRead} MaxLevel attribute and store value as maxLevel, otherwise set maxLevel to 254", test_plan_support.verify_success()), TestStep( - "3b", f"If the MinLevel attribute is in the AttributeList, {THRead} MinLevel attribute and store value as minLevel, otherwise set minLevel to 1", test_plan_support.verify_success()), + "3b", f"If the MinLevel attribute is in the AttributeList, {THRead} MinLevel attribute and store value as minLevel, otherwise set minLevel to 0 if LT is not supported or 1 if LT is supported", test_plan_support.verify_success()), TestStep(4, f"{THcommand} MoveWithOnOff with MoveMode field set to Down and rate set to 254 and remaining fields set to 0", test_plan_support.verify_success()), TestStep(5, f"{THRead} CurrentLevel attribute and store value as startCurrentLevel", @@ -77,9 +77,9 @@ def steps_TC_LVL_2_3(self) -> list[TestStep]: TestStep(20, "TH verifies reportedRemainingTimeValuesList contains three entries", "reportedRemainingTimeValuesList has 3 entries in the list"), TestStep(21, "TH verifies the first entry in reportedRemainingTimeValuesList is approximately 100 (10s)", - "The first entry in reportedRemainingTimeValuesList is approximately equal to 100"), + "The first entry in reportedRemainingTimeValuesList is in the range 95 - 100"), TestStep(22, "TH verifies the second entry in reportedRemainingTimeValuesList is approximately 150", - "The second entry in reportedRemainingTimeValuesList is approximately equal to 150"), + "The second entry in reportedRemainingTimeValuesList is in the range 145 - 150"), TestStep(23, "TH verifies the third entry in reportedRemainingTimeValuesList is 0", "The third entry in reportedRemainingTimeValuesList is equal to 0") ] @@ -96,8 +96,6 @@ async def test_TC_LVL_2_3(self): attributes = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.AttributeList) self.step("3a") - attributes = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.AttributeList) - if lvl.Attributes.MaxLevel.attribute_id in attributes: max_level = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.MaxLevel) else: @@ -107,7 +105,10 @@ async def test_TC_LVL_2_3(self): if lvl.Attributes.MinLevel.attribute_id in attributes: min_level = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.MinLevel) else: - min_level = 1 + if (lvl.Bitmaps.Feature.kLighting & feature_map) == 0: + min_level = 0 + else: + min_level = 1 self.step(4) cmd = Clusters.LevelControl.Commands.MoveToLevelWithOnOff(level=min_level, transitionTime=0) @@ -189,9 +190,11 @@ async def test_TC_LVL_2_3(self): self.step(21) remaining_time = sub_handler.attribute_reports[lvl.Attributes.RemainingTime] logging.info(f'Reamining time reports: {remaining_time}') + asserts.assert_less_equal(remaining_time[0].value, 100, "Unexpected first RemainingTime report") asserts.assert_almost_equal(remaining_time[0].value, 100, delta=10, msg="Unexpected first RemainingTime report") self.step(22) + asserts.assert_less_equal(remaining_time[1].value, 150, "Unexpected second RemainingTime report") asserts.assert_almost_equal(remaining_time[1].value, 150, delta=10, msg="Unexpected second RemainingTime report") self.step(23) From 77340692640f929163318ecd46a9e68382bbf17b Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 4 Sep 2024 17:39:54 -0700 Subject: [PATCH 64/70] [Fabric-Sync] Improve the stability of test TC_MCORE_FS_1_4 (#35416) * Improve the stability of test TC_MCORE_FS_1_4 * Address the review comments * Make wait_for_server_initialization global * Restyled by autopep8 --------- Co-authored-by: Restyled.io --- src/python_testing/TC_MCORE_FS_1_4.py | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_MCORE_FS_1_4.py b/src/python_testing/TC_MCORE_FS_1_4.py index 8e05c2dd7e9c3d..e6337352d5a71c 100644 --- a/src/python_testing/TC_MCORE_FS_1_4.py +++ b/src/python_testing/TC_MCORE_FS_1_4.py @@ -48,7 +48,34 @@ from mobly import asserts +async def wait_for_server_initialization(server_port, timeout=5): + """Wait until the server is ready by checking if it opens the expected port.""" + start_time = asyncio.get_event_loop().time() + elapsed_time = 0 + retry_interval = 1 + + logging.info(f"Waiting for server to initialize on TCP port {server_port} for up to {timeout} seconds.") + + while elapsed_time < timeout: + try: + # Try connecting to the server to check if it's ready + reader, writer = await asyncio.open_connection('::1', server_port) + writer.close() + await writer.wait_closed() + logging.info(f"TH_SERVER_NO_UID is initialized and ready on port {server_port}.") + return + except (ConnectionRefusedError, OSError) as e: + logging.warning(f"Connection to port {server_port} failed: {e}. Retrying in {retry_interval} seconds...") + + await asyncio.sleep(retry_interval) + elapsed_time = asyncio.get_event_loop().time() - start_time + + raise TimeoutError(f"Server on port {server_port} did not initialize within {timeout} seconds. " + f"Total time waited: {elapsed_time} seconds.") + # TODO: Make this class more generic. Issue #35348 + + class Subprocess(threading.Thread): def __init__(self, args: list = [], stdout_cb=None, tag="", **kw): @@ -228,7 +255,7 @@ def setup_class(self): self.th_server_port = 5544 self.th_server_discriminator = self.th_fsa_bridge_discriminator + 1 - self.th_server_passcode = 20202021 + self.th_server_passcode = 20202022 # Start the TH_SERVER_NO_UID app. self.th_server = AppServer( @@ -238,6 +265,12 @@ def setup_class(self): discriminator=self.th_server_discriminator, passcode=self.th_server_passcode) + # Wait for TH_SERVER_NO_UID get initialized. + try: + asyncio.run(wait_for_server_initialization(self.th_server_port)) + except TimeoutError: + asserts.fail(f"TH_SERVER_NO_UID server failed to open port {self.th_server_port}") + def teardown_class(self): if self.th_fsa_controller is not None: self.th_fsa_controller.stop() @@ -271,6 +304,7 @@ async def test_TC_MCORE_FS_1_4(self): self.step(1) th_server_th_node_id = 1 + await self.default_controller.CommissionOnNetwork( nodeId=th_server_th_node_id, setupPinCode=self.th_server_passcode, From 58ed63d1e6c1daaa00658b1c8a15bad162437f31 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Wed, 4 Sep 2024 21:12:53 -0400 Subject: [PATCH 65/70] Fix ACL XML for MACL and sample conformance (#35411) * Fix ACL cluster ZAP XML and regen ZAP - Remove dead event AccessRestrictionEntryChanged - Set response command for ReviewFabricRestrictions - Set correct optionality for FabricRestrictionReviewUpdate * Fix access control server after XML change * Remove unsupportable commnad * Rename RedirectURL field to ARLRequestFlowUrl * Kick CI * Kick CI * Remove non-longer-applicable files * Increase size of event buffer pool in NIM sample * Restyled by clang-format * Fix format * Remove subscription for event that no longer exists --------- Co-authored-by: Restyled.io --- .../air-purifier-app.matter | 12 +-- .../air-quality-sensor-app.matter | 12 +-- .../all-clusters-app.matter | 12 +-- .../all-clusters-minimal-app.matter | 12 +-- .../bridge-common/bridge-app.matter | 24 ++---- ...p_rootnode_dimmablelight_bCwGYSDpoe.matter | 12 +-- .../rootnode_airpurifier_73a6fe2651.matter | 12 +-- ...umiditysensor_thermostat_56de3d5f45.matter | 12 +-- ...ootnode_airqualitysensor_e63187f6c9.matter | 12 +-- ...ootnode_basicvideoplayer_0ff86e943b.matter | 12 +-- ...de_colortemperaturelight_hbUnzYVeyn.matter | 12 +-- .../rootnode_contactsensor_27f76aeaf5.matter | 12 +-- .../rootnode_contactsensor_lFAGG1bfRO.matter | 12 +-- .../rootnode_dimmablelight_bCwGYSDpoe.matter | 12 +-- ...tnode_dimmablepluginunit_f8a9a0b9d4.matter | 12 +-- .../rootnode_dishwasher_cc105034fe.matter | 12 +-- .../rootnode_doorlock_aNKYAreMXE.matter | 12 +-- ...tnode_extendedcolorlight_8lcaaYJVAa.matter | 12 +-- .../devices/rootnode_fan_7N2TobIlOX.matter | 12 +-- .../rootnode_flowsensor_1zVxHedlaV.matter | 12 +-- .../rootnode_genericswitch_2dfff6e516.matter | 12 +-- .../rootnode_genericswitch_9866e35d0b.matter | 12 +-- ...tnode_heatingcoolingunit_ncdGai1E5a.matter | 12 +-- .../rootnode_humiditysensor_Xyj4gda6Hb.matter | 12 +-- .../rootnode_laundrywasher_fb10d238c8.matter | 12 +-- .../rootnode_lightsensor_lZQycTFcJK.matter | 12 +-- ...rootnode_occupancysensor_iHyVgifZuo.matter | 12 +-- .../rootnode_onofflight_bbs1b7IaOV.matter | 12 +-- .../rootnode_onofflight_samplemei.matter | 12 +-- ...ootnode_onofflightswitch_FsPlMr090Q.matter | 12 +-- ...rootnode_onoffpluginunit_Wtf8ss5EBY.matter | 12 +-- .../rootnode_pressuresensor_s0qC9wLH4k.matter | 12 +-- .../devices/rootnode_pump_5f904818cc.matter | 12 +-- .../devices/rootnode_pump_a811bb33a0.matter | 12 +-- ...eraturecontrolledcabinet_ffdb696680.matter | 12 +-- ...ode_roboticvacuumcleaner_1807ff0c49.matter | 12 +-- ...tnode_roomairconditioner_9cf3607804.matter | 12 +-- .../rootnode_smokecoalarm_686fe0dcb8.matter | 12 +-- .../rootnode_speaker_RpzeXdimqA.matter | 12 +-- ...otnode_temperaturesensor_Qy1zkNW7c3.matter | 12 +-- .../rootnode_thermostat_bm3fb8dhYi.matter | 12 +-- ...otnode_waterleakdetector_0b067acfa3.matter | 12 +-- .../rootnode_windowcovering_RLCxaGi9Yx.matter | 12 +-- .../contact-sensor-app.matter | 12 +-- .../nxp/zap-lit/contact-sensor-app.matter | 12 +-- .../nxp/zap-sit/contact-sensor-app.matter | 12 +-- .../dishwasher-common/dishwasher-app.matter | 12 +-- .../energy-management-app.matter | 12 +-- .../fabric-bridge-app.matter | 24 ++---- .../nxp/zap/laundry-washer-app.matter | 12 +-- .../light-switch-app.matter | 12 +-- .../light-switch-app/qpg/zap/switch.matter | 12 +-- .../lighting-common/lighting-app.matter | 12 +-- .../data_model/lighting-app-ethernet.matter | 12 +-- .../data_model/lighting-app-thread.matter | 12 +-- .../data_model/lighting-app-wifi.matter | 12 +-- .../lighting-common/lighting-app.matter | 12 +-- .../nxp/zap/lighting-on-off.matter | 12 +-- examples/lighting-app/qpg/zap/light.matter | 12 +-- .../data_model/lighting-thread-app.matter | 12 +-- .../data_model/lighting-wifi-app.matter | 12 +-- .../lit-icd-common/lit-icd-server-app.matter | 12 +-- examples/lock-app/lock-common/lock-app.matter | 12 +-- examples/lock-app/nxp/zap/lock-app.matter | 12 +-- examples/lock-app/qpg/zap/lock.matter | 12 +-- .../log-source-common/log-source-app.matter | 12 +-- .../microwave-oven-app.matter | 12 +-- .../linux/include/CHIPProjectAppConfig.h | 3 + .../network-manager-app.matter | 15 ++-- .../network-manager-app.zap | 6 +- .../ota-provider-app.matter | 24 ++---- .../ota-requestor-app.matter | 12 +-- .../placeholder/linux/apps/app1/config.matter | 12 +-- .../placeholder/linux/apps/app2/config.matter | 12 +-- examples/pump-app/pump-common/pump-app.matter | 12 +-- .../silabs/data_model/pump-thread-app.matter | 12 +-- .../silabs/data_model/pump-wifi-app.matter | 12 +-- .../pump-controller-app.matter | 12 +-- .../refrigerator-app.matter | 12 +-- examples/rvc-app/rvc-common/rvc-app.matter | 12 +-- .../smoke-co-alarm-app.matter | 12 +-- .../temperature-measurement.matter | 12 +-- .../nxp/zap/thermostat_matter_thread.matter | 12 +-- .../nxp/zap/thermostat_matter_wifi.matter | 12 +-- .../qpg/zap/thermostaticRadiatorValve.matter | 12 +-- .../thermostat-common/thermostat.matter | 12 +-- .../thread-br-common/thread-br-app.matter | 12 +-- examples/tv-app/tv-common/tv-app.matter | 12 +-- .../tv-casting-common/tv-casting-app.matter | 12 +-- .../virtual-device-app.matter | 12 +-- examples/window-app/common/window-app.matter | 12 +-- .../all-clusters-app/app-templates/access.h | 5 +- .../lighting-app/app-templates/access.h | 5 +- .../access-control-server.cpp | 15 +--- .../chip/access-control-cluster.xml | 13 +--- .../data_model/controller-clusters.matter | 12 +-- .../chip/devicecontroller/ChipClusters.java | 20 ++++- .../devicecontroller/ChipEventStructs.java | 78 ++++--------------- .../devicecontroller/ClusterIDMapping.java | 3 +- .../devicecontroller/ClusterInfoMapping.java | 37 +++++++-- ...usterAccessRestrictionEntryChangedEvent.kt | 55 ------------- ...usterFabricRestrictionReviewUpdateEvent.kt | 41 +++++----- .../chip/devicecontroller/cluster/files.gni | 1 - .../cluster/clusters/AccessControlCluster.kt | 27 ++++++- ...usterAccessRestrictionEntryChangedEvent.kt | 55 ------------- ...usterFabricRestrictionReviewUpdateEvent.kt | 41 +++++----- .../java/matter/controller/cluster/files.gni | 1 - .../CHIPEventTLVValueDecoder.cpp | 66 ++++------------ .../python/chip/clusters/Objects.py | 31 ++------ .../CHIP/zap-generated/MTRBaseClusters.h | 2 +- .../CHIP/zap-generated/MTRBaseClusters.mm | 6 +- .../CHIP/zap-generated/MTRClusterConstants.h | 3 +- .../CHIP/zap-generated/MTRClusterNames.mm | 4 - .../CHIP/zap-generated/MTRClusters.h | 2 +- .../CHIP/zap-generated/MTRClusters.mm | 6 +- .../zap-generated/MTREventTLVValueDecoder.mm | 33 ++------ .../CHIP/zap-generated/MTRStructsObjc.h | 7 +- .../CHIP/zap-generated/MTRStructsObjc.mm | 33 +------- src/python_testing/TC_ACL_2_11.py | 11 +-- .../zap-generated/cluster-objects.cpp | 41 +--------- .../zap-generated/cluster-objects.h | 53 +++---------- .../app-common/zap-generated/ids/Events.h | 6 +- .../zap-generated/cluster/Commands.h | 7 +- .../cluster/logging/DataModelLogger.cpp | 25 +----- .../cluster/logging/DataModelLogger.h | 2 - .../zap-generated/cluster/Commands.h | 13 +++- 126 files changed, 585 insertions(+), 1291 deletions(-) delete mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt delete mode 100644 src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index c35b8b62e24ee6..ef3be8e5f2e630 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index 0566f91f67a953..408754950cdf6b 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both 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 9769afdc262ba0..8debb1a4930f33 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 @@ -811,14 +811,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -845,7 +841,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 9424fab0a17c1c..7c209b80465f18 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index 1cc37299be6645..f1cdf949a70524 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -627,14 +627,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -661,7 +657,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** The Access Control Cluster exposes a data model view of a @@ -756,14 +752,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -790,7 +782,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 79dfef5be486d8..b837d4bbb6423a 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index e4584f1ee4d086..a9706c7fb0fd64 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -481,14 +481,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -515,7 +511,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index d47b3a90922d57..2af9aa19a2f1f5 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter index e155c0bb946563..ef127a4ba46cde 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index f76efbed02e901..60e29aeeb5f96b 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -606,14 +606,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -640,7 +636,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter index 0a591011e1aa1c..b09fc6ffc012ab 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index 830abb4079edae..8b30190553c843 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index eff62c6119120c..3e3a4eaa84963f 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter index 767012e788c629..4c659dcce73dee 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter index b73b9867cce1c3..92b02371029b94 100644 --- a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter +++ b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index c8e41990993d27..07232aa02be8e1 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter index 71f96dbdf077d3..2b27a22610f7b4 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter index 53984bbd0a934d..265dc262215921 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index 05a176ee9ab710..19e0d8a149ea9b 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter index 93eac702dcbc06..eb578e77f624d1 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter index 8748b8cd13b81f..9c8d9477b2c0ef 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 4c8e67c11e7726..a083afc80331bc 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index 84b5d949b6eeba..84675efc397ef9 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter index adc500a4771045..00f7af07eed1b9 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index 06e8ba84d349b6..42e7362bde656d 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter index be3a039189a5ed..902658e2ffd476 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter index 9d7e22c21dc1ac..65a0c9cce398a4 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index 9d4aa0c7362d22..6cbdac26fa5923 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_onofflight_samplemei.matter b/examples/chef/devices/rootnode_onofflight_samplemei.matter index 90131350b3ca47..35addbe1b2cac6 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -704,14 +704,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -738,7 +734,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter index cffe70d9aab388..7c82c5b9b53516 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -651,14 +651,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -685,7 +681,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter index a5e0f5505dffd8..5fe0482fb1e137 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -579,14 +579,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -613,7 +609,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter index 2b9b4036e638f5..44ad0bfb504d30 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.matter b/examples/chef/devices/rootnode_pump_5f904818cc.matter index cf42feded0cee8..e8141a4d66db35 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -481,14 +481,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -515,7 +511,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.matter b/examples/chef/devices/rootnode_pump_a811bb33a0.matter index 78ae33bc847e5d..bb889d64c319e1 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -481,14 +481,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -515,7 +511,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index 7d8c54a3f41c4c..13d8b98e93f7f0 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index ae1989b2777122..2922ddca5d7ace 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index 20b7d6b80d35f5..654c955586b685 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -558,14 +558,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -592,7 +588,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter index 3408fc64e6fc6f..1057b859f6abf3 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter index bf55ae4be3bf03..a4fe9d839c4a48 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -627,14 +627,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -661,7 +657,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter index b3178232de0291..60aacfe955c687 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index 77e88549108fa8..c38c38b0a1d88c 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter index e41e0b8b65d521..dec13bdf452e45 100644 --- a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter index f49ed5824d5ce4..a57c946cfa0f93 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both 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 eb551dd395a9ae..60e67e4c4a7c46 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 @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index 4a3e015ddedb5c..5e877d10e662a1 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index d8d2734e60a98b..e60ea683965225 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index 661a2e74de4f4e..0df498ea2952f4 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -507,14 +507,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -541,7 +537,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index c3401388bae96e..9b9bf1476e0f0e 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index 22f5ae6ccda3be..7df3c29b359f91 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** The Access Control Cluster exposes a data model view of a @@ -538,14 +534,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -572,7 +564,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter index 7ecbd20a6e9d0f..adc4fe3de8065e 100644 --- a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -579,14 +579,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -613,7 +609,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 3909b6073c8b9c..a18f0c9724cda2 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -629,14 +629,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -663,7 +659,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index c93a50bb03e2dc..23033c78bffda8 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -754,14 +754,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -788,7 +784,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter b/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter index 066d3d4729b12d..c19c7d7bf8e67a 100644 --- a/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter +++ b/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter index 9536120f9defb1..c51e6ee8ca0d7f 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter index 5a26a332b8e14d..33d68c727dba51 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter index 08172f4c3a4c42..78eed27958bc67 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 578fa85b4d3c1d..16e722d746b3d1 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index 1f88cfb7687610..0bca04dad59429 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index 8ce75010f66281..6509c9202d54b8 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index d77bd6403bd573..03373bfdda8668 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index 978f277cf1f91a..ae68bac12e3e61 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -683,14 +683,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -717,7 +713,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index e76ccb9372798d..6c5e4af56cbee4 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index a925bf75f55255..2f2b9dd40850d8 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index cb2cbcc52f3263..347ad97fbe2946 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index ee7a955db20f4b..303b079b910cac 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/log-source-app/log-source-common/log-source-app.matter b/examples/log-source-app/log-source-common/log-source-app.matter index e9baa7757f53eb..18f096a55eddfb 100644 --- a/examples/log-source-app/log-source-common/log-source-app.matter +++ b/examples/log-source-app/log-source-common/log-source-app.matter @@ -326,14 +326,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -360,7 +356,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster is used to manage global aspects of the Commissioning flow. */ diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter index cea8d411735738..0ac59afb131cd9 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h b/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h index 1ef9862a272938..c5c31c345b72ec 100644 --- a/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h +++ b/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h @@ -21,5 +21,8 @@ #define CHIP_DEVICE_CONFIG_DEVICE_TYPE 144 // 0x0090 Network Infrastructure Manager #define CHIP_DEVICE_CONFIG_DEVICE_NAME "Network Infrastructure Manager" +// Sufficient space for ArlReviewEvent of several fabrics. +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE (32 * 1024) + // Inherit defaults from config/standalone/CHIPProjectConfig.h #include diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index 57118d365577f1..273b523ce5060f 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -1623,7 +1619,6 @@ endpoint 0 { server cluster AccessControl { emits event AccessControlEntryChanged; emits event AccessControlExtensionChanged; - emits event AccessRestrictionEntryChanged; emits event FabricRestrictionReviewUpdate; callback attribute acl; callback attribute extension; @@ -1635,7 +1630,7 @@ endpoint 0 { callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 1; + ram attribute featureMap default = 3; callback attribute clusterRevision; handle command ReviewFabricRestrictions; diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.zap b/examples/network-manager-app/network-manager-common/network-manager-app.zap index 240cd495a7fb4f..f471bb2d3b135b 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.zap +++ b/examples/network-manager-app/network-manager-common/network-manager-app.zap @@ -503,7 +503,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2393,7 +2393,7 @@ "mfgCode": null, "source": "client", "isIncoming": 1, - "isEnabled": 1 + "isEnabled": 0 } ], "attributes": [ @@ -3886,4 +3886,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter index a066629c9f4ae1..5958192ce981e1 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter @@ -359,14 +359,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -393,7 +389,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** The Access Control Cluster exposes a data model view of a @@ -488,14 +484,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -522,7 +514,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index 3412f30a29b1f9..c61a4908d01f1f 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -558,14 +558,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -592,7 +588,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 96c3b7220841be..bf5e6d6b75af16 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -930,14 +930,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -964,7 +960,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index facd9c94e4547e..26651684750454 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -930,14 +930,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -964,7 +960,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index a356b78b628cc1..7031fc2ecf3d26 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -627,14 +627,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -661,7 +657,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.matter b/examples/pump-app/silabs/data_model/pump-thread-app.matter index f88f26870c0224..7dca9cc390c4af 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.matter +++ b/examples/pump-app/silabs/data_model/pump-thread-app.matter @@ -627,14 +627,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -661,7 +657,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.matter b/examples/pump-app/silabs/data_model/pump-wifi-app.matter index f88f26870c0224..7dca9cc390c4af 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.matter +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.matter @@ -627,14 +627,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -661,7 +657,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index 7365654ce9c65b..0207abc4600cef 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -502,14 +502,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -536,7 +532,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index f028a3b31557c5..892012082c0d71 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -359,14 +359,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -393,7 +389,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 4c0ebdf1acc682..974c0dc73a689c 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -409,14 +409,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -443,7 +439,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index 21d1cebf065fb4..1af9ccc34b0422 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter index 4ebc3dc672d48f..cf4d7159fdbf52 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -359,14 +359,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -393,7 +389,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index cbe6a6280d8ec4..179a2c5bf19a90 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -557,14 +557,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -591,7 +587,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index cd9ddc362e36ce..820bd331ad6a6d 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -557,14 +557,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -591,7 +587,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index 548db02c520b9a..d88d6ec1feee1a 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -557,14 +557,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -591,7 +587,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index a66c2dfdad68ba..6feefe3bba1c14 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -557,14 +557,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -591,7 +587,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/thread-br-app/thread-br-common/thread-br-app.matter b/examples/thread-br-app/thread-br-common/thread-br-app.matter index 1b043a7cdde916..9498dee8be25d3 100644 --- a/examples/thread-br-app/thread-br-common/thread-br-app.matter +++ b/examples/thread-br-app/thread-br-common/thread-br-app.matter @@ -359,14 +359,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -393,7 +389,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index f2a2a6f0affb0f..bd2f29d653067b 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -598,14 +598,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -632,7 +628,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index 196e59a9edc720..3e4fe7fa47bc06 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -758,14 +758,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -792,7 +788,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index 3c20256117f2cb..07baa25e19ebc3 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -579,14 +579,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -613,7 +609,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index f31a1917a5fd0e..61a8208e0cb4bf 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -486,14 +486,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -520,7 +516,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h index 8f0c8ef6cb729a..9b35ecb22d178c 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h @@ -511,7 +511,6 @@ #define GENERATED_ACCESS_READ_EVENT__CLUSTER { \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - 0x0000001F, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } @@ -519,15 +518,13 @@ #define GENERATED_ACCESS_READ_EVENT__EVENT { \ 0x00000000, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - 0x00000002, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ - 0x00000003, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ + 0x00000002, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, event, *privilege*) for read event #define GENERATED_ACCESS_READ_EVENT__PRIVILEGE { \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } diff --git a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h index 45b93e99bae3c8..acef1673384c14 100644 --- a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h +++ b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h @@ -292,7 +292,6 @@ #define GENERATED_ACCESS_READ_EVENT__CLUSTER { \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - 0x0000001F, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } @@ -300,15 +299,13 @@ #define GENERATED_ACCESS_READ_EVENT__EVENT { \ 0x00000000, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - 0x00000002, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ - 0x00000003, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ + 0x00000002, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, event, *privilege*) for read event #define GENERATED_ACCESS_READ_EVENT__PRIVILEGE { \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ - chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } diff --git a/src/app/clusters/access-control-server/access-control-server.cpp b/src/app/clusters/access-control-server/access-control-server.cpp index 295b5535df2f95..d525e555f282e6 100644 --- a/src/app/clusters/access-control-server/access-control-server.cpp +++ b/src/app/clusters/access-control-server/access-control-server.cpp @@ -88,7 +88,7 @@ class AccessControlAttribute : public AttributeAccessInterface, void MarkRestrictionListChanged(FabricIndex fabricIndex) override; void OnFabricRestrictionReviewUpdate(FabricIndex fabricIndex, uint64_t token, Optional instruction, - Optional redirectUrl) override; + Optional arlRequestFlowUrl) override; #endif private: @@ -517,20 +517,13 @@ void AccessControlAttribute::MarkRestrictionListChanged(FabricIndex fabricIndex) } void AccessControlAttribute::OnFabricRestrictionReviewUpdate(FabricIndex fabricIndex, uint64_t token, - Optional instruction, Optional redirectUrl) + Optional instruction, Optional arlRequestFlowUrl) { CHIP_ERROR err; ArlReviewEvent event{ .token = token, .fabricIndex = fabricIndex }; - if (instruction.HasValue()) - { - event.instruction.SetNonNull(instruction.Value()); - } - - if (redirectUrl.HasValue()) - { - event.redirectURL.SetNonNull(redirectUrl.Value()); - } + event.instruction = instruction; + event.ARLRequestFlowUrl = arlRequestFlowUrl; EventNumber eventNumber; SuccessOrExit(err = LogEvent(event, kRootEndpointId, eventNumber)); diff --git a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml index a1595803109bcc..edf1b65e941ad0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml @@ -127,7 +127,7 @@ limitations under the License. CommissioningARL ARL - + This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. @@ -156,16 +156,11 @@ limitations under the License. - - The cluster SHALL send AccessRestrictionEntryChanged events whenever its ARL attribute data is changed by the device maker. - - - - + The cluster SHALL send FabricRestrictionReviewUpdate events to indicate completion of a fabric restriction review. - - + + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index cbe81c4d2e6a04..eac83d868cb375 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -751,14 +751,10 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } - fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { - fabric_idx fabricIndex = 254; - } - - fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { int64u token = 0; - nullable long_char_string instruction = 1; - nullable long_char_string redirectURL = 2; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; fabric_idx fabricIndex = 254; } @@ -785,7 +781,7 @@ cluster AccessControl = 31 { } /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ - fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 9001413960dff3..ae900222e92943 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -3982,11 +3982,11 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void reviewFabricRestrictions(DefaultClusterCallback callback, ArrayList arl) { + public void reviewFabricRestrictions(ReviewFabricRestrictionsResponseCallback callback, ArrayList arl) { reviewFabricRestrictions(callback, arl, 0); } - public void reviewFabricRestrictions(DefaultClusterCallback callback, ArrayList arl, int timedInvokeTimeoutMs) { + public void reviewFabricRestrictions(ReviewFabricRestrictionsResponseCallback callback, ArrayList arl, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); @@ -3998,10 +3998,24 @@ public void reviewFabricRestrictions(DefaultClusterCallback callback, ArrayList< invoke(new InvokeCallbackImpl(callback) { @Override public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); + final long tokenFieldID = 0L; + Long token = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == tokenFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + token = castingValue.value(Long.class); + } + } + } + callback.onSuccess(token); }}, commandId, commandArgs, timedInvokeTimeoutMs); } + public interface ReviewFabricRestrictionsResponseCallback extends BaseClusterCallback { + void onSuccess(Long token); + } + public interface AclAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index 916493fc2b60c3..179b6e396638f9 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -236,79 +236,33 @@ public String toString() { return output.toString(); } } -public static class AccessControlClusterAccessRestrictionEntryChangedEvent { - public Integer fabricIndex; - private static final long FABRIC_INDEX_ID = 254L; - - public AccessControlClusterAccessRestrictionEntryChangedEvent( - Integer fabricIndex - ) { - this.fabricIndex = fabricIndex; - } - - public StructType encodeTlv() { - ArrayList values = new ArrayList<>(); - values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); - - return new StructType(values); - } - - public static AccessControlClusterAccessRestrictionEntryChangedEvent decodeTlv(BaseTLVType tlvValue) { - if (tlvValue == null || tlvValue.type() != TLVType.Struct) { - return null; - } - Integer fabricIndex = null; - for (StructElement element: ((StructType)tlvValue).value()) { - if (element.contextTagNum() == FABRIC_INDEX_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.UInt) { - UIntType castingValue = element.value(UIntType.class); - fabricIndex = castingValue.value(Integer.class); - } - } - } - return new AccessControlClusterAccessRestrictionEntryChangedEvent( - fabricIndex - ); - } - - @Override - public String toString() { - StringBuilder output = new StringBuilder(); - output.append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n"); - output.append("\tfabricIndex: "); - output.append(fabricIndex); - output.append("\n"); - output.append("}\n"); - return output.toString(); - } -} public static class AccessControlClusterFabricRestrictionReviewUpdateEvent { public Long token; - public @Nullable String instruction; - public @Nullable String redirectURL; + public Optional instruction; + public Optional ARLRequestFlowUrl; public Integer fabricIndex; private static final long TOKEN_ID = 0L; private static final long INSTRUCTION_ID = 1L; - private static final long REDIRECT_URL_ID = 2L; + private static final long ARL_REQUEST_FLOW_URL_ID = 2L; private static final long FABRIC_INDEX_ID = 254L; public AccessControlClusterFabricRestrictionReviewUpdateEvent( Long token, - @Nullable String instruction, - @Nullable String redirectURL, + Optional instruction, + Optional ARLRequestFlowUrl, Integer fabricIndex ) { this.token = token; this.instruction = instruction; - this.redirectURL = redirectURL; + this.ARLRequestFlowUrl = ARLRequestFlowUrl; this.fabricIndex = fabricIndex; } public StructType encodeTlv() { ArrayList values = new ArrayList<>(); values.add(new StructElement(TOKEN_ID, new UIntType(token))); - values.add(new StructElement(INSTRUCTION_ID, instruction != null ? new StringType(instruction) : new NullType())); - values.add(new StructElement(REDIRECT_URL_ID, redirectURL != null ? new StringType(redirectURL) : new NullType())); + values.add(new StructElement(INSTRUCTION_ID, instruction.map((nonOptionalinstruction) -> new StringType(nonOptionalinstruction)).orElse(new EmptyType()))); + values.add(new StructElement(ARL_REQUEST_FLOW_URL_ID, ARLRequestFlowUrl.map((nonOptionalARLRequestFlowUrl) -> new StringType(nonOptionalARLRequestFlowUrl)).orElse(new EmptyType()))); values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); return new StructType(values); @@ -319,8 +273,8 @@ public static AccessControlClusterFabricRestrictionReviewUpdateEvent decodeTlv(B return null; } Long token = null; - @Nullable String instruction = null; - @Nullable String redirectURL = null; + Optional instruction = Optional.empty(); + Optional ARLRequestFlowUrl = Optional.empty(); Integer fabricIndex = null; for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == TOKEN_ID) { @@ -331,12 +285,12 @@ public static AccessControlClusterFabricRestrictionReviewUpdateEvent decodeTlv(B } else if (element.contextTagNum() == INSTRUCTION_ID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - instruction = castingValue.value(String.class); + instruction = Optional.of(castingValue.value(String.class)); } - } else if (element.contextTagNum() == REDIRECT_URL_ID) { + } else if (element.contextTagNum() == ARL_REQUEST_FLOW_URL_ID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - redirectURL = castingValue.value(String.class); + ARLRequestFlowUrl = Optional.of(castingValue.value(String.class)); } } else if (element.contextTagNum() == FABRIC_INDEX_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -348,7 +302,7 @@ public static AccessControlClusterFabricRestrictionReviewUpdateEvent decodeTlv(B return new AccessControlClusterFabricRestrictionReviewUpdateEvent( token, instruction, - redirectURL, + ARLRequestFlowUrl, fabricIndex ); } @@ -363,8 +317,8 @@ public String toString() { output.append("\tinstruction: "); output.append(instruction); output.append("\n"); - output.append("\tredirectURL: "); - output.append(redirectURL); + output.append("\tARLRequestFlowUrl: "); + output.append(ARLRequestFlowUrl); output.append("\n"); output.append("\tfabricIndex: "); output.append(fabricIndex); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index e0099ccf4c87dc..8ae6ae6fa0dac5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -1717,8 +1717,7 @@ public static Attribute value(long id) throws NoSuchFieldError { public enum Event { AccessControlEntryChanged(0L), AccessControlExtensionChanged(1L), - AccessRestrictionEntryChanged(2L), - FabricRestrictionReviewUpdate(3L),; + FabricRestrictionReviewUpdate(2L),; private final long id; Event(long id) { this.id = id; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 55659d8463581d..b65ff7bcb7f175 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -1341,6 +1341,28 @@ public void onError(Exception ex) { } } + + public static class DelegatedAccessControlClusterReviewFabricRestrictionsResponseCallback implements ChipClusters.AccessControlCluster.ReviewFabricRestrictionsResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Long token) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo tokenResponseValue = new CommandResponseInfo("token", "Long"); + responseValues.put(tokenResponseValue, token); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } public static class DelegatedAccessControlClusterAclAttributeCallback implements ChipClusters.AccessControlCluster.AclAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -23368,14 +23390,15 @@ public Map> getCommandMap() { InteractionInfo accessControlreviewFabricRestrictionsInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.AccessControlCluster) cluster) - .reviewFabricRestrictions((DefaultClusterCallback) callback - , (ArrayList) - commandArguments.get("arl") - ); - }, - () -> new DelegatedDefaultClusterCallback(), + .reviewFabricRestrictions((ChipClusters.AccessControlCluster.ReviewFabricRestrictionsResponseCallback) callback + , (ArrayList) + commandArguments.get("arl") + + ); + }, + () -> new DelegatedAccessControlClusterReviewFabricRestrictionsResponseCallback(), accessControlreviewFabricRestrictionsCommandParams - ); + ); accessControlClusterInteractionInfoMap.put("reviewFabricRestrictions", accessControlreviewFabricRestrictionsInteractionInfo); commandMap.put("accessControl", accessControlClusterInteractionInfoMap); diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt deleted file mode 100644 index 56d9b39e1a005e..00000000000000 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package chip.devicecontroller.cluster.eventstructs - -import chip.devicecontroller.cluster.* -import matter.tlv.ContextSpecificTag -import matter.tlv.Tag -import matter.tlv.TlvReader -import matter.tlv.TlvWriter - -class AccessControlClusterAccessRestrictionEntryChangedEvent(val fabricIndex: UInt) { - override fun toString(): String = buildString { - append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n") - append("\tfabricIndex : $fabricIndex\n") - append("}\n") - } - - fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { - tlvWriter.apply { - startStructure(tlvTag) - put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) - endStructure() - } - } - - companion object { - private const val TAG_FABRIC_INDEX = 254 - - fun fromTlv( - tlvTag: Tag, - tlvReader: TlvReader, - ): AccessControlClusterAccessRestrictionEntryChangedEvent { - tlvReader.enterStructure(tlvTag) - val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) - - tlvReader.exitContainer() - - return AccessControlClusterAccessRestrictionEntryChangedEvent(fabricIndex) - } - } -} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt index 7ea3d3fe02707d..2f2f4bde9aaf46 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.eventstructs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -24,15 +25,15 @@ import matter.tlv.TlvWriter class AccessControlClusterFabricRestrictionReviewUpdateEvent( val token: ULong, - val instruction: String?, - val redirectURL: String?, + val instruction: Optional, + val ARLRequestFlowUrl: Optional, val fabricIndex: UInt, ) { override fun toString(): String = buildString { append("AccessControlClusterFabricRestrictionReviewUpdateEvent {\n") append("\ttoken : $token\n") append("\tinstruction : $instruction\n") - append("\tredirectURL : $redirectURL\n") + append("\tARLRequestFlowUrl : $ARLRequestFlowUrl\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") } @@ -41,15 +42,13 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( tlvWriter.apply { startStructure(tlvTag) put(ContextSpecificTag(TAG_TOKEN), token) - if (instruction != null) { - put(ContextSpecificTag(TAG_INSTRUCTION), instruction) - } else { - putNull(ContextSpecificTag(TAG_INSTRUCTION)) + if (instruction.isPresent) { + val optinstruction = instruction.get() + put(ContextSpecificTag(TAG_INSTRUCTION), optinstruction) } - if (redirectURL != null) { - put(ContextSpecificTag(TAG_REDIRECT_URL), redirectURL) - } else { - putNull(ContextSpecificTag(TAG_REDIRECT_URL)) + if (ARLRequestFlowUrl.isPresent) { + val optARLRequestFlowUrl = ARLRequestFlowUrl.get() + put(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL), optARLRequestFlowUrl) } put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() @@ -59,7 +58,7 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( companion object { private const val TAG_TOKEN = 0 private const val TAG_INSTRUCTION = 1 - private const val TAG_REDIRECT_URL = 2 + private const val TAG_ARL_REQUEST_FLOW_URL = 2 private const val TAG_FABRIC_INDEX = 254 fun fromTlv( @@ -69,18 +68,16 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( tlvReader.enterStructure(tlvTag) val token = tlvReader.getULong(ContextSpecificTag(TAG_TOKEN)) val instruction = - if (!tlvReader.isNull()) { - tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION)) + if (tlvReader.isNextTag(ContextSpecificTag(TAG_INSTRUCTION))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION))) } else { - tlvReader.getNull(ContextSpecificTag(TAG_INSTRUCTION)) - null + Optional.empty() } - val redirectURL = - if (!tlvReader.isNull()) { - tlvReader.getString(ContextSpecificTag(TAG_REDIRECT_URL)) + val ARLRequestFlowUrl = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL))) } else { - tlvReader.getNull(ContextSpecificTag(TAG_REDIRECT_URL)) - null + Optional.empty() } val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) @@ -89,7 +86,7 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( return AccessControlClusterFabricRestrictionReviewUpdateEvent( token, instruction, - redirectURL, + ARLRequestFlowUrl, fabricIndex, ) } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index 3642d238e664f7..bbaa6112dd9dea 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -164,7 +164,6 @@ structs_sources = [ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt", - "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccountLoginClusterLoggedOutEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt index 099162a899b419..e0a5c595acf19b 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt @@ -46,6 +46,8 @@ class AccessControlCluster( private val controller: MatterController, private val endpointId: UShort, ) { + class ReviewFabricRestrictionsResponse(val token: ULong) + class AclAttribute(val value: List) sealed class AclAttributeSubscriptionState { @@ -136,7 +138,7 @@ class AccessControlCluster( suspend fun reviewFabricRestrictions( arl: List, timedInvokeTimeout: Duration? = null, - ) { + ): ReviewFabricRestrictionsResponse { val commandId: UInt = 0u val tlvWriter = TlvWriter() @@ -159,6 +161,29 @@ class AccessControlCluster( val response: InvokeResponse = controller.invoke(request) logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_TOKEN: Int = 0 + var token_decoded: ULong? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_TOKEN)) { + token_decoded = tlvReader.getULong(tag) + } else { + tlvReader.skipElement() + } + } + + if (token_decoded == null) { + throw IllegalStateException("token not found in TLV") + } + + tlvReader.exitContainer() + + return ReviewFabricRestrictionsResponse(token_decoded) } suspend fun readAclAttribute(): AclAttribute { diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt deleted file mode 100644 index 8a272f8854ae12..00000000000000 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package matter.controller.cluster.eventstructs - -import matter.controller.cluster.* -import matter.tlv.ContextSpecificTag -import matter.tlv.Tag -import matter.tlv.TlvReader -import matter.tlv.TlvWriter - -class AccessControlClusterAccessRestrictionEntryChangedEvent(val fabricIndex: UByte) { - override fun toString(): String = buildString { - append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n") - append("\tfabricIndex : $fabricIndex\n") - append("}\n") - } - - fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { - tlvWriter.apply { - startStructure(tlvTag) - put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) - endStructure() - } - } - - companion object { - private const val TAG_FABRIC_INDEX = 254 - - fun fromTlv( - tlvTag: Tag, - tlvReader: TlvReader, - ): AccessControlClusterAccessRestrictionEntryChangedEvent { - tlvReader.enterStructure(tlvTag) - val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) - - tlvReader.exitContainer() - - return AccessControlClusterAccessRestrictionEntryChangedEvent(fabricIndex) - } - } -} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt index 6bf03e6afc8c13..1a9670ca19d8db 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.eventstructs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -24,15 +25,15 @@ import matter.tlv.TlvWriter class AccessControlClusterFabricRestrictionReviewUpdateEvent( val token: ULong, - val instruction: String?, - val redirectURL: String?, + val instruction: Optional, + val ARLRequestFlowUrl: Optional, val fabricIndex: UByte, ) { override fun toString(): String = buildString { append("AccessControlClusterFabricRestrictionReviewUpdateEvent {\n") append("\ttoken : $token\n") append("\tinstruction : $instruction\n") - append("\tredirectURL : $redirectURL\n") + append("\tARLRequestFlowUrl : $ARLRequestFlowUrl\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") } @@ -41,15 +42,13 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( tlvWriter.apply { startStructure(tlvTag) put(ContextSpecificTag(TAG_TOKEN), token) - if (instruction != null) { - put(ContextSpecificTag(TAG_INSTRUCTION), instruction) - } else { - putNull(ContextSpecificTag(TAG_INSTRUCTION)) + if (instruction.isPresent) { + val optinstruction = instruction.get() + put(ContextSpecificTag(TAG_INSTRUCTION), optinstruction) } - if (redirectURL != null) { - put(ContextSpecificTag(TAG_REDIRECT_URL), redirectURL) - } else { - putNull(ContextSpecificTag(TAG_REDIRECT_URL)) + if (ARLRequestFlowUrl.isPresent) { + val optARLRequestFlowUrl = ARLRequestFlowUrl.get() + put(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL), optARLRequestFlowUrl) } put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() @@ -59,7 +58,7 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( companion object { private const val TAG_TOKEN = 0 private const val TAG_INSTRUCTION = 1 - private const val TAG_REDIRECT_URL = 2 + private const val TAG_ARL_REQUEST_FLOW_URL = 2 private const val TAG_FABRIC_INDEX = 254 fun fromTlv( @@ -69,18 +68,16 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( tlvReader.enterStructure(tlvTag) val token = tlvReader.getULong(ContextSpecificTag(TAG_TOKEN)) val instruction = - if (!tlvReader.isNull()) { - tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION)) + if (tlvReader.isNextTag(ContextSpecificTag(TAG_INSTRUCTION))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION))) } else { - tlvReader.getNull(ContextSpecificTag(TAG_INSTRUCTION)) - null + Optional.empty() } - val redirectURL = - if (!tlvReader.isNull()) { - tlvReader.getString(ContextSpecificTag(TAG_REDIRECT_URL)) + val ARLRequestFlowUrl = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_ARL_REQUEST_FLOW_URL))) } else { - tlvReader.getNull(ContextSpecificTag(TAG_REDIRECT_URL)) - null + Optional.empty() } val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) @@ -89,7 +86,7 @@ class AccessControlClusterFabricRestrictionReviewUpdateEvent( return AccessControlClusterFabricRestrictionReviewUpdateEvent( token, instruction, - redirectURL, + ARLRequestFlowUrl, fabricIndex, ) } diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index 90d1e060b724c3..1f287a13ae0ff2 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -164,7 +164,6 @@ matter_structs_sources = [ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt", - "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccountLoginClusterLoggedOutEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt", diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index e695cd1dc794a2..d9bf294c0f8486 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -500,46 +500,6 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return value; } - case Events::AccessRestrictionEntryChanged::Id: { - Events::AccessRestrictionEntryChanged::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value_fabricIndex; - std::string value_fabricIndexClassName = "java/lang/Integer"; - std::string value_fabricIndexCtorSignature = "(I)V"; - jint jnivalue_fabricIndex = static_cast(cppValue.fabricIndex); - chip::JniReferences::GetInstance().CreateBoxedObject(value_fabricIndexClassName.c_str(), - value_fabricIndexCtorSignature.c_str(), jnivalue_fabricIndex, - value_fabricIndex); - - jclass accessRestrictionEntryChangedStructClass; - err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent", - accessRestrictionEntryChangedStructClass); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Could not find class ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent"); - return nullptr; - } - - jmethodID accessRestrictionEntryChangedStructCtor; - err = chip::JniReferences::GetInstance().FindMethod(env, accessRestrictionEntryChangedStructClass, "", - "(Ljava/lang/Integer;)V", &accessRestrictionEntryChangedStructCtor); - if (err != CHIP_NO_ERROR || accessRestrictionEntryChangedStructCtor == nullptr) - { - ChipLogError(Zcl, - "Could not find ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent constructor"); - return nullptr; - } - - jobject value = env->NewObject(accessRestrictionEntryChangedStructClass, accessRestrictionEntryChangedStructCtor, - value_fabricIndex); - - return value; - } case Events::FabricRestrictionReviewUpdate::Id: { Events::FabricRestrictionReviewUpdate::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); @@ -555,25 +515,29 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & value_tokenClassName.c_str(), value_tokenCtorSignature.c_str(), jnivalue_token, value_token); jobject value_instruction; - if (cppValue.instruction.IsNull()) + if (!cppValue.instruction.HasValue()) { - value_instruction = nullptr; + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_instruction); } else { - LogErrorOnFailure( - chip::JniReferences::GetInstance().CharToStringUTF(cppValue.instruction.Value(), value_instruction)); + jobject value_instructionInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.instruction.Value(), + value_instructionInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(value_instructionInsideOptional, value_instruction); } - jobject value_redirectURL; - if (cppValue.redirectURL.IsNull()) + jobject value_ARLRequestFlowUrl; + if (!cppValue.ARLRequestFlowUrl.HasValue()) { - value_redirectURL = nullptr; + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_ARLRequestFlowUrl); } else { - LogErrorOnFailure( - chip::JniReferences::GetInstance().CharToStringUTF(cppValue.redirectURL.Value(), value_redirectURL)); + jobject value_ARLRequestFlowUrlInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.ARLRequestFlowUrl.Value(), + value_ARLRequestFlowUrlInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(value_ARLRequestFlowUrlInsideOptional, value_ARLRequestFlowUrl); } jobject value_fabricIndex; @@ -597,7 +561,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jmethodID fabricRestrictionReviewUpdateStructCtor; err = chip::JniReferences::GetInstance().FindMethod( env, fabricRestrictionReviewUpdateStructClass, "", - "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)V", + "(Ljava/lang/Long;Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/Integer;)V", &fabricRestrictionReviewUpdateStructCtor); if (err != CHIP_NO_ERROR || fabricRestrictionReviewUpdateStructCtor == nullptr) { @@ -607,7 +571,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } jobject value = env->NewObject(fabricRestrictionReviewUpdateStructClass, fabricRestrictionReviewUpdateStructCtor, - value_token, value_instruction, value_redirectURL, value_fabricIndex); + value_token, value_instruction, value_ARLRequestFlowUrl, value_fabricIndex); return value; } diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 482fe33f61c2c1..688b4d6d4d4d08 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -3096,7 +3096,7 @@ class ReviewFabricRestrictions(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000001F command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[str] = 'ReviewFabricRestrictionsResponse' @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3387,25 +3387,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: latestValue: 'typing.Union[Nullable, AccessControl.Structs.AccessControlExtensionStruct]' = NullValue fabricIndex: 'uint' = 0 - @dataclass - class AccessRestrictionEntryChanged(ClusterEvent): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000001F - - @ChipUtility.classproperty - def event_id(cls) -> int: - return 0x00000002 - - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), - ]) - - fabricIndex: 'uint' = 0 - @dataclass class FabricRestrictionReviewUpdate(ClusterEvent): @ChipUtility.classproperty @@ -3414,21 +3395,21 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def event_id(cls) -> int: - return 0x00000003 + return 0x00000002 @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ ClusterObjectFieldDescriptor(Label="token", Tag=0, Type=uint), - ClusterObjectFieldDescriptor(Label="instruction", Tag=1, Type=typing.Union[Nullable, str]), - ClusterObjectFieldDescriptor(Label="redirectURL", Tag=2, Type=typing.Union[Nullable, str]), + ClusterObjectFieldDescriptor(Label="instruction", Tag=1, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="ARLRequestFlowUrl", Tag=2, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) token: 'uint' = 0 - instruction: 'typing.Union[Nullable, str]' = NullValue - redirectURL: 'typing.Union[Nullable, str]' = NullValue + instruction: 'typing.Optional[str]' = None + ARLRequestFlowUrl: 'typing.Optional[str]' = None fabricIndex: 'uint' = 0 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 9360e68c590fcd..60c65ac382561d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -1012,7 +1012,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ -- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(void (^)(MTRAccessControlClusterReviewFabricRestrictionsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeACLWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 696d1f8058b3ed..84e03c5adeb430 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -7742,7 +7742,7 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterAccessControl -- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(MTRStatusCompletion)completion +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(void (^)(MTRAccessControlClusterReviewFabricRestrictionsResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { params = [[MTRAccessControlClusterReviewFabricRestrictionsParams @@ -7750,7 +7750,7 @@ - (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricR } auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); + completion(response, error); }; auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; @@ -7762,7 +7762,7 @@ - (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricR commandPayload:params timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil + responseClass:MTRAccessControlClusterReviewFabricRestrictionsResponseParams.class queue:self.callbackQueue completion:responseHandler]; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 1ffa3ecc58db7a..3ab34174b53453 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -7143,8 +7143,7 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { // Cluster AccessControl events MTREventIDTypeClusterAccessControlEventAccessControlEntryChangedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTREventIDTypeClusterAccessControlEventAccessControlExtensionChangedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, - MTREventIDTypeClusterAccessControlEventAccessRestrictionEntryChangedID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, // Cluster Actions deprecated event names MTRClusterActionsEventStateChangedID diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 69ec92c0e5217a..f5beab931c57fa 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -9515,10 +9515,6 @@ result = @"AccessControlExtensionChanged"; break; - case MTREventIDTypeClusterAccessControlEventAccessRestrictionEntryChangedID: - result = @"AccessRestrictionEntryChanged"; - break; - case MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID: result = @"FabricRestrictionReviewUpdate"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index a717868edf09fc..e2197784a01237 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -510,7 +510,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterAccessControl : MTRGenericCluster -- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRAccessControlClusterReviewFabricRestrictionsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeACLWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 6f6db16eb72210..26d1ec95ecf1f6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -1617,7 +1617,7 @@ - (instancetype)initWithDevice:(MTRDevice *)device endpoint:(uint16_t)endpoint q @implementation MTRClusterAccessControl -- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRAccessControlClusterReviewFabricRestrictionsResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { params = [[MTRAccessControlClusterReviewFabricRestrictionsParams @@ -1625,7 +1625,7 @@ - (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricR } auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); + completion(response, error); }; auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; @@ -1639,7 +1639,7 @@ - (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricR expectedValueInterval:expectedValueIntervalMs timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil + responseClass:MTRAccessControlClusterReviewFabricRestrictionsResponseParams.class queue:self.callbackQueue completion:responseHandler]; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 99f43ea97f0360..85dcba3510205e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -304,23 +304,6 @@ static id _Nullable DecodeEventPayloadForAccessControlCluster(EventId aEventId, return value; } - case Events::AccessRestrictionEntryChanged::Id: { - Events::AccessRestrictionEntryChanged::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - - __auto_type * value = [MTRAccessControlClusterAccessRestrictionEntryChangedEvent new]; - - do { - NSNumber * _Nonnull memberValue; - memberValue = [NSNumber numberWithUnsignedChar:cppValue.fabricIndex]; - value.fabricIndex = memberValue; - } while (0); - - return value; - } case Events::FabricRestrictionReviewUpdate::Id: { Events::FabricRestrictionReviewUpdate::DecodableType cppValue; *aError = DataModel::Decode(aReader, cppValue); @@ -337,31 +320,31 @@ static id _Nullable DecodeEventPayloadForAccessControlCluster(EventId aEventId, } while (0); do { NSString * _Nullable memberValue; - if (cppValue.instruction.IsNull()) { - memberValue = nil; - } else { + if (cppValue.instruction.HasValue()) { memberValue = AsString(cppValue.instruction.Value()); if (memberValue == nil) { CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; *aError = err; return nil; } + } else { + memberValue = nil; } value.instruction = memberValue; } while (0); do { NSString * _Nullable memberValue; - if (cppValue.redirectURL.IsNull()) { - memberValue = nil; - } else { - memberValue = AsString(cppValue.redirectURL.Value()); + if (cppValue.ARLRequestFlowUrl.HasValue()) { + memberValue = AsString(cppValue.ARLRequestFlowUrl.Value()); if (memberValue == nil) { CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; *aError = err; return nil; } + } else { + memberValue = nil; } - value.redirectURL = memberValue; + value.arlRequestFlowUrl = memberValue; } while (0); do { NSNumber * _Nonnull memberValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 93632e8935cbc6..b0dcf5afb48858 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -151,16 +151,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @end -MTR_PROVISIONALLY_AVAILABLE -@interface MTRAccessControlClusterAccessRestrictionEntryChangedEvent : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; -@end - MTR_PROVISIONALLY_AVAILABLE @interface MTRAccessControlClusterFabricRestrictionReviewUpdateEvent : NSObject @property (nonatomic, copy) NSNumber * _Nonnull token MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSString * _Nullable instruction MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSString * _Nullable redirectURL MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable arlRequestFlowUrl MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 917332e40cff8f..2d5a3835a98f4b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -532,33 +532,6 @@ - (NSString *)description @end -@implementation MTRAccessControlClusterAccessRestrictionEntryChangedEvent -- (instancetype)init -{ - if (self = [super init]) { - - _fabricIndex = @(0); - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone -{ - auto other = [[MTRAccessControlClusterAccessRestrictionEntryChangedEvent alloc] init]; - - other.fabricIndex = self.fabricIndex; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: fabricIndex:%@; >", NSStringFromClass([self class]), _fabricIndex]; - return descriptionString; -} - -@end - @implementation MTRAccessControlClusterFabricRestrictionReviewUpdateEvent - (instancetype)init { @@ -568,7 +541,7 @@ - (instancetype)init _instruction = nil; - _redirectURL = nil; + _arlRequestFlowUrl = nil; _fabricIndex = @(0); } @@ -581,7 +554,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.token = self.token; other.instruction = self.instruction; - other.redirectURL = self.redirectURL; + other.arlRequestFlowUrl = self.arlRequestFlowUrl; other.fabricIndex = self.fabricIndex; return other; @@ -589,7 +562,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: token:%@; instruction:%@; redirectURL:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _token, _instruction, _redirectURL, _fabricIndex]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: token:%@; instruction:%@; arlRequestFlowUrl:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _token, _instruction, _arlRequestFlowUrl, _fabricIndex]; return descriptionString; } diff --git a/src/python_testing/TC_ACL_2_11.py b/src/python_testing/TC_ACL_2_11.py index a9f63b22d5c798..ce8034a82f5f74 100644 --- a/src/python_testing/TC_ACL_2_11.py +++ b/src/python_testing/TC_ACL_2_11.py @@ -173,19 +173,10 @@ async def test_TC_ACL_2_11(self): arru_cb = EventChangeCallback(Clusters.AccessControl.Events.FabricRestrictionReviewUpdate, arru_queue) urgent = 1 - subscription_arru = await dev_ctrl.ReadEvent(dut_node_id, events=[(0, Clusters.AccessControl.Events.FabricRestrictionReviewUpdate, urgent)], reportInterval=(1, 5), keepSubscriptions=True, autoResubscribe=False) + subscription_arru = await dev_ctrl.ReadEvent(dut_node_id, events=[(0, Clusters.AccessControl.Events.FabricRestrictionReviewUpdate, urgent)], reportInterval=(0, 30), keepSubscriptions=True, autoResubscribe=False) subscription_arru.SetEventUpdateCallback(callback=arru_cb) # end - # Belongs to step 7, but needs to be subscribed before executing step 5: begin - arec_queue = queue.Queue() - arec_cb = EventChangeCallback(Clusters.AccessControl.Events.AccessRestrictionEntryChanged, arec_queue) - - urgent = 1 - subscription_arec = await dev_ctrl.ReadEvent(dut_node_id, events=[(0, Clusters.AccessControl.Events.AccessRestrictionEntryChanged, urgent)], reportInterval=(1, 5), keepSubscriptions=True, autoResubscribe=False) - subscription_arec.SetEventUpdateCallback(callback=arec_cb) - # end - self.step(5) root_node_endpoint = 0 root_part_list = await dev_ctrl.ReadAttribute(dut_node_id, [(root_node_endpoint, Clusters.Descriptor.Attributes.PartsList)]) diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 354eb75feb77de..e75804a86709e2 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -2717,41 +2717,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace AccessControlExtensionChanged. -namespace AccessRestrictionEntryChanged { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - TLV::TLVType outer; - ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); - return aWriter.EndContainer(outer); -} - -CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) -{ - detail::StructDecodeIterator __iterator(reader); - while (true) - { - auto __element = __iterator.Next(); - if (std::holds_alternative(__element)) - { - return std::get(__element); - } - - CHIP_ERROR err = CHIP_NO_ERROR; - const uint8_t __context_tag = std::get(__element); - - if (__context_tag == to_underlying(Fields::kFabricIndex)) - { - err = DataModel::Decode(reader, fabricIndex); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} -} // namespace AccessRestrictionEntryChanged. namespace FabricRestrictionReviewUpdate { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -2759,7 +2724,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kToken), token)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kInstruction), instruction)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRedirectURL), redirectURL)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kARLRequestFlowUrl), ARLRequestFlowUrl)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); return aWriter.EndContainer(outer); } @@ -2786,9 +2751,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, instruction); } - else if (__context_tag == to_underlying(Fields::kRedirectURL)) + else if (__context_tag == to_underlying(Fields::kARLRequestFlowUrl)) { - err = DataModel::Decode(reader, redirectURL); + err = DataModel::Decode(reader, ARLRequestFlowUrl); } else if (__context_tag == to_underlying(Fields::kFabricIndex)) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index e96a078ea28f58..b2fc8fb5a43f63 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -2928,7 +2928,7 @@ struct Type CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - using ResponseType = DataModel::NullObjectType; + using ResponseType = Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType; static constexpr bool MustUseTimedInvoke() { return false; } }; @@ -3228,50 +3228,15 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; } // namespace AccessControlExtensionChanged -namespace AccessRestrictionEntryChanged { -static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; - -enum class Fields : uint8_t -{ - kFabricIndex = 254, -}; - -struct Type -{ -public: - static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } - static constexpr EventId GetEventId() { return Events::AccessRestrictionEntryChanged::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } - static constexpr bool kIsFabricScoped = true; - - chip::FabricIndex fabricIndex = static_cast(0); - - auto GetFabricIndex() const { return fabricIndex; } - - CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; -}; - -struct DecodableType -{ -public: - static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } - static constexpr EventId GetEventId() { return Events::AccessRestrictionEntryChanged::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } - - chip::FabricIndex fabricIndex = static_cast(0); - - CHIP_ERROR Decode(TLV::TLVReader & reader); -}; -} // namespace AccessRestrictionEntryChanged namespace FabricRestrictionReviewUpdate { static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; enum class Fields : uint8_t { - kToken = 0, - kInstruction = 1, - kRedirectURL = 2, - kFabricIndex = 254, + kToken = 0, + kInstruction = 1, + kARLRequestFlowUrl = 2, + kFabricIndex = 254, }; struct Type @@ -3283,8 +3248,8 @@ struct Type static constexpr bool kIsFabricScoped = true; uint64_t token = static_cast(0); - DataModel::Nullable instruction; - DataModel::Nullable redirectURL; + Optional instruction; + Optional ARLRequestFlowUrl; chip::FabricIndex fabricIndex = static_cast(0); auto GetFabricIndex() const { return fabricIndex; } @@ -3300,8 +3265,8 @@ struct DecodableType static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } uint64_t token = static_cast(0); - DataModel::Nullable instruction; - DataModel::Nullable redirectURL; + Optional instruction; + Optional ARLRequestFlowUrl; chip::FabricIndex fabricIndex = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h index 01caeeadee4188..0756af5268e9ed 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h @@ -36,12 +36,8 @@ namespace AccessControlExtensionChanged { static constexpr EventId Id = 0x00000001; } // namespace AccessControlExtensionChanged -namespace AccessRestrictionEntryChanged { -static constexpr EventId Id = 0x00000002; -} // namespace AccessRestrictionEntryChanged - namespace FabricRestrictionReviewUpdate { -static constexpr EventId Id = 0x00000003; +static constexpr EventId Id = 0x00000002; } // namespace FabricRestrictionReviewUpdate } // namespace Events diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 5e6f77d66bde82..1c6f6af5db03ff 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -1273,8 +1273,7 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | Events: | | | * AccessControlEntryChanged | 0x0000 | | * AccessControlExtensionChanged | 0x0001 | -| * AccessRestrictionEntryChanged | 0x0002 | -| * FabricRestrictionReviewUpdate | 0x0003 | +| * FabricRestrictionReviewUpdate | 0x0002 | \*----------------------------------------------------------------------------*/ /* @@ -16285,8 +16284,6 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands make_unique(Id, "access-control-entry-changed", Events::AccessControlEntryChanged::Id, credsIssuerConfig), // make_unique(Id, "access-control-extension-changed", Events::AccessControlExtensionChanged::Id, credsIssuerConfig), // - make_unique(Id, "access-restriction-entry-changed", Events::AccessRestrictionEntryChanged::Id, - credsIssuerConfig), // make_unique(Id, "fabric-restriction-review-update", Events::FabricRestrictionReviewUpdate::Id, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // @@ -16294,8 +16291,6 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique(Id, "access-control-extension-changed", Events::AccessControlExtensionChanged::Id, credsIssuerConfig), // - make_unique(Id, "access-restriction-entry-changed", Events::AccessRestrictionEntryChanged::Id, - credsIssuerConfig), // make_unique(Id, "fabric-restriction-review-update", Events::FabricRestrictionReviewUpdate::Id, credsIssuerConfig), // }; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index b61e6e9bae9232..f8946b7327fabd 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -5613,22 +5613,6 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } -CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const AccessControl::Events::AccessRestrictionEntryChanged::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); - { - CHIP_ERROR err = DataModelLogger::LogValue("FabricIndex", indent + 1, value.fabricIndex); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'FabricIndex'"); - return err; - } - } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType & value) { @@ -5650,10 +5634,10 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } } { - CHIP_ERROR err = DataModelLogger::LogValue("RedirectURL", indent + 1, value.redirectURL); + CHIP_ERROR err = DataModelLogger::LogValue("ARLRequestFlowUrl", indent + 1, value.ARLRequestFlowUrl); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RedirectURL'"); + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ARLRequestFlowUrl'"); return err; } } @@ -20270,11 +20254,6 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("AccessControlExtensionChanged", 1, value); } - case AccessControl::Events::AccessRestrictionEntryChanged::Id: { - chip::app::Clusters::AccessControl::Events::AccessRestrictionEntryChanged::DecodableType value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("AccessRestrictionEntryChanged", 1, value); - } case AccessControl::Events::FabricRestrictionReviewUpdate::Id: { chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index c2b9cfbe337afd..ce1aa0b46f01da 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -436,8 +436,6 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Events::AccessControlEntryChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Events::AccessControlExtensionChanged::DecodableType & value); -static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::AccessControl::Events::AccessRestrictionEntryChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 7fdfb6f9689c01..85632c6b4c8520 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -10090,8 +10090,7 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | Events: | | | * AccessControlEntryChanged | 0x0000 | | * AccessControlExtensionChanged | 0x0001 | -| * AccessRestrictionEntryChanged | 0x0002 | -| * FabricRestrictionReviewUpdate | 0x0003 | +| * FabricRestrictionReviewUpdate | 0x0002 | \*----------------------------------------------------------------------------*/ #if MTR_ENABLE_PROVISIONAL @@ -10153,12 +10152,18 @@ class AccessControlReviewFabricRestrictions : public ClusterCommand { uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { [cluster reviewFabricRestrictionsWithParams:params completion: - ^(NSError * _Nullable error) { + ^(MTRAccessControlClusterReviewFabricRestrictionsResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } responsesNeeded--; if (error != nil) { mError = error; LogNSError("Error", error); - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + constexpr chip::CommandId responseId = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); } if (responsesNeeded == 0) { SetCommandExitStatus(mError); From 17b1a38e909e7874593bcb87c31be03a5866f1d4 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 4 Sep 2024 21:22:32 -0400 Subject: [PATCH 66/70] MACL: Add checks that ARL / CommissioningARL are populated or not populated as required by the test (#35413) * Add check for unpopulated ARLs * linter * Add check to TC-ACL-2.11 for populated ARLs --- src/python_testing/TC_ACL_2_11.py | 11 +++- src/python_testing/TestConformanceTest.py | 50 ++++++++++++++++++- .../basic_composition_support.py | 24 +++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_ACL_2_11.py b/src/python_testing/TC_ACL_2_11.py index ce8034a82f5f74..a580cc2575017e 100644 --- a/src/python_testing/TC_ACL_2_11.py +++ b/src/python_testing/TC_ACL_2_11.py @@ -31,6 +31,7 @@ import queue import chip.clusters as Clusters +from basic_composition_support import arls_populated from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction, ValueDecodeFailure from chip.clusters.ClusterObjects import ALL_ACCEPTED_COMMANDS, ALL_ATTRIBUTES, ALL_CLUSTERS, ClusterEvent from chip.clusters.Objects import AccessControl @@ -82,7 +83,7 @@ def desc_TC_ACL_2_11(self) -> str: def steps_TC_ACL_2_11(self) -> list[TestStep]: steps = [ - TestStep(1, "Commissioning, already done"), + TestStep(1, "Commissioning (already done) and precondition checks", is_commissioning=True), TestStep(2, "TH1 reads DUT Endpoint 0 AccessControl cluster CommissioningARL attribute"), TestStep(3, "TH1 reads DUT Endpoint 0 AccessControl cluster ARL attribute"), TestStep(4, "For each entry in ARL, iterate over each restriction and attempt access the restriction's ID on the Endpoint and Cluster in the ARL entry.", @@ -102,6 +103,14 @@ async def test_TC_ACL_2_11(self): dev_ctrl = self.default_controller dut_node_id = self.dut_node_id self.step(1) + + wildcard_read = (await dev_ctrl.Read(self.dut_node_id, [()])) + has_arl, has_carl = arls_populated(wildcard_read.tlvAttributes) + asserts.assert_true( + has_arl, "ARL attribute must contain at least one restriction to run this test. Please follow manufacturer-specific steps to add access restrictions and re-run this test") + asserts.assert_true( + has_carl, "CommissioningARL attribute must contain at least one restriction to run this test. Please follow manufacturer-specific steps to add access restrictions and re-run this test") + self.step(2) await self.read_single_attribute_check_success( endpoint=0, diff --git a/src/python_testing/TestConformanceTest.py b/src/python_testing/TestConformanceTest.py index 5af8d1f639ef0c..12ecb25fef6f0c 100644 --- a/src/python_testing/TestConformanceTest.py +++ b/src/python_testing/TestConformanceTest.py @@ -18,6 +18,7 @@ from typing import Any import chip.clusters as Clusters +from basic_composition_support import arls_populated from conformance_support import ConformanceDecision from global_attribute_ids import GlobalAttributeIds from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main @@ -191,7 +192,7 @@ def _create_minimal_dt(self, device_type_id: int) -> dict[int, dict[int, Any]]: endpoint_tlv[Clusters.Descriptor.id] = attrs return endpoint_tlv - def add_macl(self, root_endpoint: dict[int, dict[int, Any]]): + def add_macl(self, root_endpoint: dict[int, dict[int, Any]], populate_arl: bool = False, populate_commissioning_arl: bool = False): ac = Clusters.AccessControl root_endpoint[ac.id][ac.Attributes.FeatureMap.attribute_id] = ac.Bitmaps.Feature.kManagedDevice root_endpoint[ac.id][ac.Attributes.Arl.attribute_id] = [] @@ -202,6 +203,14 @@ def add_macl(self, root_endpoint: dict[int, dict[int, Any]]): root_endpoint[ac.id][ac.Attributes.GeneratedCommandList.attribute_id].append( ac.Commands.ReviewFabricRestrictionsResponse.command_id) + generic_restriction = ac.Structs.AccessRestrictionStruct( + type=ac.Enums.AccessRestrictionTypeEnum.kAttributeAccessForbidden, id=1) + entry = ac.Structs.CommissioningAccessRestrictionEntryStruct(endpoint=1, cluster=2, restrictions=generic_restriction) + if populate_arl: + root_endpoint[ac.id][ac.Attributes.Arl.attribute_id] = [entry] + if populate_commissioning_arl: + root_endpoint[ac.id][ac.Attributes.CommissioningARL.attribute_id] = [entry] + @async_test_body async def test_macl_handling(self): nim_id = self._get_device_type_id('network infrastructure manager') @@ -231,6 +240,45 @@ async def test_macl_handling(self): # TODO: what happens if there is a NIM and a non-NIM endpoint? + @async_test_body + async def test_macl_restrictions(self): + + nim_id = self._get_device_type_id('network infrastructure manager') + root_node_id = self._get_device_type_id('root node') + + root = self._create_minimal_dt(device_type_id=root_node_id) + nim = self._create_minimal_dt(device_type_id=nim_id) + self.endpoints_tlv = {0: root, 1: nim} + + # device with no macl + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_false(have_arl, "Unexpected ARL found") + asserts.assert_false(have_carl, "Unexpected CommissioningARL found") + + # device with unpopulated macl + self.add_macl(root) + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_false(have_arl, "Unexpected ARL found") + asserts.assert_false(have_carl, "Unexpected CommissioningARL found") + + # device with populated ARL + self.add_macl(root, populate_arl=True) + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_true(have_arl, "Did not find expected ARL") + asserts.assert_false(have_carl, "Unexpected CommissioningARL found") + + # device with populated commissioning ARL + self.add_macl(root, populate_commissioning_arl=True) + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_false(have_arl, "Unexpected ARL found") + asserts.assert_true(have_carl, "Did not find expected Commissioning ARL") + + # device with both + self.add_macl(root, populate_arl=True, populate_commissioning_arl=True) + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_true(have_arl, "Did not find expected ARL") + asserts.assert_true(have_carl, "Did not find expected Commissioning ARL") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/basic_composition_support.py b/src/python_testing/basic_composition_support.py index 5401b1fad04f9d..781007cdbdf685 100644 --- a/src/python_testing/basic_composition_support.py +++ b/src/python_testing/basic_composition_support.py @@ -26,12 +26,30 @@ from pprint import pformat, pprint from typing import Any, Optional +import chip.clusters as Clusters import chip.clusters.ClusterObjects import chip.tlv from chip.clusters.Attribute import ValueDecodeFailure from mobly import asserts +def arls_populated(tlv_data: dict[int, Any]) -> tuple[bool, bool]: + """ Returns a tuple indicating if the ARL and CommissioningARL are populated. + Requires a wildcard read of the device TLV. + """ + # ACL is always on endpoint 0 + if 0 not in tlv_data or Clusters.AccessControl.id not in tlv_data[0]: + return (False, False) + # Both attributes are mandatory for this feature, so if one doesn't exist, neither should the other. + if Clusters.AccessControl.Attributes.Arl.attribute_id not in tlv_data[0][Clusters.AccessControl.id][Clusters.AccessControl.Attributes.AttributeList.attribute_id]: + return (False, False) + + have_arl = tlv_data[0][Clusters.AccessControl.id][Clusters.AccessControl.Attributes.Arl.attribute_id] + have_carl = tlv_data[0][Clusters.AccessControl.id][Clusters.AccessControl.Attributes.CommissioningARL.attribute_id] + + return (have_arl, have_carl) + + def MatterTlvToJson(tlv_data: dict[int, Any]) -> dict[str, Any]: """Given TLV data for a specific cluster instance, convert to the Matter JSON format.""" @@ -169,6 +187,12 @@ async def setup_class_helper(self, allow_pase: bool = True): logging.info("Start of actual tests") logging.info("###########################################################") + have_arl, have_carl = arls_populated(self.endpoints_tlv) + asserts.assert_false( + have_arl, "ARL cannot be populated for this test - Please follow manufacturer-specific steps to remove the access restrictions and re-run this test") + asserts.assert_false( + have_carl, "CommissioningARL cannot be populated for this test - Please follow manufacturer-specific steps to remove the access restrictions and re-run this test") + def get_test_name(self) -> str: """Return the function name of the caller. Used to create logging entries.""" return sys._getframe().f_back.f_code.co_name From e78a1862e61d407e15b4650319b70ee22016b606 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 4 Sep 2024 21:31:55 -0400 Subject: [PATCH 67/70] Fix intermittent falure in Darwin browsing test. (#35421) We are running the test against Matter applications that are starting up, and during startup we do some silly unregistering/re-registering of DNS-SD advertisements. The test was counting all the registrations, not subtracting the un-registrations, and asserting that the resulting count was not too high. But sometimes it is, if we get a "unregister/re-register" pair in there. The fix: 1) Fixes the test to better track un-registration bits. 2) Fixes the OnBleScanRemove code to call the right delegate method. 3) Fixes OnBrowseRemove to not call the delegate if we have not notified about the add for the relevant result. We could have just worked around this in the test, but notifying "removed" about an object with all fields set to nil just doesn't make much sense. --- .../CHIP/MTRCommissionableBrowser.mm | 13 +++-- .../CHIPTests/MTRCommissionableBrowserTests.m | 52 ++++++++++++++++--- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm b/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm index 276fb5e3460682..8a111a6a019bdb 100644 --- a/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm +++ b/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm @@ -268,9 +268,14 @@ void OnBrowseRemove(DnssdService service) override // If there is nothing else to resolve for the given instance name, just remove it // too and informs the delegate that it is gone. if ([interfaces count] == 0) { - dispatch_async(mDispatchQueue, ^{ - [mDelegate controller:mController didRemoveCommissionableDevice:result]; - }); + // If result.instanceName is nil, that means we never notified our + // delegate about this result (because we did not get that far in + // resolving it), so don't bother notifying about the removal either. + if (result.instanceName != nil) { + dispatch_async(mDispatchQueue, ^{ + [mDelegate controller:mController didRemoveCommissionableDevice:result]; + }); + } mDiscoveredResults[key] = nil; } @@ -325,7 +330,7 @@ void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override MATTER_LOG_METRIC(kMetricBLEDevicesRemoved, ++mBLEDevicesRemoved); dispatch_async(mDispatchQueue, ^{ - [mDelegate controller:mController didFindCommissionableDevice:result]; + [mDelegate controller:mController didRemoveCommissionableDevice:result]; }); } diff --git a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m index 31ca37ffd4bc94..185f4981cff405 100644 --- a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m @@ -36,9 +36,27 @@ // Singleton controller we use. static MTRDeviceController * sController = nil; +static NSString * kInstanceNameKey = @"instanceName"; +static NSString * kVendorIDKey = @"vendorID"; +static NSString * kProductIDKey = @"productID"; +static NSString * kDiscriminatorKey = @"discriminator"; +static NSString * kCommissioningModeKey = @"commissioningMode"; + +static NSDictionary * ResultSnapshot(MTRCommissionableBrowserResult * result) +{ + return @{ + kInstanceNameKey : result.instanceName, + kVendorIDKey : result.vendorID, + kProductIDKey : result.productID, + kDiscriminatorKey : result.discriminator, + kCommissioningModeKey : @(result.commissioningMode), + }; +} + @interface DeviceScannerDelegate : NSObject @property (nonatomic, nullable) XCTestExpectation * expectation; -@property (nonatomic) NSNumber * resultsCount; +@property (nonatomic) NSMutableArray *> * results; +@property (nonatomic) NSMutableArray *> * removedResults; - (instancetype)initWithExpectation:(XCTestExpectation *)expectation; - (void)controller:(MTRDeviceController *)controller didFindCommissionableDevice:(MTRCommissionableBrowserResult *)device; @@ -52,8 +70,9 @@ - (instancetype)initWithExpectation:(XCTestExpectation *)expectation return nil; } - _resultsCount = 0; _expectation = expectation; + _results = [[NSMutableArray alloc] init]; + _removedResults = [[NSMutableArray alloc] init]; return self; } @@ -63,8 +82,9 @@ - (instancetype)init return nil; } - _resultsCount = 0; _expectation = nil; + _results = [[NSMutableArray alloc] init]; + _removedResults = [[NSMutableArray alloc] init]; return self; } @@ -77,12 +97,26 @@ - (void)controller:(MTRDeviceController *)controller didFindCommissionableDevice return; } - _resultsCount = @(_resultsCount.unsignedLongValue + 1); - if ([_resultsCount isEqual:@(kExpectedDiscoveredDevicesCount)]) { + __auto_type * snapshot = ResultSnapshot(device); + + XCTAssertFalse([_results containsObject:snapshot], @"Newly discovered device %@ should not be in results already.", snapshot); + + [_results addObject:snapshot]; + + if (_results.count == kExpectedDiscoveredDevicesCount) { + // Do some sanity checking on our results and removedResults to make + // sure we really only saw the relevant set of things. + NSSet *> * finalResultsSet = [NSSet setWithArray:_results]; + NSSet *> * allResultsSet = [finalResultsSet copy]; + allResultsSet = [allResultsSet setByAddingObjectsFromArray:_removedResults]; + + // Ensure that we just saw the same results as our final set popping in and out if things + // ever got removed here. + XCTAssertEqualObjects(finalResultsSet, allResultsSet); [self.expectation fulfill]; } - XCTAssertLessThanOrEqual(_resultsCount.unsignedLongValue, kExpectedDiscoveredDevicesCount); + XCTAssertLessThanOrEqual(_results.count, kExpectedDiscoveredDevicesCount); __auto_type instanceName = device.instanceName; __auto_type vendorId = device.vendorID; @@ -108,6 +142,12 @@ - (void)controller:(MTRDeviceController *)controller didRemoveCommissionableDevi NSLog( @"Removed Device (%@) with discriminator: %@ (vendor: %@, product: %@)", instanceName, discriminator, vendorId, productId); + + __auto_type * snapshot = ResultSnapshot(device); + XCTAssertTrue([_results containsObject:snapshot], @"Removed device %@ is not something we found before", snapshot); + + [_removedResults addObject:snapshot]; + [_results removeObject:snapshot]; } @end From 1df53d8ba87dcce4698e831c3e6ac9673a94eb7a Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 4 Sep 2024 21:08:59 -0700 Subject: [PATCH 68/70] Update the FS XML definations to algin with spec update (#35381) --- .../device_manager/DeviceManager.cpp | 4 +-- .../fabric-bridge-app.matter | 14 ++++---- .../linux/CommissionerControl.cpp | 4 +-- .../commissioner-control-server.cpp | 8 ++--- .../chip/bridged-device-basic-information.xml | 2 +- .../chip/commissioner-control-cluster.xml | 16 ++++----- .../data_model/controller-clusters.matter | 14 ++++---- .../chip/devicecontroller/ChipClusters.java | 36 +++++++++---------- .../devicecontroller/ChipEventStructs.java | 36 +++++++++---------- .../devicecontroller/ClusterIDMapping.java | 4 +-- .../devicecontroller/ClusterInfoMapping.java | 24 ++++++------- ...lClusterCommissioningRequestResultEvent.kt | 20 +++++------ .../clusters/CommissionerControlCluster.kt | 16 ++++----- ...lClusterCommissioningRequestResultEvent.kt | 20 +++++------ .../CHIPEventTLVValueDecoder.cpp | 26 +++++++------- .../python/chip/clusters/CHIPClusters.py | 8 ++--- .../python/chip/clusters/Objects.py | 24 ++++++------- .../zap-generated/MTRCommandPayloadsObjc.h | 8 ++--- .../zap-generated/MTRCommandPayloadsObjc.mm | 28 +++++++-------- .../zap-generated/MTREventTLVValueDecoder.mm | 8 ++--- .../CHIP/zap-generated/MTRStructsObjc.h | 4 +-- .../CHIP/zap-generated/MTRStructsObjc.mm | 10 +++--- .../zap-generated/cluster-objects.cpp | 36 +++++++++---------- .../zap-generated/cluster-objects.h | 36 +++++++++---------- .../zap-generated/cluster/Commands.h | 8 ++--- .../cluster/logging/DataModelLogger.cpp | 8 ++--- .../zap-generated/cluster/Commands.h | 16 ++++----- 27 files changed, 219 insertions(+), 219 deletions(-) diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 54c4bd8d45debf..d8de362255dd81 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -282,7 +282,7 @@ void DeviceManager::HandleCommissioningRequestResult(TLV::TLVReader & data) return; } - if (value.requestId != mRequestId) + if (value.requestID != mRequestId) { ChipLogError(NotSpecified, "The RequestId does not match the RequestId provided to RequestCommissioningApproval"); return; @@ -296,7 +296,7 @@ void DeviceManager::HandleCommissioningRequestResult(TLV::TLVReader & data) // The server is ready to begin commissioning the requested device, request the Commissioner Control Server to begin // commissioning a previously approved request. - SendCommissionNodeRequest(value.requestId, kResponseTimeoutSeconds); + SendCommissionNodeRequest(value.requestID, kResponseTimeoutSeconds); } void DeviceManager::HandleAttributePartsListUpdate(chip::TLV::TLVReader & data) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index 7df3c29b359f91..0b4cb214b5f3be 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -1698,9 +1698,9 @@ provisional cluster CommissionerControl = 1873 { } fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { - int64u requestId = 0; - node_id clientNodeId = 1; - enum8 statusCode = 2; + int64u requestID = 0; + node_id clientNodeID = 1; + status statusCode = 2; fabric_idx fabricIndex = 254; } @@ -1713,14 +1713,14 @@ provisional cluster CommissionerControl = 1873 { readonly attribute int16u clusterRevision = 65533; request struct RequestCommissioningApprovalRequest { - int64u requestId = 0; - vendor_id vendorId = 1; - int16u productId = 2; + int64u requestID = 0; + vendor_id vendorID = 1; + int16u productID = 2; optional char_string<64> label = 3; } request struct CommissionNodeRequest { - int64u requestId = 0; + int64u requestID = 0; int16u responseTimeoutSeconds = 1; } diff --git a/examples/fabric-bridge-app/linux/CommissionerControl.cpp b/examples/fabric-bridge-app/linux/CommissionerControl.cpp index 96984d50696474..e9dded102bcac1 100644 --- a/examples/fabric-bridge-app/linux/CommissionerControl.cpp +++ b/examples/fabric-bridge-app/linux/CommissionerControl.cpp @@ -79,8 +79,8 @@ CHIP_ERROR CommissionerControlDelegate::HandleCommissioningApprovalRequest(const VerifyOrReturnError(mNextStep == Step::kIdle, CHIP_ERROR_INCORRECT_STATE); CommissionerControl::Events::CommissioningRequestResult::Type result; - result.requestId = request.requestId; - result.clientNodeId = request.clientNodeId; + result.requestID = request.requestId; + result.clientNodeID = request.clientNodeId; result.fabricIndex = request.fabricIndex; result.statusCode = static_cast(Protocols::InteractionModel::Status::Success); diff --git a/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp b/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp index 80d65b2c4d16fc..d6282f287a1181 100644 --- a/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp +++ b/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp @@ -170,9 +170,9 @@ bool emberAfCommissionerControlClusterRequestCommissioningApprovalCallback( } auto fabricIndex = commandObj->GetAccessingFabricIndex(); - auto requestId = commandData.requestId; - auto vendorId = commandData.vendorId; - auto productId = commandData.productId; + auto requestId = commandData.requestID; + auto vendorId = commandData.vendorID; + auto productId = commandData.productID; // The label assigned from commandData need to be stored in CommissionerControl::Delegate which ensure that the backing buffer // of it has a valid lifespan during fabric sync setup process. @@ -232,7 +232,7 @@ bool emberAfCommissionerControlClusterCommissionNodeCallback( return true; } - auto requestId = commandData.requestId; + auto requestId = commandData.requestID; auto commissioningWindowParams = std::make_unique(); diff --git a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml index ef2629c3574701..bc1d61e64309b5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml +++ b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml @@ -111,7 +111,7 @@ limitations under the License. The Leave event SHOULD be emitted by a Node prior to permanently leaving the Fabric. - + This event SHALL be generated when there is a change in the Reachable attribute. diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml index af9a734d6e7176..abfd85dde2cd93 100644 --- a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -39,21 +39,21 @@ limitations under the License. This command is sent by a client to request approval for a future CommissionNode call. - - - + + + This command is sent by a client to request that the server begins commissioning a previously approved request. - + - + When received within the timeout specified by CommissionNode, the client SHALL open a commissioning window on to the node which the client called RequestCommissioningApproval to have commissioned. @@ -64,9 +64,9 @@ limitations under the License. This event SHALL be sent by the server following a RequestCommissioningApproval command which the server responded to with SUCCESS. - - - + + + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index eac83d868cb375..ea7ab01b39d2dd 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9422,9 +9422,9 @@ provisional cluster CommissionerControl = 1873 { } fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { - int64u requestId = 0; - node_id clientNodeId = 1; - enum8 statusCode = 2; + int64u requestID = 0; + node_id clientNodeID = 1; + status statusCode = 2; fabric_idx fabricIndex = 254; } @@ -9437,14 +9437,14 @@ provisional cluster CommissionerControl = 1873 { readonly attribute int16u clusterRevision = 65533; request struct RequestCommissioningApprovalRequest { - int64u requestId = 0; - vendor_id vendorId = 1; - int16u productId = 2; + int64u requestID = 0; + vendor_id vendorID = 1; + int16u productID = 2; optional char_string<64> label = 3; } request struct CommissionNodeRequest { - int64u requestId = 0; + int64u requestID = 0; int16u responseTimeoutSeconds = 1; } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index ae900222e92943..ce3d602f1f89b6 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -61069,25 +61069,25 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label) { - requestCommissioningApproval(callback, requestId, vendorId, productId, label, 0); + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestID, Integer vendorID, Integer productID, Optional label) { + requestCommissioningApproval(callback, requestID, vendorID, productID, label, 0); } - public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label, int timedInvokeTimeoutMs) { + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestID, Integer vendorID, Integer productID, Optional label, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); - final long requestIdFieldID = 0L; - BaseTLVType requestIdtlvValue = new UIntType(requestId); - elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); + final long requestIDFieldID = 0L; + BaseTLVType requestIDtlvValue = new UIntType(requestID); + elements.add(new StructElement(requestIDFieldID, requestIDtlvValue)); - final long vendorIdFieldID = 1L; - BaseTLVType vendorIdtlvValue = new UIntType(vendorId); - elements.add(new StructElement(vendorIdFieldID, vendorIdtlvValue)); + final long vendorIDFieldID = 1L; + BaseTLVType vendorIDtlvValue = new UIntType(vendorID); + elements.add(new StructElement(vendorIDFieldID, vendorIDtlvValue)); - final long productIdFieldID = 2L; - BaseTLVType productIdtlvValue = new UIntType(productId); - elements.add(new StructElement(productIdFieldID, productIdtlvValue)); + final long productIDFieldID = 2L; + BaseTLVType productIDtlvValue = new UIntType(productID); + elements.add(new StructElement(productIDFieldID, productIDtlvValue)); final long labelFieldID = 3L; BaseTLVType labeltlvValue = label.map((nonOptionallabel) -> new StringType(nonOptionallabel)).orElse(new EmptyType()); @@ -61101,17 +61101,17 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds) { - commissionNode(callback, requestId, responseTimeoutSeconds, 0); + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestID, Integer responseTimeoutSeconds) { + commissionNode(callback, requestID, responseTimeoutSeconds, 0); } - public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds, int timedInvokeTimeoutMs) { + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestID, Integer responseTimeoutSeconds, int timedInvokeTimeoutMs) { final long commandId = 1L; ArrayList elements = new ArrayList<>(); - final long requestIdFieldID = 0L; - BaseTLVType requestIdtlvValue = new UIntType(requestId); - elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); + final long requestIDFieldID = 0L; + BaseTLVType requestIDtlvValue = new UIntType(requestID); + elements.add(new StructElement(requestIDFieldID, requestIDtlvValue)); final long responseTimeoutSecondsFieldID = 1L; BaseTLVType responseTimeoutSecondstlvValue = new UIntType(responseTimeoutSeconds); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index 179b6e396638f9..737462f3da184d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -6188,8 +6188,8 @@ public String toString() { } } public static class CommissionerControlClusterCommissioningRequestResultEvent { - public Long requestId; - public Long clientNodeId; + public Long requestID; + public Long clientNodeID; public Integer statusCode; public Integer fabricIndex; private static final long REQUEST_ID_ID = 0L; @@ -6198,21 +6198,21 @@ public static class CommissionerControlClusterCommissioningRequestResultEvent { private static final long FABRIC_INDEX_ID = 254L; public CommissionerControlClusterCommissioningRequestResultEvent( - Long requestId, - Long clientNodeId, + Long requestID, + Long clientNodeID, Integer statusCode, Integer fabricIndex ) { - this.requestId = requestId; - this.clientNodeId = clientNodeId; + this.requestID = requestID; + this.clientNodeID = clientNodeID; this.statusCode = statusCode; this.fabricIndex = fabricIndex; } public StructType encodeTlv() { ArrayList values = new ArrayList<>(); - values.add(new StructElement(REQUEST_ID_ID, new UIntType(requestId))); - values.add(new StructElement(CLIENT_NODE_ID_ID, new UIntType(clientNodeId))); + values.add(new StructElement(REQUEST_ID_ID, new UIntType(requestID))); + values.add(new StructElement(CLIENT_NODE_ID_ID, new UIntType(clientNodeID))); values.add(new StructElement(STATUS_CODE_ID, new UIntType(statusCode))); values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); @@ -6223,20 +6223,20 @@ public static CommissionerControlClusterCommissioningRequestResultEvent decodeTl if (tlvValue == null || tlvValue.type() != TLVType.Struct) { return null; } - Long requestId = null; - Long clientNodeId = null; + Long requestID = null; + Long clientNodeID = null; Integer statusCode = null; Integer fabricIndex = null; for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == REQUEST_ID_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - requestId = castingValue.value(Long.class); + requestID = castingValue.value(Long.class); } } else if (element.contextTagNum() == CLIENT_NODE_ID_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - clientNodeId = castingValue.value(Long.class); + clientNodeID = castingValue.value(Long.class); } } else if (element.contextTagNum() == STATUS_CODE_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -6251,8 +6251,8 @@ public static CommissionerControlClusterCommissioningRequestResultEvent decodeTl } } return new CommissionerControlClusterCommissioningRequestResultEvent( - requestId, - clientNodeId, + requestID, + clientNodeID, statusCode, fabricIndex ); @@ -6262,11 +6262,11 @@ public static CommissionerControlClusterCommissioningRequestResultEvent decodeTl public String toString() { StringBuilder output = new StringBuilder(); output.append("CommissionerControlClusterCommissioningRequestResultEvent {\n"); - output.append("\trequestId: "); - output.append(requestId); + output.append("\trequestID: "); + output.append(requestID); output.append("\n"); - output.append("\tclientNodeId: "); - output.append(clientNodeId); + output.append("\tclientNodeID: "); + output.append(clientNodeID); output.append("\n"); output.append("\tstatusCode: "); output.append(statusCode); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 8ae6ae6fa0dac5..950e6070dff2c0 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -17406,7 +17406,7 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }public enum RequestCommissioningApprovalCommandField {RequestId(0),VendorId(1),ProductId(2),Label(3),; + }public enum RequestCommissioningApprovalCommandField {RequestID(0),VendorID(1),ProductID(2),Label(3),; private final int id; RequestCommissioningApprovalCommandField(int id) { this.id = id; @@ -17423,7 +17423,7 @@ public static RequestCommissioningApprovalCommandField value(int id) throws NoSu } throw new NoSuchFieldError(); } - }public enum CommissionNodeCommandField {RequestId(0),ResponseTimeoutSeconds(1),; + }public enum CommissionNodeCommandField {RequestID(0),ResponseTimeoutSeconds(1),; private final int id; CommissionNodeCommandField(int id) { this.id = id; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index b65ff7bcb7f175..6e009e3ae63c5a 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -29032,14 +29032,14 @@ public Map> getCommandMap() { Map commissionerControlrequestCommissioningApprovalCommandParams = new LinkedHashMap(); - CommandParameterInfo commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); - commissionerControlrequestCommissioningApprovalCommandParams.put("requestId",commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo); + CommandParameterInfo commissionerControlrequestCommissioningApprovalrequestIDCommandParameterInfo = new CommandParameterInfo("requestID", Long.class, Long.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("requestID",commissionerControlrequestCommissioningApprovalrequestIDCommandParameterInfo); - CommandParameterInfo commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo = new CommandParameterInfo("vendorId", Integer.class, Integer.class); - commissionerControlrequestCommissioningApprovalCommandParams.put("vendorId",commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo); + CommandParameterInfo commissionerControlrequestCommissioningApprovalvendorIDCommandParameterInfo = new CommandParameterInfo("vendorID", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("vendorID",commissionerControlrequestCommissioningApprovalvendorIDCommandParameterInfo); - CommandParameterInfo commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo = new CommandParameterInfo("productId", Integer.class, Integer.class); - commissionerControlrequestCommissioningApprovalCommandParams.put("productId",commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo); + CommandParameterInfo commissionerControlrequestCommissioningApprovalproductIDCommandParameterInfo = new CommandParameterInfo("productID", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("productID",commissionerControlrequestCommissioningApprovalproductIDCommandParameterInfo); CommandParameterInfo commissionerControlrequestCommissioningApprovallabelCommandParameterInfo = new CommandParameterInfo("label", Optional.class, String.class); commissionerControlrequestCommissioningApprovalCommandParams.put("label",commissionerControlrequestCommissioningApprovallabelCommandParameterInfo); @@ -29048,11 +29048,11 @@ public Map> getCommandMap() { ((ChipClusters.CommissionerControlCluster) cluster) .requestCommissioningApproval((DefaultClusterCallback) callback , (Long) - commandArguments.get("requestId") + commandArguments.get("requestID") , (Integer) - commandArguments.get("vendorId") + commandArguments.get("vendorID") , (Integer) - commandArguments.get("productId") + commandArguments.get("productID") , (Optional) commandArguments.get("label") ); @@ -29064,8 +29064,8 @@ public Map> getCommandMap() { Map commissionerControlcommissionNodeCommandParams = new LinkedHashMap(); - CommandParameterInfo commissionerControlcommissionNoderequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); - commissionerControlcommissionNodeCommandParams.put("requestId",commissionerControlcommissionNoderequestIdCommandParameterInfo); + CommandParameterInfo commissionerControlcommissionNoderequestIDCommandParameterInfo = new CommandParameterInfo("requestID", Long.class, Long.class); + commissionerControlcommissionNodeCommandParams.put("requestID",commissionerControlcommissionNoderequestIDCommandParameterInfo); CommandParameterInfo commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo = new CommandParameterInfo("responseTimeoutSeconds", Integer.class, Integer.class); commissionerControlcommissionNodeCommandParams.put("responseTimeoutSeconds",commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo); @@ -29074,7 +29074,7 @@ public Map> getCommandMap() { ((ChipClusters.CommissionerControlCluster) cluster) .commissionNode((ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback) callback , (Long) - commandArguments.get("requestId") + commandArguments.get("requestID") , (Integer) commandArguments.get("responseTimeoutSeconds") diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt index 2a7a8d3c5b8ffb..ce05d28a261e91 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -23,15 +23,15 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class CommissionerControlClusterCommissioningRequestResultEvent( - val requestId: ULong, - val clientNodeId: ULong, + val requestID: ULong, + val clientNodeID: ULong, val statusCode: UInt, val fabricIndex: UInt, ) { override fun toString(): String = buildString { append("CommissionerControlClusterCommissioningRequestResultEvent {\n") - append("\trequestId : $requestId\n") - append("\tclientNodeId : $clientNodeId\n") + append("\trequestID : $requestID\n") + append("\tclientNodeID : $clientNodeID\n") append("\tstatusCode : $statusCode\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") @@ -40,8 +40,8 @@ class CommissionerControlClusterCommissioningRequestResultEvent( fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_REQUEST_ID), requestId) - put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_REQUEST_ID), requestID) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeID) put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() @@ -59,16 +59,16 @@ class CommissionerControlClusterCommissioningRequestResultEvent( tlvReader: TlvReader, ): CommissionerControlClusterCommissioningRequestResultEvent { tlvReader.enterStructure(tlvTag) - val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) - val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val requestID = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) val statusCode = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS_CODE)) val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) tlvReader.exitContainer() return CommissionerControlClusterCommissioningRequestResultEvent( - requestId, - clientNodeId, + requestID, + clientNodeID, statusCode, fabricIndex, ) diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt index 3e9d07f3f04354..f7b592b6bc2c72 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt @@ -92,9 +92,9 @@ class CommissionerControlCluster( } suspend fun requestCommissioningApproval( - requestId: ULong, - vendorId: UShort, - productId: UShort, + requestID: ULong, + vendorID: UShort, + productID: UShort, label: String?, timedInvokeTimeout: Duration? = null, ) { @@ -104,13 +104,13 @@ class CommissionerControlCluster( tlvWriter.startStructure(AnonymousTag) val TAG_REQUEST_ID_REQ: Int = 0 - tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestID) val TAG_VENDOR_ID_REQ: Int = 1 - tlvWriter.put(ContextSpecificTag(TAG_VENDOR_ID_REQ), vendorId) + tlvWriter.put(ContextSpecificTag(TAG_VENDOR_ID_REQ), vendorID) val TAG_PRODUCT_ID_REQ: Int = 2 - tlvWriter.put(ContextSpecificTag(TAG_PRODUCT_ID_REQ), productId) + tlvWriter.put(ContextSpecificTag(TAG_PRODUCT_ID_REQ), productID) val TAG_LABEL_REQ: Int = 3 label?.let { tlvWriter.put(ContextSpecificTag(TAG_LABEL_REQ), label) } @@ -128,7 +128,7 @@ class CommissionerControlCluster( } suspend fun commissionNode( - requestId: ULong, + requestID: ULong, responseTimeoutSeconds: UShort, timedInvokeTimeout: Duration? = null, ): ReverseOpenCommissioningWindow { @@ -138,7 +138,7 @@ class CommissionerControlCluster( tlvWriter.startStructure(AnonymousTag) val TAG_REQUEST_ID_REQ: Int = 0 - tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestID) val TAG_RESPONSE_TIMEOUT_SECONDS_REQ: Int = 1 tlvWriter.put(ContextSpecificTag(TAG_RESPONSE_TIMEOUT_SECONDS_REQ), responseTimeoutSeconds) diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt index c8947776269773..4cc7a31fdbe97c 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -23,15 +23,15 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class CommissionerControlClusterCommissioningRequestResultEvent( - val requestId: ULong, - val clientNodeId: ULong, + val requestID: ULong, + val clientNodeID: ULong, val statusCode: UByte, val fabricIndex: UByte, ) { override fun toString(): String = buildString { append("CommissionerControlClusterCommissioningRequestResultEvent {\n") - append("\trequestId : $requestId\n") - append("\tclientNodeId : $clientNodeId\n") + append("\trequestID : $requestID\n") + append("\tclientNodeID : $clientNodeID\n") append("\tstatusCode : $statusCode\n") append("\tfabricIndex : $fabricIndex\n") append("}\n") @@ -40,8 +40,8 @@ class CommissionerControlClusterCommissioningRequestResultEvent( fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_REQUEST_ID), requestId) - put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_REQUEST_ID), requestID) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeID) put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) endStructure() @@ -59,16 +59,16 @@ class CommissionerControlClusterCommissioningRequestResultEvent( tlvReader: TlvReader, ): CommissionerControlClusterCommissioningRequestResultEvent { tlvReader.enterStructure(tlvTag) - val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) - val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val requestID = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) val statusCode = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS_CODE)) val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) tlvReader.exitContainer() return CommissionerControlClusterCommissioningRequestResultEvent( - requestId, - clientNodeId, + requestID, + clientNodeID, statusCode, fabricIndex, ) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index d9bf294c0f8486..a133eceb499a0f 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -8299,20 +8299,20 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & { return nullptr; } - jobject value_requestId; - std::string value_requestIdClassName = "java/lang/Long"; - std::string value_requestIdCtorSignature = "(J)V"; - jlong jnivalue_requestId = static_cast(cppValue.requestId); + jobject value_requestID; + std::string value_requestIDClassName = "java/lang/Long"; + std::string value_requestIDCtorSignature = "(J)V"; + jlong jnivalue_requestID = static_cast(cppValue.requestID); chip::JniReferences::GetInstance().CreateBoxedObject( - value_requestIdClassName.c_str(), value_requestIdCtorSignature.c_str(), jnivalue_requestId, value_requestId); + value_requestIDClassName.c_str(), value_requestIDCtorSignature.c_str(), jnivalue_requestID, value_requestID); - jobject value_clientNodeId; - std::string value_clientNodeIdClassName = "java/lang/Long"; - std::string value_clientNodeIdCtorSignature = "(J)V"; - jlong jnivalue_clientNodeId = static_cast(cppValue.clientNodeId); - chip::JniReferences::GetInstance().CreateBoxedObject(value_clientNodeIdClassName.c_str(), - value_clientNodeIdCtorSignature.c_str(), - jnivalue_clientNodeId, value_clientNodeId); + jobject value_clientNodeID; + std::string value_clientNodeIDClassName = "java/lang/Long"; + std::string value_clientNodeIDCtorSignature = "(J)V"; + jlong jnivalue_clientNodeID = static_cast(cppValue.clientNodeID); + chip::JniReferences::GetInstance().CreateBoxedObject(value_clientNodeIDClassName.c_str(), + value_clientNodeIDCtorSignature.c_str(), + jnivalue_clientNodeID, value_clientNodeID); jobject value_statusCode; std::string value_statusCodeClassName = "java/lang/Integer"; @@ -8352,7 +8352,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } jobject value = env->NewObject(commissioningRequestResultStructClass, commissioningRequestResultStructCtor, - value_requestId, value_clientNodeId, value_statusCode, value_fabricIndex); + value_requestID, value_clientNodeID, value_statusCode, value_fabricIndex); return value; } diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index a26555e58dd517..268dd1abfb574c 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -13377,9 +13377,9 @@ class ChipClusters: "commandId": 0x00000000, "commandName": "RequestCommissioningApproval", "args": { - "requestId": "int", - "vendorId": "int", - "productId": "int", + "requestID": "int", + "vendorID": "int", + "productID": "int", "label": "str", }, }, @@ -13387,7 +13387,7 @@ class ChipClusters: "commandId": 0x00000001, "commandName": "CommissionNode", "args": { - "requestId": "int", + "requestID": "int", "responseTimeoutSeconds": "int", }, }, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 688b4d6d4d4d08..b408fb5fd57e71 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -47434,15 +47434,15 @@ class RequestCommissioningApproval(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), - ClusterObjectFieldDescriptor(Label="vendorId", Tag=1, Type=uint), - ClusterObjectFieldDescriptor(Label="productId", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="requestID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="vendorID", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="productID", Tag=2, Type=uint), ClusterObjectFieldDescriptor(Label="label", Tag=3, Type=typing.Optional[str]), ]) - requestId: 'uint' = 0 - vendorId: 'uint' = 0 - productId: 'uint' = 0 + requestID: 'uint' = 0 + vendorID: 'uint' = 0 + productID: 'uint' = 0 label: 'typing.Optional[str]' = None @dataclass @@ -47456,11 +47456,11 @@ class CommissionNode(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="requestID", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="responseTimeoutSeconds", Tag=1, Type=uint), ]) - requestId: 'uint' = 0 + requestID: 'uint' = 0 responseTimeoutSeconds: 'uint' = 0 @dataclass @@ -47615,14 +47615,14 @@ def event_id(cls) -> int: def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), - ClusterObjectFieldDescriptor(Label="clientNodeId", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="requestID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="clientNodeID", Tag=1, Type=uint), ClusterObjectFieldDescriptor(Label="statusCode", Tag=2, Type=uint), ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - requestId: 'uint' = 0 - clientNodeId: 'uint' = 0 + requestID: 'uint' = 0 + clientNodeID: 'uint' = 0 statusCode: 'uint' = 0 fabricIndex: 'uint' = 0 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 044b0116ff4778..05bcb8213b6df9 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -10894,11 +10894,11 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRCommissionerControlClusterRequestCommissioningApprovalParams : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull requestID MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nonnull vendorId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull vendorID MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nonnull productId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull productID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSString * _Nullable label MTR_PROVISIONALLY_AVAILABLE; /** @@ -10930,7 +10930,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRCommissionerControlClusterCommissionNodeParams : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull requestID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull responseTimeoutSeconds MTR_PROVISIONALLY_AVAILABLE; /** diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index d24ce54fc84028..87aacfd377eb82 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -31480,11 +31480,11 @@ - (instancetype)init { if (self = [super init]) { - _requestId = @(0); + _requestID = @(0); - _vendorId = @(0); + _vendorID = @(0); - _productId = @(0); + _productID = @(0); _label = nil; _timedInvokeTimeoutMs = nil; @@ -31497,9 +31497,9 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; { auto other = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; - other.requestId = self.requestId; - other.vendorId = self.vendorId; - other.productId = self.productId; + other.requestID = self.requestID; + other.vendorID = self.vendorID; + other.productID = self.productID; other.label = self.label; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -31509,7 +31509,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; vendorId:%@; productId:%@; label:%@; >", NSStringFromClass([self class]), _requestId, _vendorId, _productId, _label]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestID:%@; vendorID:%@; productID:%@; label:%@; >", NSStringFromClass([self class]), _requestID, _vendorID, _productID, _label]; return descriptionString; } @@ -31522,13 +31522,13 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type encodableStruct; ListFreer listFreer; { - encodableStruct.requestId = self.requestId.unsignedLongLongValue; + encodableStruct.requestID = self.requestID.unsignedLongLongValue; } { - encodableStruct.vendorId = static_cast>(self.vendorId.unsignedShortValue); + encodableStruct.vendorID = static_cast>(self.vendorID.unsignedShortValue); } { - encodableStruct.productId = self.productId.unsignedShortValue; + encodableStruct.productID = self.productID.unsignedShortValue; } { if (self.label != nil) { @@ -31580,7 +31580,7 @@ - (instancetype)init { if (self = [super init]) { - _requestId = @(0); + _requestID = @(0); _responseTimeoutSeconds = @(0); _timedInvokeTimeoutMs = nil; @@ -31593,7 +31593,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; { auto other = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; - other.requestId = self.requestId; + other.requestID = self.requestID; other.responseTimeoutSeconds = self.responseTimeoutSeconds; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -31603,7 +31603,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; responseTimeoutSeconds:%@; >", NSStringFromClass([self class]), _requestId, _responseTimeoutSeconds]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestID:%@; responseTimeoutSeconds:%@; >", NSStringFromClass([self class]), _requestID, _responseTimeoutSeconds]; return descriptionString; } @@ -31616,7 +31616,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type encodableStruct; ListFreer listFreer; { - encodableStruct.requestId = self.requestId.unsignedLongLongValue; + encodableStruct.requestID = self.requestID.unsignedLongLongValue; } { encodableStruct.responseTimeoutSeconds = self.responseTimeoutSeconds.unsignedShortValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 85dcba3510205e..6ecc072f6b44a6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4606,13 +4606,13 @@ static id _Nullable DecodeEventPayloadForCommissionerControlCluster(EventId aEve do { NSNumber * _Nonnull memberValue; - memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.requestId]; - value.requestId = memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.requestID]; + value.requestID = memberValue; } while (0); do { NSNumber * _Nonnull memberValue; - memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.clientNodeId]; - value.clientNodeId = memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.clientNodeID]; + value.clientNodeID = memberValue; } while (0); do { NSNumber * _Nonnull memberValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index b0dcf5afb48858..61aa5161dced29 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -2145,8 +2145,8 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRCommissionerControlClusterCommissioningRequestResultEvent : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nonnull clientNodeId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull requestID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull clientNodeID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull statusCode MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 2d5a3835a98f4b..5cb5806c112a69 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -8887,9 +8887,9 @@ - (instancetype)init { if (self = [super init]) { - _requestId = @(0); + _requestID = @(0); - _clientNodeId = @(0); + _clientNodeID = @(0); _statusCode = @(0); @@ -8902,8 +8902,8 @@ - (id)copyWithZone:(NSZone * _Nullable)zone { auto other = [[MTRCommissionerControlClusterCommissioningRequestResultEvent alloc] init]; - other.requestId = self.requestId; - other.clientNodeId = self.clientNodeId; + other.requestID = self.requestID; + other.clientNodeID = self.clientNodeID; other.statusCode = self.statusCode; other.fabricIndex = self.fabricIndex; @@ -8912,7 +8912,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; clientNodeId:%@; statusCode:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _requestId, _clientNodeId, _statusCode, _fabricIndex]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestID:%@; clientNodeID:%@; statusCode:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _requestID, _clientNodeID, _statusCode, _fabricIndex]; return descriptionString; } diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index e75804a86709e2..78368f7293b1a4 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -28887,9 +28887,9 @@ namespace RequestCommissioningApproval { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kRequestId), requestId); - encoder.Encode(to_underlying(Fields::kVendorId), vendorId); - encoder.Encode(to_underlying(Fields::kProductId), productId); + encoder.Encode(to_underlying(Fields::kRequestID), requestID); + encoder.Encode(to_underlying(Fields::kVendorID), vendorID); + encoder.Encode(to_underlying(Fields::kProductID), productID); encoder.Encode(to_underlying(Fields::kLabel), label); return encoder.Finalize(); } @@ -28908,17 +28908,17 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kRequestId)) + if (__context_tag == to_underlying(Fields::kRequestID)) { - err = DataModel::Decode(reader, requestId); + err = DataModel::Decode(reader, requestID); } - else if (__context_tag == to_underlying(Fields::kVendorId)) + else if (__context_tag == to_underlying(Fields::kVendorID)) { - err = DataModel::Decode(reader, vendorId); + err = DataModel::Decode(reader, vendorID); } - else if (__context_tag == to_underlying(Fields::kProductId)) + else if (__context_tag == to_underlying(Fields::kProductID)) { - err = DataModel::Decode(reader, productId); + err = DataModel::Decode(reader, productID); } else if (__context_tag == to_underlying(Fields::kLabel)) { @@ -28936,7 +28936,7 @@ namespace CommissionNode { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kRequestId), requestId); + encoder.Encode(to_underlying(Fields::kRequestID), requestID); encoder.Encode(to_underlying(Fields::kResponseTimeoutSeconds), responseTimeoutSeconds); return encoder.Finalize(); } @@ -28955,9 +28955,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kRequestId)) + if (__context_tag == to_underlying(Fields::kRequestID)) { - err = DataModel::Decode(reader, requestId); + err = DataModel::Decode(reader, requestID); } else if (__context_tag == to_underlying(Fields::kResponseTimeoutSeconds)) { @@ -29058,8 +29058,8 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { TLV::TLVType outer; ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRequestId), requestId)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kClientNodeId), clientNodeId)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRequestID), requestID)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kClientNodeID), clientNodeID)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kStatusCode), statusCode)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); return aWriter.EndContainer(outer); @@ -29079,13 +29079,13 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kRequestId)) + if (__context_tag == to_underlying(Fields::kRequestID)) { - err = DataModel::Decode(reader, requestId); + err = DataModel::Decode(reader, requestID); } - else if (__context_tag == to_underlying(Fields::kClientNodeId)) + else if (__context_tag == to_underlying(Fields::kClientNodeID)) { - err = DataModel::Decode(reader, clientNodeId); + err = DataModel::Decode(reader, clientNodeID); } else if (__context_tag == to_underlying(Fields::kStatusCode)) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index b2fc8fb5a43f63..2aaf40bdbad6f9 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -41938,9 +41938,9 @@ namespace Commands { namespace RequestCommissioningApproval { enum class Fields : uint8_t { - kRequestId = 0, - kVendorId = 1, - kProductId = 2, + kRequestID = 0, + kVendorID = 1, + kProductID = 2, kLabel = 3, }; @@ -41951,9 +41951,9 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } - uint64_t requestId = static_cast(0); - chip::VendorId vendorId = static_cast(0); - uint16_t productId = static_cast(0); + uint64_t requestID = static_cast(0); + chip::VendorId vendorID = static_cast(0); + uint16_t productID = static_cast(0); Optional label; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -41969,9 +41969,9 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } - uint64_t requestId = static_cast(0); - chip::VendorId vendorId = static_cast(0); - uint16_t productId = static_cast(0); + uint64_t requestID = static_cast(0); + chip::VendorId vendorID = static_cast(0); + uint16_t productID = static_cast(0); Optional label; CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -41979,7 +41979,7 @@ struct DecodableType namespace CommissionNode { enum class Fields : uint8_t { - kRequestId = 0, + kRequestID = 0, kResponseTimeoutSeconds = 1, }; @@ -41990,7 +41990,7 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } - uint64_t requestId = static_cast(0); + uint64_t requestID = static_cast(0); uint16_t responseTimeoutSeconds = static_cast(0); CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -42006,7 +42006,7 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } - uint64_t requestId = static_cast(0); + uint64_t requestID = static_cast(0); uint16_t responseTimeoutSeconds = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -42133,8 +42133,8 @@ static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; enum class Fields : uint8_t { - kRequestId = 0, - kClientNodeId = 1, + kRequestID = 0, + kClientNodeID = 1, kStatusCode = 2, kFabricIndex = 254, }; @@ -42147,8 +42147,8 @@ struct Type static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } static constexpr bool kIsFabricScoped = true; - uint64_t requestId = static_cast(0); - chip::NodeId clientNodeId = static_cast(0); + uint64_t requestID = static_cast(0); + chip::NodeId clientNodeID = static_cast(0); uint8_t statusCode = static_cast(0); chip::FabricIndex fabricIndex = static_cast(0); @@ -42164,8 +42164,8 @@ struct DecodableType static constexpr EventId GetEventId() { return Events::CommissioningRequestResult::Id; } static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } - uint64_t requestId = static_cast(0); - chip::NodeId clientNodeId = static_cast(0); + uint64_t requestID = static_cast(0); + chip::NodeId clientNodeID = static_cast(0); uint8_t statusCode = static_cast(0); chip::FabricIndex fabricIndex = static_cast(0); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 1c6f6af5db03ff..c01a3135dc46bd 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -13842,9 +13842,9 @@ class CommissionerControlRequestCommissioningApproval : public ClusterCommand CommissionerControlRequestCommissioningApproval(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("request-commissioning-approval", credsIssuerConfig) { - AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); - AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); - AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); + AddArgument("RequestID", 0, UINT64_MAX, &mRequest.requestID); + AddArgument("VendorID", 0, UINT16_MAX, &mRequest.vendorID); + AddArgument("ProductID", 0, UINT16_MAX, &mRequest.productID); AddArgument("Label", &mRequest.label); ClusterCommand::AddArguments(); } @@ -13883,7 +13883,7 @@ class CommissionerControlCommissionNode : public ClusterCommand CommissionerControlCommissionNode(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("commission-node", credsIssuerConfig) { - AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("RequestID", 0, UINT64_MAX, &mRequest.requestID); AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); ClusterCommand::AddArguments(); } diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index f8946b7327fabd..2d788bd2613215 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -7896,18 +7896,18 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = DataModelLogger::LogValue("RequestId", indent + 1, value.requestId); + CHIP_ERROR err = DataModelLogger::LogValue("RequestID", indent + 1, value.requestID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RequestId'"); + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RequestID'"); return err; } } { - CHIP_ERROR err = DataModelLogger::LogValue("ClientNodeId", indent + 1, value.clientNodeId); + CHIP_ERROR err = DataModelLogger::LogValue("ClientNodeID", indent + 1, value.clientNodeID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ClientNodeId'"); + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ClientNodeID'"); return err; } } diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 85632c6b4c8520..0f3dc4f7991331 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -164678,13 +164678,13 @@ class CommissionerControlRequestCommissioningApproval : public ClusterCommand { : ClusterCommand("request-commissioning-approval") { #if MTR_ENABLE_PROVISIONAL - AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("RequestID", 0, UINT64_MAX, &mRequest.requestID); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); + AddArgument("VendorID", 0, UINT16_MAX, &mRequest.vendorID); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); + AddArgument("ProductID", 0, UINT16_MAX, &mRequest.productID); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL AddArgument("Label", &mRequest.label); @@ -164704,13 +164704,13 @@ class CommissionerControlRequestCommissioningApproval : public ClusterCommand { __auto_type * params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; #if MTR_ENABLE_PROVISIONAL - params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; + params.requestID = [NSNumber numberWithUnsignedLongLong:mRequest.requestID]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - params.vendorId = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorId)]; + params.vendorID = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorID)]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - params.productId = [NSNumber numberWithUnsignedShort:mRequest.productId]; + params.productID = [NSNumber numberWithUnsignedShort:mRequest.productID]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL if (mRequest.label.HasValue()) { @@ -164753,7 +164753,7 @@ class CommissionerControlCommissionNode : public ClusterCommand { : ClusterCommand("commission-node") { #if MTR_ENABLE_PROVISIONAL - AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("RequestID", 0, UINT64_MAX, &mRequest.requestID); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); @@ -164773,7 +164773,7 @@ class CommissionerControlCommissionNode : public ClusterCommand { __auto_type * params = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; #if MTR_ENABLE_PROVISIONAL - params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; + params.requestID = [NSNumber numberWithUnsignedLongLong:mRequest.requestID]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL params.responseTimeoutSeconds = [NSNumber numberWithUnsignedShort:mRequest.responseTimeoutSeconds]; From 3660c0d13e54a07abacd74b71ba0b8f5e804f219 Mon Sep 17 00:00:00 2001 From: cdj <45139296+DejinChen@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:54:00 +0800 Subject: [PATCH 69/70] Auto-commissioner: remove primary network config if failed in commissioning SecondaryNetworkInterface device (#35255) --- src/controller/AutoCommissioner.cpp | 15 ++++++-- src/controller/CHIPDeviceController.cpp | 46 ++++++++++++++++-------- src/controller/CHIPDeviceController.h | 2 -- src/controller/CommissioningDelegate.cpp | 7 ++-- src/controller/CommissioningDelegate.h | 7 ++-- 5 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 0e83d7125cf175..64f132c3124cda 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -502,8 +502,16 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio case CommissioningStage::kEvictPreviousCaseSessions: return CommissioningStage::kFindOperationalForStayActive; case CommissioningStage::kPrimaryOperationalNetworkFailed: - return CommissioningStage::kDisablePrimaryNetworkInterface; - case CommissioningStage::kDisablePrimaryNetworkInterface: + if (mDeviceCommissioningInfo.network.wifi.endpoint == kRootEndpointId) + { + return CommissioningStage::kRemoveWiFiNetworkConfig; + } + else + { + return CommissioningStage::kRemoveThreadNetworkConfig; + } + case CommissioningStage::kRemoveWiFiNetworkConfig: + case CommissioningStage::kRemoveThreadNetworkConfig: return GetNextCommissioningStageNetworkSetup(currentStage, lastErr); case CommissioningStage::kFindOperationalForStayActive: return CommissioningStage::kICDSendStayActive; @@ -567,7 +575,8 @@ EndpointId AutoCommissioner::GetEndpoint(const CommissioningStage & stage) const case CommissioningStage::kThreadNetworkSetup: case CommissioningStage::kThreadNetworkEnable: return mDeviceCommissioningInfo.network.thread.endpoint; - case CommissioningStage::kDisablePrimaryNetworkInterface: + case CommissioningStage::kRemoveWiFiNetworkConfig: + case CommissioningStage::kRemoveThreadNetworkConfig: return kRootEndpointId; default: return kRootEndpointId; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 955e36bfb0d8a2..7c43d50c082389 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1878,12 +1878,6 @@ void DeviceCommissioner::OnBasicSuccess(void * context, const chip::app::DataMod commissioner->CommissioningStageComplete(CHIP_NO_ERROR); } -void DeviceCommissioner::OnInterfaceEnableWriteSuccessResponse(void * context) -{ - DeviceCommissioner * commissioner = static_cast(context); - commissioner->CommissioningStageComplete(CHIP_NO_ERROR); -} - void DeviceCommissioner::OnBasicFailure(void * context, CHIP_ERROR error) { ChipLogProgress(Controller, "Received failure response %s\n", chip::ErrorStr(error)); @@ -3536,19 +3530,43 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio } break; case CommissioningStage::kPrimaryOperationalNetworkFailed: { - // nothing to do. This stage indicates that the primary operational network failed and the network interface should be - // disabled later. + // nothing to do. This stage indicates that the primary operational network failed and the network config should be + // removed later. break; } - case CommissioningStage::kDisablePrimaryNetworkInterface: { - NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo::Type request = false; - CHIP_ERROR err = SendCommissioningWriteRequest(proxy, endpoint, NetworkCommissioning::Id, - NetworkCommissioning::Attributes::InterfaceEnabled::Id, request, - OnInterfaceEnableWriteSuccessResponse, OnBasicFailure); + case CommissioningStage::kRemoveWiFiNetworkConfig: { + NetworkCommissioning::Commands::RemoveNetwork::Type request; + request.networkID = params.GetWiFiCredentials().Value().ssid; + request.breadcrumb.Emplace(breadcrumb); + CHIP_ERROR err = SendCommissioningCommand(proxy, request, OnNetworkConfigResponse, OnBasicFailure, endpoint, timeout); + if (err != CHIP_NO_ERROR) + { + // We won't get any async callbacks here, so just complete our stage. + ChipLogError(Controller, "Failed to send RemoveNetwork command: %" CHIP_ERROR_FORMAT, err.Format()); + CommissioningStageComplete(err); + return; + } + break; + } + case CommissioningStage::kRemoveThreadNetworkConfig: { + ByteSpan extendedPanId; + chip::Thread::OperationalDataset operationalDataset; + if (!params.GetThreadOperationalDataset().HasValue() || + operationalDataset.Init(params.GetThreadOperationalDataset().Value()) != CHIP_NO_ERROR || + operationalDataset.GetExtendedPanIdAsByteSpan(extendedPanId) != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Unable to get extended pan ID for thread operational dataset\n"); + CommissioningStageComplete(CHIP_ERROR_INVALID_ARGUMENT); + return; + } + NetworkCommissioning::Commands::RemoveNetwork::Type request; + request.networkID = extendedPanId; + request.breadcrumb.Emplace(breadcrumb); + CHIP_ERROR err = SendCommissioningCommand(proxy, request, OnNetworkConfigResponse, OnBasicFailure, endpoint, timeout); if (err != CHIP_NO_ERROR) { // We won't get any async callbacks here, so just complete our stage. - ChipLogError(Controller, "Failed to send InterfaceEnabled write request: %" CHIP_ERROR_FORMAT, err.Format()); + ChipLogError(Controller, "Failed to send RemoveNetwork command: %" CHIP_ERROR_FORMAT, err.Format()); CommissioningStageComplete(err); return; } diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 4b876156199735..2ec020340ee98d 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -980,8 +980,6 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, OnICDManagementStayActiveResponse(void * context, const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data); - static void OnInterfaceEnableWriteSuccessResponse(void * context); - /** * @brief * This function processes the CSR sent by the device. diff --git a/src/controller/CommissioningDelegate.cpp b/src/controller/CommissioningDelegate.cpp index 85ea5e86c5e3a6..d6acac6bc00bd4 100644 --- a/src/controller/CommissioningDelegate.cpp +++ b/src/controller/CommissioningDelegate.cpp @@ -139,8 +139,11 @@ const char * StageToString(CommissioningStage stage) case kPrimaryOperationalNetworkFailed: return "PrimaryOperationalNetworkFailed"; - case kDisablePrimaryNetworkInterface: - return "DisablePrimaryNetworkInterface"; + case kRemoveWiFiNetworkConfig: + return "RemoveWiFiNetworkConfig"; + + case kRemoveThreadNetworkConfig: + return "RemoveThreadNetworkConfig"; default: return "???"; diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 7a96939cf49434..f0f98961adf3c3 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -79,9 +79,10 @@ enum CommissioningStage : uint8_t /// Call CHIPDeviceController::NetworkCredentialsReady() when CommissioningParameters is populated with /// network credentials to use in kWiFiNetworkSetup or kThreadNetworkSetup steps. kNeedsNetworkCreds, - kPrimaryOperationalNetworkFailed, ///< Indicate that the primary operational network (on root endpoint) failed, should disable - ///< the primary network interface later. - kDisablePrimaryNetworkInterface, ///< Send InterfaceEnabled write request to the device to disable network interface. + kPrimaryOperationalNetworkFailed, ///< Indicate that the primary operational network (on root endpoint) failed, should remove + ///< the primary network config later. + kRemoveWiFiNetworkConfig, ///< Remove Wi-Fi network config. + kRemoveThreadNetworkConfig ///< Remove Thread network config. }; enum class ICDRegistrationStrategy : uint8_t From 2cf028b7d54be514547ccd37ee1077ad634b6d07 Mon Sep 17 00:00:00 2001 From: cdj <45139296+DejinChen@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:02:40 +0800 Subject: [PATCH 70/70] [ESP32] Support Thread and Wi-Fi network revert configuration (#33745) * ESP32: Support Thread and Wi-Fi network revert configuration * Update src/platform/ESP32/NetworkCommissioningDriver.cpp Co-authored-by: Wang Qixiang <43193572+wqx6@users.noreply.github.com> * Update KeyValueStoreManagerImpl.cpp --------- Co-authored-by: Wang Qixiang <43193572+wqx6@users.noreply.github.com> --- .../ESP32/KeyValueStoreManagerImpl.cpp | 2 +- .../ESP32/NetworkCommissioningDriver.cpp | 104 ++++++++++++------ .../ESP32/NetworkCommissioningDriver.h | 2 +- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/platform/ESP32/KeyValueStoreManagerImpl.cpp b/src/platform/ESP32/KeyValueStoreManagerImpl.cpp index 6617bb2cb11bf0..3c587167334de2 100644 --- a/src/platform/ESP32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/ESP32/KeyValueStoreManagerImpl.cpp @@ -68,7 +68,7 @@ KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset_bytes) { - VerifyOrReturnError(value, CHIP_ERROR_INVALID_ARGUMENT); + // value may be NULL when checking whether the key exists // Offset and partial reads are not supported in nvs, for now just return NOT_IMPLEMENTED. Support can be added in the // future if this is needed. diff --git a/src/platform/ESP32/NetworkCommissioningDriver.cpp b/src/platform/ESP32/NetworkCommissioningDriver.cpp index 2871c4c3f2031d..ee061fb746681e 100644 --- a/src/platform/ESP32/NetworkCommissioningDriver.cpp +++ b/src/platform/ESP32/NetworkCommissioningDriver.cpp @@ -95,39 +95,31 @@ CHIP_ERROR GetConfiguredNetwork(Network & network) CHIP_ERROR ESPWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback) { - CHIP_ERROR err; - size_t ssidLen = 0; - size_t credentialsLen = 0; - - err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials, - sizeof(mSavedNetwork.credentials), &credentialsLen); - if (err == CHIP_ERROR_NOT_FOUND) + wifi_config_t stationConfig; + if (esp_wifi_get_config(WIFI_IF_STA, &stationConfig) == ESP_OK && stationConfig.sta.ssid[0] != 0) { - return CHIP_NO_ERROR; - } + uint8_t ssidLen = static_cast( + strnlen(reinterpret_cast(stationConfig.sta.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength)); + memcpy(mStagingNetwork.ssid, stationConfig.sta.ssid, ssidLen); + mStagingNetwork.ssidLen = ssidLen; - err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, mSavedNetwork.ssid, sizeof(mSavedNetwork.ssid), &ssidLen); - if (err == CHIP_ERROR_NOT_FOUND) - { - return CHIP_NO_ERROR; - } - if (!CanCastTo(credentialsLen)) - { - return CHIP_ERROR_INCORRECT_STATE; - } - mSavedNetwork.credentialsLen = static_cast(credentialsLen); + uint8_t credentialsLen = static_cast( + strnlen(reinterpret_cast(stationConfig.sta.password), DeviceLayer::Internal::kMaxWiFiKeyLength)); - if (!CanCastTo(ssidLen)) - { - return CHIP_ERROR_INCORRECT_STATE; + memcpy(mStagingNetwork.credentials, stationConfig.sta.password, credentialsLen); + mStagingNetwork.credentialsLen = credentialsLen; } - mSavedNetwork.ssidLen = static_cast(ssidLen); - mStagingNetwork = mSavedNetwork; mpScanCallback = nullptr; mpConnectCallback = nullptr; mpStatusChangeCallback = networkStatusChangeCallback; - return err; + + // If the network configuration backup exists, it means that the device has been rebooted with + // the fail-safe armed. Since ESP-WiFi persists all wifi credentials changes, the backup must + // be restored on the boot. If there's no backup, the below function is a no-op. + RevertConfiguration(); + + return CHIP_NO_ERROR; } void ESPWiFiDriver::Shutdown() @@ -137,17 +129,51 @@ void ESPWiFiDriver::Shutdown() CHIP_ERROR ESPWiFiDriver::CommitConfiguration() { - ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); - ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials, - mStagingNetwork.credentialsLen)); - mSavedNetwork = mStagingNetwork; + PersistedStorage::KeyValueStoreMgr().Delete(kWiFiSSIDKeyName); + PersistedStorage::KeyValueStoreMgr().Delete(kWiFiCredentialsKeyName); + return CHIP_NO_ERROR; } CHIP_ERROR ESPWiFiDriver::RevertConfiguration() { - mStagingNetwork = mSavedNetwork; - return CHIP_NO_ERROR; + WiFiNetwork network; + Network configuredNetwork; + size_t ssidLen = 0; + size_t credentialsLen = 0; + + CHIP_ERROR error = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, network.ssid, sizeof(network.ssid), &ssidLen); + ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + VerifyOrExit(CanCastTo(ssidLen), error = CHIP_ERROR_INTERNAL); + VerifyOrExit(PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, network.credentials, sizeof(network.credentials), + &credentialsLen) == CHIP_NO_ERROR, + error = CHIP_ERROR_INTERNAL); + VerifyOrExit(CanCastTo(credentialsLen), error = CHIP_ERROR_INTERNAL); + + network.ssidLen = static_cast(ssidLen); + network.credentialsLen = static_cast(credentialsLen); + mStagingNetwork = network; + + if (GetConfiguredNetwork(configuredNetwork) == CHIP_NO_ERROR) + { + VerifyOrExit(!NetworkMatch(mStagingNetwork, ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)), + error = CHIP_NO_ERROR); + } + + if (error == CHIP_NO_ERROR) + { + // ConnectWiFiNetwork can work with empty mStagingNetwork (ssidLen = 0). + error = ConnectWiFiNetwork(reinterpret_cast(mStagingNetwork.ssid), mStagingNetwork.ssidLen, + reinterpret_cast(mStagingNetwork.credentials), mStagingNetwork.credentialsLen); + } + +exit: + + // Remove the backup. + PersistedStorage::KeyValueStoreMgr().Delete(kWiFiSSIDKeyName); + PersistedStorage::KeyValueStoreMgr().Delete(kWiFiCredentialsKeyName); + + return error; } bool ESPWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId) @@ -163,6 +189,7 @@ Status ESPWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, Mu VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded); VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange); VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); + VerifyOrReturnError(BackupConfiguration() == CHIP_NO_ERROR, Status::kUnknownError); memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size()); mStagingNetwork.credentialsLen = static_cast(credentials.size()); @@ -178,6 +205,7 @@ Status ESPWiFiDriver::RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDeb outDebugText.reduce_size(0); outNetworkIndex = 0; VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + VerifyOrReturnError(BackupConfiguration() == CHIP_NO_ERROR, Status::kUnknownError); // Use empty ssid for representing invalid network mStagingNetwork.ssidLen = 0; @@ -273,6 +301,7 @@ void ESPWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callbac const uint32_t secToMiliSec = 1000; VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), networkingStatus = Status::kNetworkIDNotFound); + VerifyOrExit(BackupConfiguration() == CHIP_NO_ERROR, networkingStatus = Status::kUnknownError); VerifyOrExit(mpConnectCallback == nullptr, networkingStatus = Status::kUnknownError); ChipLogProgress(NetworkProvisioning, "ESP NetworkCommissioningDelegate: SSID: %.*s", static_cast(networkId.size()), networkId.data()); @@ -484,6 +513,19 @@ bool ESPWiFiDriver::WiFiNetworkIterator::Next(Network & item) return true; } +CHIP_ERROR ESPWiFiDriver::BackupConfiguration() +{ + CHIP_ERROR err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, nullptr, 0); + if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials, + mStagingNetwork.credentialsLen)); + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + return CHIP_NO_ERROR; +} + } // namespace NetworkCommissioning } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/ESP32/NetworkCommissioningDriver.h b/src/platform/ESP32/NetworkCommissioningDriver.h index 447d6346dcbd1c..7c89e564292682 100644 --- a/src/platform/ESP32/NetworkCommissioningDriver.h +++ b/src/platform/ESP32/NetworkCommissioningDriver.h @@ -133,8 +133,8 @@ class ESPWiFiDriver final : public WiFiDriver private: bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId); CHIP_ERROR StartScanWiFiNetworks(ByteSpan ssid); + CHIP_ERROR BackupConfiguration(); - WiFiNetwork mSavedNetwork; WiFiNetwork mStagingNetwork; ScanCallback * mpScanCallback; ConnectCallback * mpConnectCallback;