diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index c61ac770a608ff..83d3f1c893261d 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -37,16 +37,6 @@ menu "CHIP Core" exchange (conversation) with a peer, e.g. a cloud service, a mobile application, or another device. - config MAX_BINDINGS - int "Max Bindings" - range 0 65535 - default 8 - help - The maximum number of simultaneously active CHIP Binding objects. - - A Binding object is used to configure how the local device communicates with - a remote entity, be it a cloud service, a mobile application, or another device. - config MAX_FABRICS int "Max Fabrics" range 5 255 diff --git a/examples/air-quality-sensor-app/silabs/build_for_wifi_args.gni b/examples/air-quality-sensor-app/silabs/build_for_wifi_args.gni index 718600a8115e59..8b5ccad9ebc272 100644 --- a/examples/air-quality-sensor-app/silabs/build_for_wifi_args.gni +++ b/examples/air-quality-sensor-app/silabs/build_for_wifi_args.gni @@ -15,7 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_wifi = true chip_enable_ota_requestor = true app_data_model = diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 31292543ca5f50..c35efdf4def94e 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/air-quality-server" diff --git a/examples/all-clusters-app/nxp/mw320/include/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/mw320/include/CHIPProjectConfig.h index 5e4a6b1e4f5419..d39e2dc0c03f6d 100644 --- a/examples/all-clusters-app/nxp/mw320/include/CHIPProjectConfig.h +++ b/examples/all-clusters-app/nxp/mw320/include/CHIPProjectConfig.h @@ -143,15 +143,6 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h +++ b/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h +++ b/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h index 2653e97705fe39..33a42909f464ea 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h +++ b/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -168,15 +168,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt index f82f301e3ae362..680d4a9c02636e 100644 --- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/application-basic-server" diff --git a/examples/bridge-app/esp32/main/CMakeLists.txt b/examples/bridge-app/esp32/main/CMakeLists.txt index 3330f6971b68cd..9d34b44a92f0e1 100644 --- a/examples/bridge-app/esp32/main/CMakeLists.txt +++ b/examples/bridge-app/esp32/main/CMakeLists.txt @@ -23,6 +23,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index 5c8963f7735f6d..a7905ff214c584 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -79,6 +79,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" ) diff --git a/examples/chef/silabs/build_for_wifi_args.gni b/examples/chef/silabs/build_for_wifi_args.gni index 9394037ba0ee38..97180fa504123a 100644 --- a/examples/chef/silabs/build_for_wifi_args.gni +++ b/examples/chef/silabs/build_for_wifi_args.gni @@ -15,6 +15,6 @@ import("//build_overrides/chip.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true diff --git a/examples/dishwasher-app/silabs/build_for_wifi_args.gni b/examples/dishwasher-app/silabs/build_for_wifi_args.gni index 7e52816578fbee..0a421db59d117d 100644 --- a/examples/dishwasher-app/silabs/build_for_wifi_args.gni +++ b/examples/dishwasher-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") sl_enable_test_event_trigger = true chip_enable_ota_requestor = true diff --git a/examples/energy-management-app/esp32/main/CMakeLists.txt b/examples/energy-management-app/esp32/main/CMakeLists.txt index e5459616238d3d..06623d3faf839d 100644 --- a/examples/energy-management-app/esp32/main/CMakeLists.txt +++ b/examples/energy-management-app/esp32/main/CMakeLists.txt @@ -44,6 +44,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/energy-management-app/silabs/build_for_wifi_args.gni b/examples/energy-management-app/silabs/build_for_wifi_args.gni index 1b1c0ecd6a7c78..feeffecd6f935a 100644 --- a/examples/energy-management-app/silabs/build_for_wifi_args.gni +++ b/examples/energy-management-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") sl_enable_test_event_trigger = true chip_enable_ota_requestor = false diff --git a/examples/fabric-admin/device_manager/CommissionerControl.cpp b/examples/fabric-admin/device_manager/CommissionerControl.cpp index 3c6dfa5a8a0f57..a0c24eb956d5bb 100644 --- a/examples/fabric-admin/device_manager/CommissionerControl.cpp +++ b/examples/fabric-admin/device_manager/CommissionerControl.cpp @@ -1,3 +1,21 @@ +/* + * 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 "CommissionerControl.h" #include "DeviceManager.h" diff --git a/examples/fabric-sync/admin/BUILD.gn b/examples/fabric-sync/admin/BUILD.gn index c2ab7152305204..2ccc30ca2f7976 100644 --- a/examples/fabric-sync/admin/BUILD.gn +++ b/examples/fabric-sync/admin/BUILD.gn @@ -15,16 +15,44 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") +config("config") { + include_dirs = [ + ".", + "${chip_root}/examples/fabric-sync", + "${chip_root}/examples/platform/linux", + "${chip_root}/src/lib", + ] +} + source_set("fabric-admin-lib") { + public_configs = [ ":config" ] + sources = [ + "BridgeSubscription.cpp", + "BridgeSubscription.h", + "CommissionerControl.cpp", + "CommissionerControl.h", "DeviceManager.cpp", "DeviceManager.h", + "DeviceSubscription.cpp", + "DeviceSubscription.h", + "DeviceSubscriptionManager.cpp", + "DeviceSubscriptionManager.h", + "DeviceSynchronization.cpp", + "DeviceSynchronization.h", + "FabricAdmin.cpp", + "FabricAdmin.h", + "FabricSyncGetter.cpp", + "FabricSyncGetter.h", "PairingManager.cpp", "PairingManager.h", + "UniqueIdGetter.cpp", + "UniqueIdGetter.h", ] deps = [ "${chip_root}/examples/fabric-sync/bridge:fabric-bridge-lib", + "${chip_root}/examples/platform/linux:app-main", "${chip_root}/src/lib", ] } diff --git a/examples/fabric-sync/admin/BridgeSubscription.cpp b/examples/fabric-sync/admin/BridgeSubscription.cpp new file mode 100644 index 00000000000000..1df9371ff74dff --- /dev/null +++ b/examples/fabric-sync/admin/BridgeSubscription.cpp @@ -0,0 +1,163 @@ +/* + * 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 "BridgeSubscription.h" +#include "DeviceManager.h" + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace admin { + +namespace { + +constexpr uint16_t kSubscribeMinInterval = 0; +constexpr uint16_t kSubscribeMaxInterval = 60; + +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); +} + +} // namespace + +BridgeSubscription::BridgeSubscription() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR BridgeSubscription::StartSubscription(Controller::DeviceController & controller, NodeId nodeId, EndpointId endpointId) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrDie(!subscriptionStarted); // Ensure it's not called multiple times. + + // Mark as started + subscriptionStarted = true; + + mEndpointId = endpointId; + + 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()); + } + return err; +} + +void BridgeSubscription::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + + if (data == nullptr) + { + ChipLogError(NotSpecified, "Response Failure: No Data"); + return; + } + + DeviceManager::Instance().HandleAttributeData(path, *data); +} + +void BridgeSubscription::OnEventData(const app::EventHeader & eventHeader, TLV::TLVReader * data, const app::StatusIB * status) +{ + if (status != nullptr) + { + CHIP_ERROR error = status->ToChipError(); + if (CHIP_NO_ERROR != error) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + } + + if (data == nullptr) + { + ChipLogError(NotSpecified, "Response Failure: No Data"); + return; + } + + DeviceManager::Instance().HandleEventData(eventHeader, *data); +} + +void BridgeSubscription::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error on remote fabric sync bridge subscription: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void BridgeSubscription::OnDone(ReadClient * apReadClient) +{ + mClient.reset(); + ChipLogProgress(NotSpecified, "The remote fabric sync bridge subscription is terminated"); + + // Reset the subscription state to allow retry + subscriptionStarted = false; + + // TODO:(#36092) Fabric-Admin should attempt to re-subscribe when the subscription to the remote bridge is terminated. +} + +void BridgeSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Subscribe); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(mEndpointId, Clusters::Descriptor::Id, Clusters::Descriptor::Attributes::PartsList::Id); + + EventPathParams eventPaths[1]; + eventPaths[0] = EventPathParams(mEndpointId, Clusters::CommissionerControl::Id, + Clusters::CommissionerControl::Events::CommissioningRequestResult::Id); + eventPaths[0].mIsUrgentEvent = true; + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + readParams.mpEventPathParamsList = eventPaths; + readParams.mEventPathParamsListSize = 1; + readParams.mMinIntervalFloorSeconds = kSubscribeMinInterval; + readParams.mMaxIntervalCeilingSeconds = kSubscribeMaxInterval; + readParams.mKeepSubscriptions = true; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to issue subscription to the Descriptor Cluster of the remote bridged device."); + OnDone(nullptr); + return; + } +} + +void BridgeSubscription::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "BridgeSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + OnDone(nullptr); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/BridgeSubscription.h b/examples/fabric-sync/admin/BridgeSubscription.h new file mode 100644 index 00000000000000..e5f8c73fc14257 --- /dev/null +++ b/examples/fabric-sync/admin/BridgeSubscription.h @@ -0,0 +1,81 @@ +/* + * 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 admin { + +/** + * @brief Class used to subscribe to attributes and events from the remote bridged device. + * + * The Descriptor Cluster contains attributes such as the Parts List, which provides a list + * of endpoints or devices that are part of a composite device or bridge. The CommissionerControl + * Cluster generates events related to commissioning requests, which can be monitored to track + * device commissioning status. + * + * When subscribing to attributes and events of a bridged device from another fabric, the class: + * - Establishes a secure session with the device (if needed) via CASE (Chip over + * Authenticated Session Establishment) session. + * - Subscribes to the specified attributes in the Descriptor Cluster (e.g., Parts List) and + * events in the CommissionerControl Cluster (e.g., CommissioningRequestResult) of the remote + * device on the specified node and endpoint. + * - Invokes the provided callback upon successful or unsuccessful subscription, allowing + * further handling of data or errors. + * + * This class also implements the necessary callbacks to handle attribute data reports, event data, + * errors, and session establishment procedures. + */ +class BridgeSubscription : public chip::app::ReadClient::Callback +{ +public: + BridgeSubscription(); + + CHIP_ERROR StartSubscription(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 OnEventData(const chip::app::EventHeader & eventHeader, chip::TLV::TLVReader * data, + const chip::app::StatusIB * status) 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; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + chip::EndpointId mEndpointId; + bool subscriptionStarted = false; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/CommissionerControl.cpp b/examples/fabric-sync/admin/CommissionerControl.cpp new file mode 100644 index 00000000000000..a0c24eb956d5bb --- /dev/null +++ b/examples/fabric-sync/admin/CommissionerControl.cpp @@ -0,0 +1,166 @@ +/* + * 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 "CommissionerControl.h" +#include "DeviceManager.h" + +using namespace ::chip; + +namespace admin { + +void CommissionerControl::Init(Controller::DeviceCommissioner & commissioner, NodeId nodeId, EndpointId endpointId) +{ + // Ensure that mCommissioner is not already initialized + VerifyOrDie(mCommissioner == nullptr); + + ChipLogProgress(NotSpecified, "Initilize CommissionerControl"); + mCommissioner = &commissioner; + mDestinationId = nodeId; + mEndpointId = endpointId; +} + +CHIP_ERROR CommissionerControl::RequestCommissioningApproval(uint64_t requestId, uint16_t vendorId, uint16_t productId, + Optional label) +{ + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + + ChipLogProgress(NotSpecified, "Sending RequestCommissioningApproval to node " ChipLogFormatX64, + ChipLogValueX64(mDestinationId)); + + mRequestCommissioningApproval.requestID = requestId; + mRequestCommissioningApproval.vendorID = static_cast(vendorId); + mRequestCommissioningApproval.productID = productId; + + if (label.HasValue()) + { + VerifyOrReturnError(label.Value().size() <= kMaxDeviceLabelLength, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(mLabelBuffer, label.Value().data(), label.Value().size()); + mRequestCommissioningApproval.label = Optional>(CharSpan(mLabelBuffer, label.Value().size())); + } + + mCommandType = CommandType::kRequestCommissioningApproval; + return mCommissioner->GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); +} + +CHIP_ERROR CommissionerControl::CommissionNode(uint64_t requestId, uint16_t responseTimeoutSeconds) +{ + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + + ChipLogProgress(NotSpecified, "Sending CommissionNode to node " ChipLogFormatX64, ChipLogValueX64(mDestinationId)); + + mCommissionNode.requestID = requestId; + mCommissionNode.responseTimeoutSeconds = responseTimeoutSeconds; + + mCommandType = CommandType::kCommissionNode; + return mCommissioner->GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); +} + +void CommissionerControl::OnResponse(app::CommandSender * client, const app::ConcreteCommandPath & path, + const app::StatusIB & status, TLV::TLVReader * data) +{ + ChipLogProgress(NotSpecified, "CommissionerControl: OnResponse."); + + CHIP_ERROR error = status.ToChipError(); + if (CHIP_NO_ERROR != error) + { + ChipLogError(NotSpecified, "Response Failure: %s", ErrorStr(error)); + return; + } + + if (data != nullptr) + { + DeviceManager::Instance().HandleCommandResponse(path, *data); + } +} + +void CommissionerControl::OnError(const app::CommandSender * client, CHIP_ERROR error) +{ + // Handle the error, then reset mCommandSender + ChipLogProgress(NotSpecified, "CommissionerControl: OnError: Error: %s", ErrorStr(error)); +} + +void CommissionerControl::OnDone(app::CommandSender * client) +{ + ChipLogProgress(NotSpecified, "CommissionerControl: OnDone."); + + switch (mCommandType) + { + case CommandType::kRequestCommissioningApproval: + ChipLogProgress(NotSpecified, "CommissionerControl: Command RequestCommissioningApproval has been successfully processed."); + break; + + case CommandType::kCommissionNode: + ChipLogProgress(NotSpecified, "CommissionerControl: Command CommissionNode has been successfully processed."); + break; + + default: + ChipLogError(NotSpecified, "CommissionerControl: Unknown or unhandled command type in OnDone."); + break; + } + + // Reset command type to undefined after processing is done + mCommandType = CommandType::kUndefined; + + // Ensure that mCommandSender is cleaned up after it is done + mCommandSender.reset(); +} + +CHIP_ERROR CommissionerControl::SendCommandForType(CommandType commandType, DeviceProxy * device) +{ + ChipLogProgress(AppServer, "Sending command with Endpoint ID: %d, Command Type: %d", mEndpointId, + static_cast(commandType)); + + switch (commandType) + { + case CommandType::kRequestCommissioningApproval: + return SendCommand(device, mEndpointId, app::Clusters::CommissionerControl::Id, + app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id, + mRequestCommissioningApproval); + case CommandType::kCommissionNode: + return SendCommand(device, mEndpointId, app::Clusters::CommissionerControl::Id, + app::Clusters::CommissionerControl::Commands::CommissionNode::Id, mCommissionNode); + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } +} + +void CommissionerControl::OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, + const SessionHandle & sessionHandle) +{ + CommissionerControl * self = reinterpret_cast(context); + VerifyOrReturn(self != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); + + OperationalDeviceProxy device(&exchangeMgr, sessionHandle); + + CHIP_ERROR err = self->SendCommandForType(self->mCommandType, &device); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to send CommissionerControl command."); + self->OnDone(nullptr); + } +} + +void CommissionerControl::OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR err) +{ + LogErrorOnFailure(err); + CommissionerControl * self = reinterpret_cast(context); + VerifyOrReturn(self != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); + self->OnDone(nullptr); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/CommissionerControl.h b/examples/fabric-sync/admin/CommissionerControl.h new file mode 100644 index 00000000000000..392367d6c04367 --- /dev/null +++ b/examples/fabric-sync/admin/CommissionerControl.h @@ -0,0 +1,129 @@ +/* + * 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 + +namespace admin { + +/** + * @class CommissionerControl + * @brief This class handles sending CHIP commands related to commissioning, including sending + * commissioning approval requests and commissioning nodes. + * + * The class acts as a command sender and implements the `chip::app::CommandSender::Callback` interface + * to handle responses, errors, and completion events for the commands it sends. It relies on external + * CCTRL delegate and server mechanisms to manage the overall protocol and state transitions, including + * processing the CommissioningRequestResult and invoking CommissionNode. + */ +class CommissionerControl : public chip::app::CommandSender::Callback +{ +public: + CommissionerControl() : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + {} + + /** + * @brief Initializes the CommissionerControl with a DeviceCommissioner, NodeId, and EndpointId. + * + * @param commissioner The DeviceCommissioner to use for the commissioning process. + * @param nodeId The node ID of the remote fabric bridge. + * @param endpointId The endpoint on which to send CommissionerControl commands. + */ + void Init(chip::Controller::DeviceCommissioner & commissioner, chip::NodeId nodeId, chip::EndpointId endpointId); + + /** + * @brief Sends a RequestCommissioningApproval command to the device. + * + * @param requestId The unique request ID. + * @param vendorId The vendor ID of the device. + * @param productId The product ID of the device. + * @param label Optional label for the device. + * @return CHIP_ERROR CHIP_NO_ERROR on success, or an appropriate error code on failure. + */ + CHIP_ERROR RequestCommissioningApproval(uint64_t requestId, uint16_t vendorId, uint16_t productId, + chip::Optional label); + /** + * @brief Sends a CommissionNode command to the device. + * + * @param requestId The unique request ID. + * @param responseTimeoutSeconds Timeout for the response in seconds. + * @return CHIP_ERROR CHIP_NO_ERROR on success, or an appropriate error code on failure. + */ + CHIP_ERROR CommissionNode(uint64_t requestId, uint16_t responseTimeoutSeconds); + + /////////// CommandSender Callback Interface ///////// + virtual void OnResponse(chip::app::CommandSender * client, const chip::app::ConcreteCommandPath & path, + const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override; + + virtual void OnError(const chip::app::CommandSender * client, CHIP_ERROR error) override; + + virtual void OnDone(chip::app::CommandSender * client) override; + +private: + static constexpr uint16_t kMaxDeviceLabelLength = 64; + + enum class CommandType : uint8_t + { + kUndefined = 0, + kRequestCommissioningApproval = 1, + kCommissionNode = 2, + }; + + template + CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, + chip::CommandId commandId, const T & value) + { + chip::app::CommandPathParams commandPath = { endpointId, clusterId, commandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + mCommandSender = std::make_unique(this, device->GetExchangeManager(), false, false, + device->GetSecureSession().Value()->AllowsLargePayload()); + + VerifyOrReturnError(mCommandSender != nullptr, CHIP_ERROR_NO_MEMORY); + + chip::app::CommandSender::AddRequestDataParameters addRequestDataParams(chip::NullOptional); + ReturnErrorOnFailure(mCommandSender->AddRequestData(commandPath, value, addRequestDataParams)); + ReturnErrorOnFailure(mCommandSender->SendCommandRequest(device->GetSecureSession().Value())); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR SendCommandForType(CommandType commandType, chip::DeviceProxy * device); + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle); + static void OnDeviceConnectionFailureFn(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error); + + // Private data members + chip::Controller::DeviceCommissioner * mCommissioner = nullptr; + std::unique_ptr mCommandSender; + chip::NodeId mDestinationId = chip::kUndefinedNodeId; + chip::EndpointId mEndpointId = chip::kRootEndpointId; + CommandType mCommandType = CommandType::kUndefined; + char mLabelBuffer[kMaxDeviceLabelLength]; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequestCommissioningApproval; + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mCommissionNode; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceManager.cpp b/examples/fabric-sync/admin/DeviceManager.cpp index 76863e6a33869e..6dfdad1213bc68 100644 --- a/examples/fabric-sync/admin/DeviceManager.cpp +++ b/examples/fabric-sync/admin/DeviceManager.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -18,6 +17,9 @@ #include "DeviceManager.h" +#include +#include +#include #include #include @@ -27,8 +29,14 @@ using namespace chip; namespace admin { -// Define the static member -DeviceManager DeviceManager::sInstance; + +namespace { + +constexpr EndpointId kAggregatorEndpointId = 1; + +} // namespace + +LinuxCommissionableDataProvider sCommissionableDataProvider; void DeviceManager::Init() { @@ -60,6 +68,68 @@ void DeviceManager::UpdateLastUsedNodeId(NodeId nodeId) void DeviceManager::SetRemoteBridgeNodeId(chip::NodeId nodeId) { mRemoteBridgeNodeId = nodeId; + + if (mRemoteBridgeNodeId != kUndefinedNodeId) + { + mCommissionerControl.Init(PairingManager::Instance().CurrentCommissioner(), mRemoteBridgeNodeId, kAggregatorEndpointId); + } +} + +SyncedDevice * DeviceManager::FindDeviceByEndpoint(EndpointId endpointId) +{ + for (auto & device : mSyncedDevices) + { + if (device.GetEndpointId() == endpointId) + { + return const_cast(&device); + } + } + return nullptr; +} + +SyncedDevice * DeviceManager::FindDeviceByNode(NodeId nodeId) +{ + for (auto & device : mSyncedDevices) + { + if (device.GetNodeId() == nodeId) + { + return const_cast(&device); + } + } + return nullptr; +} + +void DeviceManager::OpenLocalBridgeCommissioningWindow(uint32_t iterations, uint16_t commissioningTimeoutSec, + uint16_t discriminator, const ByteSpan & salt, const ByteSpan & verifier) +{ + ChipLogProgress(NotSpecified, "Opening commissioning window of the local bridge"); + + auto & commissionMgr = Server::GetInstance().GetCommissioningWindowManager(); + auto commissioningTimeout = System::Clock::Seconds16(commissioningTimeoutSec); + + Optional> spake2pVerifier = verifier.empty() + ? Optional>::Missing() + : Optional>(std::vector(verifier.begin(), verifier.end())); + + Optional> spake2pSalt = salt.empty() + ? Optional>::Missing() + : Optional>(std::vector(salt.begin(), salt.end())); + + CHIP_ERROR err = + sCommissionableDataProvider.Init(spake2pVerifier, spake2pSalt, iterations, Optional(), discriminator); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to initialize the commissionable data provider of the local bridge: %s", ErrorStr(err)); + return; + } + + DeviceLayer::SetCommissionableDataProvider(&sCommissionableDataProvider); + + err = commissionMgr.OpenBasicCommissioningWindow(commissioningTimeout); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to open commissioning window of the local bridge: %s", ErrorStr(err)); + } } CHIP_ERROR DeviceManager::PairRemoteFabricBridge(NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp, @@ -137,4 +207,265 @@ CHIP_ERROR DeviceManager::UnpairRemoteDevice(NodeId nodeId) return CHIP_NO_ERROR; } +void DeviceManager::SubscribeRemoteFabricBridge() +{ + ChipLogProgress(NotSpecified, "Start subscription to the remote bridge."); + + CHIP_ERROR error = mBridgeSubscriber.StartSubscription(PairingManager::Instance().CurrentCommissioner(), mRemoteBridgeNodeId, + kAggregatorEndpointId); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to subscribe to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } +} + +void DeviceManager::ReadSupportedDeviceCategories() +{ + if (!IsFabricSyncReady()) + { + // print to console + fprintf(stderr, "Remote Fabric Bridge is not configured yet.\n"); + return; + } + + ChipLogProgress(NotSpecified, "Read SupportedDeviceCategories from the remote bridge."); + + CHIP_ERROR error = mFabricSyncGetter.GetFabricSynchronizationData( + [this](TLV::TLVReader & data) { this->HandleReadSupportedDeviceCategories(data); }, + PairingManager::Instance().CurrentCommissioner(), this->GetRemoteBridgeNodeId(), kAggregatorEndpointId); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to read SupportedDeviceCategories from the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + } +} + +void DeviceManager::HandleReadSupportedDeviceCategories(TLV::TLVReader & data) +{ + ChipLogProgress(NotSpecified, "Attribute SupportedDeviceCategories detected."); + + BitMask value; + CHIP_ERROR error = app::DataModel::Decode(data, value); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to decode attribute value. Error: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + + if (value.Has(app::Clusters::CommissionerControl::SupportedDeviceCategoryBitmap::kFabricSynchronization)) + { + ChipLogProgress(NotSpecified, "Remote Fabric-Bridge supports Fabric Synchronization, start reverse commissioning."); + RequestCommissioningApproval(); + } + else + { + ChipLogProgress(NotSpecified, "Remote Fabric-Bridge does not support Fabric Synchronization."); + } +} + +void DeviceManager::RequestCommissioningApproval() +{ + ChipLogProgress(NotSpecified, "Starting reverse commissioning for bridge device: NodeId: " ChipLogFormatX64, + ChipLogValueX64(mRemoteBridgeNodeId)); + + uint64_t requestId = Crypto::GetRandU64(); + uint16_t vendorId = static_cast(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID); + uint16_t productId = static_cast(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID); + + CHIP_ERROR error = mCommissionerControl.RequestCommissioningApproval(requestId, vendorId, productId, NullOptional); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to request commissioning-approval to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } + + mRequestId = requestId; +} + +void DeviceManager::HandleCommissioningRequestResult(TLV::TLVReader & data) +{ + ChipLogProgress(NotSpecified, "CommissioningRequestResult event received."); + + app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType value; + CHIP_ERROR error = app::DataModel::Decode(data, value); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to decode event value. Error: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + + if (value.requestID != mRequestId) + { + ChipLogError(NotSpecified, "The RequestId does not match the RequestId provided to RequestCommissioningApproval"); + return; + } + + if (value.statusCode != static_cast(Protocols::InteractionModel::Status::Success)) + { + ChipLogError(NotSpecified, "The server is not ready to begin commissioning the requested device"); + return; + } + + // 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); +} + +void DeviceManager::HandleAttributePartsListUpdate(TLV::TLVReader & data) +{ + ChipLogProgress(NotSpecified, "Attribute PartsList change detected:"); + + app::DataModel::DecodableList value; + CHIP_ERROR error = app::DataModel::Decode(data, value); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to decode attribute value. Error: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + + std::set newEndpoints; + + // Populate the newEndpoints set from the decoded value using an iterator + auto iter = value.begin(); + while (iter.Next()) + { + newEndpoints.insert(iter.GetValue()); + } + + if (iter.GetStatus() != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to iterate over decoded attribute value."); + return; + } + + // Compare newEndpoints with mSyncedDevices to determine added and removed endpoints + std::vector addedEndpoints; + std::vector removedEndpoints; + + // Note: We're using vectors and manual searches instead of set operations + // because we need to work with the SyncedDevice objects in mSyncedDevices, + // not just their EndpointIds. This approach allows us to access the full + // Device information when processing changes. + + // Find added endpoints + for (const auto & endpoint : newEndpoints) + { + if (FindDeviceByEndpoint(endpoint) == nullptr) + { + addedEndpoints.push_back(endpoint); + } + } + + // Find removed endpoints + for (auto & device : mSyncedDevices) + { + EndpointId endpointId = device.GetEndpointId(); + if (newEndpoints.find(endpointId) == newEndpoints.end()) + { + removedEndpoints.push_back(endpointId); + } + } + + // Process added endpoints + for (const auto & endpoint : addedEndpoints) + { + // print to console + fprintf(stderr, "A new device is added on Endpoint: %u\n", endpoint); + } + + // Process removed endpoints + for (const auto & endpoint : removedEndpoints) + { + ChipLogProgress(NotSpecified, "Endpoint removed: %u", endpoint); + + SyncedDevice * device = FindDeviceByEndpoint(endpoint); + + if (device == nullptr) + { + ChipLogProgress(NotSpecified, "No device on Endpoint: %u", endpoint); + continue; + } + } +} + +void DeviceManager::SendCommissionNodeRequest(uint64_t requestId, uint16_t responseTimeoutSeconds) +{ + ChipLogProgress(NotSpecified, "Request the Commissioner Control Server to begin commissioning a previously approved request."); + + CHIP_ERROR error = mCommissionerControl.CommissionNode(requestId, responseTimeoutSeconds); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to send CommissionNode command to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } +} + +void DeviceManager::HandleReverseOpenCommissioningWindow(TLV::TLVReader & data) +{ + ChipLogProgress(NotSpecified, "Handle ReverseOpenCommissioningWindow command."); + + app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType value; + CHIP_ERROR error = app::DataModel::Decode(data, value); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to decode command response value. Error: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + + // Log all fields + ChipLogProgress(NotSpecified, "DecodableType fields:"); + ChipLogProgress(NotSpecified, " commissioningTimeout: %u", value.commissioningTimeout); + ChipLogProgress(NotSpecified, " discriminator: %u", value.discriminator); + ChipLogProgress(NotSpecified, " iterations: %u", value.iterations); + ChipLogProgress(NotSpecified, " PAKEPasscodeVerifier size: %lu", value.PAKEPasscodeVerifier.size()); + ChipLogProgress(NotSpecified, " salt size: %lu", value.salt.size()); + + OpenLocalBridgeCommissioningWindow(value.iterations, value.commissioningTimeout, value.discriminator, + ByteSpan(value.salt.data(), value.salt.size()), + ByteSpan(value.PAKEPasscodeVerifier.data(), value.PAKEPasscodeVerifier.size())); +} + +void DeviceManager::HandleAttributeData(const app::ConcreteDataAttributePath & path, TLV::TLVReader & data) +{ + if (path.mClusterId == app::Clusters::Descriptor::Id && + path.mAttributeId == app::Clusters::Descriptor::Attributes::PartsList::Id) + { + HandleAttributePartsListUpdate(data); + return; + } +} + +void DeviceManager::HandleEventData(const app::EventHeader & header, TLV::TLVReader & data) +{ + if (header.mPath.mClusterId == app::Clusters::CommissionerControl::Id && + header.mPath.mEventId == app::Clusters::CommissionerControl::Events::CommissioningRequestResult::Id) + { + HandleCommissioningRequestResult(data); + } +} + +void DeviceManager::HandleCommandResponse(const app::ConcreteCommandPath & path, TLV::TLVReader & data) +{ + ChipLogProgress(NotSpecified, "Command Response received."); + + if (path.mClusterId == app::Clusters::CommissionerControl::Id && + path.mCommandId == app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id) + { + VerifyOrDie(path.mEndpointId == kAggregatorEndpointId); + HandleReverseOpenCommissioningWindow(data); + } +} + } // namespace admin diff --git a/examples/fabric-sync/admin/DeviceManager.h b/examples/fabric-sync/admin/DeviceManager.h index db6ad9b528ade4..e114a62748549a 100644 --- a/examples/fabric-sync/admin/DeviceManager.h +++ b/examples/fabric-sync/admin/DeviceManager.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -18,18 +17,49 @@ #pragma once +#include "BridgeSubscription.h" +#include "CommissionerControl.h" +#include "FabricSyncGetter.h" #include "PairingManager.h" #include #include +#include namespace admin { +constexpr uint32_t kDefaultSetupPinCode = 20202021; +constexpr uint16_t kResponseTimeoutSeconds = 30; + +class SyncedDevice +{ +public: + SyncedDevice(chip::NodeId nodeId, chip::EndpointId endpointId) : mNodeId(nodeId), mEndpointId(endpointId) {} + + chip::NodeId GetNodeId() const { return mNodeId; } + chip::EndpointId GetEndpointId() const { return mEndpointId; } + + bool operator<(const SyncedDevice & other) const + { + return mNodeId < other.mNodeId || (mNodeId == other.mNodeId && mEndpointId < other.mEndpointId); + } + +private: + chip::NodeId mNodeId; + chip::EndpointId mEndpointId; +}; + class DeviceManager { public: DeviceManager() = default; + static DeviceManager & Instance() + { + static DeviceManager instance; + return instance; + } + void Init(); chip::NodeId GetNextAvailableNodeId(); @@ -51,6 +81,22 @@ class DeviceManager */ bool IsCurrentBridgeDevice(chip::NodeId nodeId) const { return nodeId == mRemoteBridgeNodeId; } + /** + * @brief Open the commissioning window of the local bridge. + * + * @param iterations The number of PBKDF (Password-Based Key Derivation Function) iterations to use + * for deriving the PAKE (Password Authenticated Key Exchange) verifier. + * @param commissioningTimeoutSec The time in seconds before the commissioning window closes. This value determines + * how long the commissioning window remains open for incoming connections. + * @param discriminator The device-specific discriminator, determined during commissioning, which helps + * to uniquely identify the device among others. + * @param salt The salt used in the cryptographic operations for commissioning. + * @param verifier The PAKE verifier used to authenticate the commissioning process. + * + */ + void OpenLocalBridgeCommissioningWindow(uint32_t iterations, uint16_t commissioningTimeoutSec, uint16_t discriminator, + const chip::ByteSpan & salt, const chip::ByteSpan & verifier); + /** * @brief Pair a remote fabric bridge with a given node ID. * @@ -116,10 +162,31 @@ class DeviceManager */ CHIP_ERROR UnpairRemoteDevice(chip::NodeId nodeId); + void SubscribeRemoteFabricBridge(); + + void ReadSupportedDeviceCategories(); + + void HandleAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader & data); + + void HandleEventData(const chip::app::EventHeader & header, chip::TLV::TLVReader & data); + + void HandleCommandResponse(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader & data); + + SyncedDevice * FindDeviceByEndpoint(chip::EndpointId endpointId); + SyncedDevice * FindDeviceByNode(chip::NodeId nodeId); + private: - friend DeviceManager & DeviceMgr(); + void RequestCommissioningApproval(); + + void HandleReadSupportedDeviceCategories(chip::TLV::TLVReader & data); + + void HandleCommissioningRequestResult(chip::TLV::TLVReader & data); - static DeviceManager sInstance; + void HandleAttributePartsListUpdate(chip::TLV::TLVReader & data); + + void SendCommissionNodeRequest(uint64_t requestId, uint16_t responseTimeoutSeconds); + + void HandleReverseOpenCommissioningWindow(chip::TLV::TLVReader & data); chip::NodeId mLastUsedNodeId = 0; @@ -127,22 +194,13 @@ class DeviceManager // This represents the bridge on the other ecosystem. chip::NodeId mRemoteBridgeNodeId = chip::kUndefinedNodeId; - bool mInitialized = false; -}; + std::set mSyncedDevices; + bool mInitialized = false; + uint64_t mRequestId = 0; -/** - * Returns the public interface of the DeviceManager singleton object. - * - * Applications should use this to access features of the DeviceManager - * object. - */ -inline DeviceManager & DeviceMgr() -{ - if (!DeviceManager::sInstance.mInitialized) - { - DeviceManager::sInstance.Init(); - } - return DeviceManager::sInstance; -} + BridgeSubscription mBridgeSubscriber; + CommissionerControl mCommissionerControl; + FabricSyncGetter mFabricSyncGetter; +}; } // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSubscription.cpp b/examples/fabric-sync/admin/DeviceSubscription.cpp new file mode 100644 index 00000000000000..9379df6910f84a --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSubscription.cpp @@ -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. + * + */ + +#include "DeviceSubscription.h" +#include "DeviceManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace admin { + +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); +} + +} // namespace + +DeviceSubscription::DeviceSubscription() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +void DeviceSubscription::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + VerifyOrDie(path.mEndpointId == kRootEndpointId); + VerifyOrDie(path.mClusterId == Clusters::AdministratorCommissioning::Id); + + switch (path.mAttributeId) + { + case Clusters::AdministratorCommissioning::Attributes::WindowStatus::Id: { + Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum windowStatus; + CHIP_ERROR err = data->Get(windowStatus); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(NotSpecified, "Failed to read WindowStatus")); + VerifyOrReturn(windowStatus != Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kUnknownEnumValue); + mCurrentAdministratorCommissioningAttributes.windowStatus = windowStatus; + mChangeDetected = true; + break; + } + case Clusters::AdministratorCommissioning::Attributes::AdminFabricIndex::Id: { + FabricIndex fabricIndex; + CHIP_ERROR err = data->Get(fabricIndex); + if (err == CHIP_NO_ERROR) + { + mCurrentAdministratorCommissioningAttributes.openerFabricIndex = fabricIndex; + } + else + { + mCurrentAdministratorCommissioningAttributes.openerFabricIndex.reset(); + } + + mChangeDetected = true; + break; + } + case Clusters::AdministratorCommissioning::Attributes::AdminVendorId::Id: { + VendorId vendorId; + CHIP_ERROR err = data->Get(vendorId); + if (err == CHIP_NO_ERROR) + { + mCurrentAdministratorCommissioningAttributes.openerVendorId = vendorId; + } + else + { + mCurrentAdministratorCommissioningAttributes.openerVendorId.reset(); + } + + mChangeDetected = true; + break; + } + default: + break; + } +} + +void DeviceSubscription::OnReportEnd() +{ + // Report end is at the end of all attributes (success) + if (mChangeDetected) + { + CHIP_ERROR err = + bridge::FabricBridge::Instance().AdminCommissioningAttributeChanged(mCurrentAdministratorCommissioningAttributes); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Cannot forward Administrator Commissioning Attribute to fabric bridge %" CHIP_ERROR_FORMAT, + err.Format()); + } + mChangeDetected = false; + } +} + +void DeviceSubscription::OnDone(ReadClient * apReadClient) +{ + // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with + // DeviceSubscription. + MoveToState(State::AwaitingDestruction); + mOnDoneCallback(mScopedNodeId); +} + +void DeviceSubscription::OnError(CHIP_ERROR error) +{ + if (error == CHIP_ERROR_TIMEOUT && mState == State::SubscriptionStarted) + { + if (bridge::FabricBridge::Instance().DeviceReachableChanged(mCurrentAdministratorCommissioningAttributes.id, false) != + CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to update the device reachability state"); + } + } + + ChipLogProgress(NotSpecified, "Error subscribing: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void DeviceSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + if (mState == State::Stopping) + { + // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with + // DeviceSubscription. + MoveToState(State::AwaitingDestruction); + mOnDoneCallback(mScopedNodeId); + return; + } + VerifyOrDie(mState == State::Connecting); + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Subscribe); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(kRootEndpointId, Clusters::AdministratorCommissioning::Id); + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + readParams.mMaxIntervalCeilingSeconds = 5 * 60; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to issue subscription to AdministratorCommissioning data"); + // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with + // DeviceSubscription. + MoveToState(State::AwaitingDestruction); + mOnDoneCallback(mScopedNodeId); + return; + } + MoveToState(State::SubscriptionStarted); +} + +void DeviceSubscription::MoveToState(const State aTargetState) +{ + mState = aTargetState; + ChipLogDetail(NotSpecified, "DeviceSubscription moving to [%10.10s]", GetStateStr()); +} + +const char * DeviceSubscription::GetStateStr() const +{ + switch (mState) + { + case State::Idle: + return "Idle"; + + case State::Connecting: + return "Connecting"; + + case State::Stopping: + return "Stopping"; + + case State::SubscriptionStarted: + return "SubscriptionStarted"; + + case State::AwaitingDestruction: + return "AwaitingDestruction"; + } + return "N/A"; +} + +void DeviceSubscription::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + VerifyOrDie(mState == State::Connecting || mState == State::Stopping); + ChipLogError(NotSpecified, "DeviceSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + + if (mState == State::Connecting) + { + if (bridge::FabricBridge::Instance().DeviceReachableChanged(mCurrentAdministratorCommissioningAttributes.id, false) != + CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to update the device reachability state"); + } + } + + // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with + // DeviceSubscription. + MoveToState(State::AwaitingDestruction); + mOnDoneCallback(mScopedNodeId); +} + +CHIP_ERROR DeviceSubscription::StartSubscription(OnDoneCallback onDoneCallback, Controller::DeviceController & controller, + ScopedNodeId scopedNodeId) +{ + assertChipStackLockedByCurrentThread(); + VerifyOrDie(mState == State::Idle); + VerifyOrReturnError(controller.GetFabricIndex() == scopedNodeId.GetFabricIndex(), CHIP_ERROR_INVALID_ARGUMENT); + + mScopedNodeId = scopedNodeId; + + mCurrentAdministratorCommissioningAttributes = AdministratorCommissioningChanged_init_default; + mCurrentAdministratorCommissioningAttributes.id = scopedNodeId; + mCurrentAdministratorCommissioningAttributes.windowStatus = + Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen; + + mOnDoneCallback = onDoneCallback; + MoveToState(State::Connecting); + CHIP_ERROR err = + controller.GetConnectedDevice(scopedNodeId.GetNodeId(), &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + MoveToState(State::Idle); + } + return err; +} + +void DeviceSubscription::StopSubscription() +{ + assertChipStackLockedByCurrentThread(); + VerifyOrDie(mState != State::Idle); + // Something is seriously wrong if we die on the line below + VerifyOrDie(mState != State::AwaitingDestruction); + + if (mState == State::Stopping) + { + // Stop is called again while we are still waiting on connected callbacks + return; + } + + if (mState == State::Connecting) + { + MoveToState(State::Stopping); + return; + } + + // By calling reset on our ReadClient we terminate the subscription. + VerifyOrDie(mClient); + mClient.reset(); + // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with + // DeviceSubscription. + MoveToState(State::AwaitingDestruction); + mOnDoneCallback(mScopedNodeId); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSubscription.h b/examples/fabric-sync/admin/DeviceSubscription.h new file mode 100644 index 00000000000000..59169223e6fbb7 --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSubscription.h @@ -0,0 +1,94 @@ +/* + * 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 +#include + +namespace admin { + +class DeviceSubscriptionManager; + +/// Attribute subscription to attributes that are important to keep track and send to fabric-bridge +/// via RPC when change has been identified. +/// +/// An instance of DeviceSubscription is intended to be used only once. Once a DeviceSubscription is +/// terminated, either from an error or from subscriptions getting shut down, we expect the instance +/// to be deleted. Any new subscription should instantiate another instance of DeviceSubscription. +class DeviceSubscription : public chip::app::ReadClient::Callback +{ +public: + using OnDoneCallback = std::function; + + DeviceSubscription(); + + CHIP_ERROR StartSubscription(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, + chip::ScopedNodeId nodeId); + + /// This will trigger stopping the subscription. Once subscription is stopped the OnDoneCallback + /// provided in StartSubscription will be called to indicate that subscription have been terminated. + /// + /// Must only be called after StartSubscription was successfully called. + void StopSubscription(); + + /////////////////////////////////////////////////////////////// + // 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: + 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 + Stopping, ///< We are waiting for OnDeviceConnected or OnDeviceConnectionFailure callbacks so we can terminate + SubscriptionStarted, ///< We have started a subscription. + AwaitingDestruction, ///< The object has completed its work and is awaiting destruction. + }; + + void MoveToState(const State aTargetState); + const char * GetStateStr() const; + + chip::ScopedNodeId mScopedNodeId; + + OnDoneCallback mOnDoneCallback; + std::unique_ptr mClient; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + + bridge::AdministratorCommissioningChanged mCurrentAdministratorCommissioningAttributes; + + bool mChangeDetected = false; + State mState = State::Idle; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSubscriptionManager.cpp b/examples/fabric-sync/admin/DeviceSubscriptionManager.cpp new file mode 100644 index 00000000000000..d2209bdd5d52ba --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSubscriptionManager.cpp @@ -0,0 +1,79 @@ +/* + * 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 "DeviceSubscriptionManager.h" +#include "DeviceManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app; + +namespace admin { + +DeviceSubscriptionManager & DeviceSubscriptionManager::Instance() +{ + static DeviceSubscriptionManager instance; + return instance; +} + +CHIP_ERROR DeviceSubscriptionManager::StartSubscription(Controller::DeviceController & controller, ScopedNodeId scopedNodeId) +{ + assertChipStackLockedByCurrentThread(); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); + VerifyOrReturnError((it == mDeviceSubscriptionMap.end()), CHIP_ERROR_INCORRECT_STATE); + + auto deviceSubscription = std::make_unique(); + VerifyOrReturnError(deviceSubscription, CHIP_ERROR_NO_MEMORY); + ReturnErrorOnFailure(deviceSubscription->StartSubscription( + [this](ScopedNodeId aNodeId) { this->DeviceSubscriptionTerminated(aNodeId); }, controller, scopedNodeId)); + + mDeviceSubscriptionMap[scopedNodeId] = std::move(deviceSubscription); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DeviceSubscriptionManager::RemoveSubscription(ScopedNodeId scopedNodeId) +{ + assertChipStackLockedByCurrentThread(); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); + VerifyOrReturnError((it != mDeviceSubscriptionMap.end()), CHIP_ERROR_NOT_FOUND); + // We cannot safely erase the DeviceSubscription from mDeviceSubscriptionMap. + // After calling StopSubscription we expect DeviceSubscription to eventually + // call the OnDoneCallback we provided in StartSubscription which will call + // DeviceSubscriptionTerminated where it will be erased from the + // mDeviceSubscriptionMap. + it->second->StopSubscription(); + return CHIP_NO_ERROR; +} + +void DeviceSubscriptionManager::DeviceSubscriptionTerminated(ScopedNodeId scopedNodeId) +{ + assertChipStackLockedByCurrentThread(); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); + // DeviceSubscriptionTerminated is a private method that is expected to only + // be called by DeviceSubscription when it is terminal and is ready to be + // cleaned up and removed. If it is not mapped that means something has gone + // really wrong and there is likely a memory leak somewhere. + VerifyOrDie(it != mDeviceSubscriptionMap.end()); + mDeviceSubscriptionMap.erase(scopedNodeId); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSubscriptionManager.h b/examples/fabric-sync/admin/DeviceSubscriptionManager.h new file mode 100644 index 00000000000000..eb32d3f439276d --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSubscriptionManager.h @@ -0,0 +1,58 @@ +/* + * 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 "DeviceSubscription.h" + +#include +#include +#include + +#include + +namespace admin { + +class DeviceSubscriptionManager +{ +public: + static DeviceSubscriptionManager & Instance(); + + /// Usually called after we have added a synchronized device to fabric-bridge to monitor + /// for any changes that need to be propagated to fabric-bridge. + CHIP_ERROR StartSubscription(chip::Controller::DeviceController & controller, chip::ScopedNodeId scopedNodeId); + + CHIP_ERROR RemoveSubscription(chip::ScopedNodeId scopedNodeId); + +private: + struct ScopedNodeIdHasher + { + std::size_t operator()(const chip::ScopedNodeId & scopedNodeId) const + { + std::size_t h1 = std::hash{}(scopedNodeId.GetFabricIndex()); + std::size_t h2 = std::hash{}(scopedNodeId.GetNodeId()); + // Bitshifting h2 reduces collisions when fabricIndex == nodeId. + return h1 ^ (h2 << 1); + } + }; + + void DeviceSubscriptionTerminated(chip::ScopedNodeId scopedNodeId); + + std::unordered_map, ScopedNodeIdHasher> mDeviceSubscriptionMap; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSynchronization.cpp b/examples/fabric-sync/admin/DeviceSynchronization.cpp new file mode 100644 index 00000000000000..05a4fa9db8f398 --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSynchronization.cpp @@ -0,0 +1,323 @@ +/* + * 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 "DeviceSynchronization.h" +#include "DeviceManager.h" +#include "DeviceSubscriptionManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace admin { + +namespace { + +constexpr uint16_t kBasicInformationAttributeBufSize = 128; + +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 + +DeviceSynchronizer & DeviceSynchronizer::Instance() +{ + static DeviceSynchronizer instance; + return instance; +} + +DeviceSynchronizer::DeviceSynchronizer() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + 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: { + char uniqueIdBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(uniqueIdBuffer, sizeof(uniqueIdBuffer)), "UniqueId")) + { + mCurrentDeviceData.uniqueId = std::string(uniqueIdBuffer); + } + } + break; + case Clusters::BasicInformation::Attributes::VendorName::Id: { + char vendorNameBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(vendorNameBuffer, sizeof(vendorNameBuffer)), "VendorName")) + { + mCurrentDeviceData.vendorName = std::string(vendorNameBuffer); + } + } + break; + case Clusters::BasicInformation::Attributes::ProductName::Id: { + char productNameBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(productNameBuffer, sizeof(productNameBuffer)), "ProductName")) + { + mCurrentDeviceData.productName = std::string(productNameBuffer); + } + } + break; + case Clusters::BasicInformation::Attributes::NodeLabel::Id: { + char nodeLabelBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(nodeLabelBuffer, sizeof(nodeLabelBuffer)), "NodeLabel")) + { + mCurrentDeviceData.nodeLabel = std::string(nodeLabelBuffer); + } + } + break; + case Clusters::BasicInformation::Attributes::HardwareVersionString::Id: { + char hardwareVersionStringBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(hardwareVersionStringBuffer, sizeof(hardwareVersionStringBuffer)), + "HardwareVersionString")) + { + mCurrentDeviceData.hardwareVersionString = std::string(hardwareVersionStringBuffer); + } + } + break; + case Clusters::BasicInformation::Attributes::SoftwareVersionString::Id: { + char softwareVersionStringBuffer[kBasicInformationAttributeBufSize]; + if (SuccessOrLog(data->GetString(softwareVersionStringBuffer, sizeof(softwareVersionStringBuffer)), + "SoftwareVersionString")) + { + mCurrentDeviceData.softwareVersionString = std::string(softwareVersionStringBuffer); + } + } + break; + default: + break; + } +} + +void DeviceSynchronizer::OnReportEnd() +{ + // Report end is at the end of all attributes (success) + MoveToState(State::ReceivedResponse); +} + +void DeviceSynchronizer::OnDone(app::ReadClient * apReadClient) +{ + ChipLogProgress(NotSpecified, "Synchronization complete for NodeId:" ChipLogFormatX64, ChipLogValueX64(mNodeId)); + + if (mState == State::ReceivedResponse && !DeviceManager::Instance().IsCurrentBridgeDevice(mNodeId)) + { + GetUniqueId(); + if (mState == State::GettingUid) + { + ChipLogProgress(NotSpecified, + "GetUniqueId was successful and we rely on callback to call SynchronizationCompleteAddDevice."); + return; + } + SynchronizationCompleteAddDevice(); + } + + MoveToState(State::Idle); +} + +void DeviceSynchronizer::OnError(CHIP_ERROR error) +{ + MoveToState(State::ReceivedError); + ChipLogProgress(NotSpecified, "Error fetching device data: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void DeviceSynchronizer::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Read); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(kRootEndpointId, Clusters::BasicInformation::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 read for BasicInformation data"); + MoveToState(State::Idle); + } + MoveToState(State::AwaitingResponse); +} + +void DeviceSynchronizer::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "Device Sync failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + MoveToState(State::Idle); +} + +void DeviceSynchronizer::StartDeviceSynchronization(Controller::DeviceController * controller, NodeId nodeId, bool deviceIsIcd) +{ + VerifyOrDie(controller); + if (mState != State::Idle) + { + ChipLogError(NotSpecified, "Device Sync NOT POSSIBLE: another sync is in progress"); + return; + } + + mNodeId = nodeId; + + ChipLogProgress(NotSpecified, "Start device synchronization for NodeId:" ChipLogFormatX64, ChipLogValueX64(mNodeId)); + + mCurrentDeviceData = SynchronizedDevice_init_default; + mCurrentDeviceData.id = chip::ScopedNodeId(nodeId, controller->GetFabricIndex()); + mCurrentDeviceData.isIcd = deviceIsIcd; + + ReturnOnFailure(controller->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback)); + mController = controller; + MoveToState(State::Connecting); +} + +void DeviceSynchronizer::GetUniqueId() +{ + VerifyOrDie(mState == State::ReceivedResponse); + VerifyOrDie(mController); + + // If we have a UniqueId we can return leaving state in ReceivedResponse. + VerifyOrReturn(!mCurrentDeviceData.uniqueId.has_value(), ChipLogDetail(NotSpecified, "We already have UniqueId")); + + auto * device = DeviceManager::Instance().FindDeviceByNode(mNodeId); + // 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(DeviceManager::Instance().IsFabricSyncReady()); + auto remoteBridgeNodeId = DeviceManager::Instance().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()) + { + // Convert CharSpan to std::string and set it as uniqueId + this->mCurrentDeviceData.uniqueId = std::string(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() +{ + VerifyOrDie(mState == State::ReceivedResponse || mState == State::GettingUid); + ChipLogProgress(NotSpecified, "Synchronization complete and add device"); + + bridge::FabricBridge::Instance().AddSynchronizedDevice(mCurrentDeviceData); + + // TODO(#35077) Figure out how we should reflect CADMIN values of ICD. + if (!mCurrentDeviceData.isIcd) + { + VerifyOrDie(mController); + ScopedNodeId scopedNodeId(mNodeId, mController->GetFabricIndex()); + CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, scopedNodeId); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed start subscription to NodeId:" ChipLogFormatX64, ChipLogValueX64(mNodeId)); + bridge::FabricBridge::Instance().DeviceReachableChanged(mCurrentDeviceData.id, false); + } + } + + 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"; +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/DeviceSynchronization.h b/examples/fabric-sync/admin/DeviceSynchronization.h new file mode 100644 index 00000000000000..1a72a447993b9d --- /dev/null +++ b/examples/fabric-sync/admin/DeviceSynchronization.h @@ -0,0 +1,99 @@ +/* + * 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 "UniqueIdGetter.h" + +#include +#include +#include +#include +#include + +namespace admin { + +/// Ensures that device data is synchronized to the remote fabric bridge. +/// +/// Includes a state machine that: +/// - initiates a "read basic information data" command to fetch basic information +/// - upon receiving such information, ensures that synchronized device data is sent +/// to the remote end. +class DeviceSynchronizer : public chip::app::ReadClient::Callback +{ +public: + DeviceSynchronizer(); + + /// Usually called after commissioning is complete, initiates a + /// read of required data from the remote node ID and then will synchronize + /// the device towards the fabric bridge + /// + /// @param controller Must be a non-null pointer. The DeviceController instance + /// pointed to must out live the entire device synchronization process. + /// @param nodeId Node ID of the device we need to syncronize data from. + /// @param deviceIsIcd If the device is an ICD device. + void StartDeviceSynchronization(chip::Controller::DeviceController * controller, chip::NodeId nodeId, bool deviceIsIcd); + + /////////////////////////////////////////////////////////////// + // 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); + + 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 GetUniqueId(); + 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 + // mState != Idle). + chip::Controller::DeviceController * mController = nullptr; + chip::NodeId mNodeId = chip::kUndefinedNodeId; + bridge::SynchronizedDevice mCurrentDeviceData; + UniqueIdGetter mUniqueIdGetter; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/FabricAdmin.cpp b/examples/fabric-sync/admin/FabricAdmin.cpp new file mode 100644 index 00000000000000..65b5a5a8e8fc30 --- /dev/null +++ b/examples/fabric-sync/admin/FabricAdmin.cpp @@ -0,0 +1,117 @@ +/* + * 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 "FabricAdmin.h" + +using namespace ::chip; + +namespace admin { + +namespace { + +constexpr uint32_t kCommissionPrepareTimeMs = 500; + +} // namespace + +FabricAdmin FabricAdmin::sInstance; + +FabricAdmin & FabricAdmin::Instance() +{ + if (!sInstance.mInitialized) + { + sInstance.Init(); + } + return sInstance; +} + +CHIP_ERROR +FabricAdmin::CommissionRemoteBridge(Controller::CommissioningWindowPasscodeParams params, VendorId vendorId, uint16_t productId) +{ + char saltHex[Crypto::kSpake2p_Max_PBKDF_Salt_Length * 2 + 1]; + Encoding::BytesToHex(params.GetSalt().data(), params.GetSalt().size(), saltHex, sizeof(saltHex), + Encoding::HexFlags::kNullTerminate); + + ChipLogProgress(NotSpecified, "Received CommissionNode request"); + + SetupPayload setupPayload = SetupPayload(); + + setupPayload.setUpPINCode = params.GetSetupPIN(); + setupPayload.version = 0; + setupPayload.vendorID = vendorId; + setupPayload.productID = productId; + setupPayload.rendezvousInformation.SetValue(RendezvousInformationFlag::kOnNetwork); + + SetupDiscriminator discriminator{}; + discriminator.SetLongValue(params.GetDiscriminator()); + setupPayload.discriminator = discriminator; + + QRCodeSetupPayloadGenerator generator(setupPayload); + std::string code; + CHIP_ERROR err = generator.payloadBase38RepresentationWithAutoTLVBuffer(code); + + if (err == CHIP_NO_ERROR) + { + NodeId nodeId = DeviceManager::Instance().GetNextAvailableNodeId(); + + // After responding with RequestCommissioningApproval to the node where the client initiated the + // RequestCommissioningApproval, you need to wait for it to open a commissioning window on its bridge. + usleep(kCommissionPrepareTimeMs * 1000); + + DeviceManager::Instance().PairRemoteDevice(nodeId, code.c_str()); + } + else + { + ChipLogError(NotSpecified, "Unable to generate pairing code for setup payload: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FabricAdmin::KeepActive(ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) +{ + ChipLogProgress(NotSpecified, "Received KeepActive request: Id[%d, 0x" ChipLogFormatX64 "], %u", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId()), stayActiveDurationMs); + + KeepActiveWorkData * data = Platform::New(this, scopedNodeId, stayActiveDurationMs, timeoutMs); + VerifyOrReturnError(data != nullptr, CHIP_ERROR_NO_MEMORY); + + DeviceLayer::PlatformMgr().ScheduleWork(KeepActiveWork, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +void FabricAdmin::ScheduleSendingKeepActiveOnCheckIn(ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) +{ + // Accessing mPendingCheckIn should only be done while holding ChipStackLock + assertChipStackLockedByCurrentThread(); + + auto timeNow = System::SystemClock().GetMonotonicTimestamp(); + System::Clock::Timestamp expiryTimestamp = timeNow + System::Clock::Milliseconds64(timeoutMs); + KeepActiveDataForCheckIn checkInData = { .mStayActiveDurationMs = stayActiveDurationMs, + .mRequestExpiryTimestamp = expiryTimestamp }; + + auto it = mPendingCheckIn.find(scopedNodeId); + if (it != mPendingCheckIn.end()) + { + checkInData.mStayActiveDurationMs = std::max(checkInData.mStayActiveDurationMs, it->second.mStayActiveDurationMs); + checkInData.mRequestExpiryTimestamp = std::max(checkInData.mRequestExpiryTimestamp, it->second.mRequestExpiryTimestamp); + } + + mPendingCheckIn[scopedNodeId] = checkInData; +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/FabricAdmin.h b/examples/fabric-sync/admin/FabricAdmin.h new file mode 100644 index 00000000000000..1219e594fa8c5f --- /dev/null +++ b/examples/fabric-sync/admin/FabricAdmin.h @@ -0,0 +1,93 @@ +/* + * 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 "DeviceManager.h" + +#include +#include +#include +#include + +namespace admin { + +struct ScopedNodeIdHasher +{ + std::size_t operator()(const chip::ScopedNodeId & scopedNodeId) const + { + std::size_t h1 = std::hash{}(scopedNodeId.GetFabricIndex()); + std::size_t h2 = std::hash{}(scopedNodeId.GetNodeId()); + // Bitshifting h2 reduces collisions when fabricIndex == nodeId. + return h1 ^ (h2 << 1); + } +}; + +class FabricAdmin final : public bridge::FabricAdminDelegate +{ +public: + static FabricAdmin & Instance(); + + CHIP_ERROR + CommissionRemoteBridge(chip::Controller::CommissioningWindowPasscodeParams params, chip::VendorId vendorId, + uint16_t productId) override; + + CHIP_ERROR KeepActive(chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) override; + + void ScheduleSendingKeepActiveOnCheckIn(chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs); + +private: + struct KeepActiveDataForCheckIn + { + uint32_t mStayActiveDurationMs = 0; + chip::System::Clock::Timestamp mRequestExpiryTimestamp; + }; + + struct KeepActiveWorkData + { + KeepActiveWorkData(FabricAdmin * fabricAdmin, chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, + uint32_t timeoutMs) : + mFabricAdmin(fabricAdmin), + mScopedNodeId(scopedNodeId), mStayActiveDurationMs(stayActiveDurationMs), mTimeoutMs(timeoutMs) + {} + + FabricAdmin * mFabricAdmin; + chip::ScopedNodeId mScopedNodeId; + uint32_t mStayActiveDurationMs; + uint32_t mTimeoutMs; + }; + + static void KeepActiveWork(intptr_t arg) + { + KeepActiveWorkData * data = reinterpret_cast(arg); + data->mFabricAdmin->ScheduleSendingKeepActiveOnCheckIn(data->mScopedNodeId, data->mStayActiveDurationMs, data->mTimeoutMs); + chip::Platform::Delete(data); + } + + // Modifications to mPendingCheckIn should be done on the MatterEventLoop thread + // otherwise we would need a mutex protecting this data to prevent race as this + // data is accessible by both RPC thread and Matter eventloop. + std::unordered_map mPendingCheckIn; + + static FabricAdmin sInstance; + + bool mInitialized = false; + + void Init() { mInitialized = true; } +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/FabricSyncGetter.cpp b/examples/fabric-sync/admin/FabricSyncGetter.cpp new file mode 100644 index 00000000000000..7e5118090716c0 --- /dev/null +++ b/examples/fabric-sync/admin/FabricSyncGetter.cpp @@ -0,0 +1,125 @@ +/* + * 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 "FabricSyncGetter.h" + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace admin { + +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); +} + +} // namespace + +FabricSyncGetter::FabricSyncGetter() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR FabricSyncGetter::GetFabricSynchronizationData(OnDoneCallback onDoneCallback, Controller::DeviceController & controller, + NodeId nodeId, EndpointId endpointId) +{ + assertChipStackLockedByCurrentThread(); + + mEndpointId = endpointId; + mOnDoneCallback = onDoneCallback; + + CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to connect to remote fabric bridge %" CHIP_ERROR_FORMAT, err.Format()); + } + return err; +} + +void FabricSyncGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + VerifyOrDie(path.mClusterId == Clusters::CommissionerControl::Id); + + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + + switch (path.mAttributeId) + { + case Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id: { + mOnDoneCallback(*data); + break; + } + default: + break; + } +} + +void FabricSyncGetter::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error Getting SupportedDeviceCategories: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void FabricSyncGetter::OnDone(ReadClient * apReadClient) +{ + ChipLogProgress(NotSpecified, "Reading SupportedDeviceCategories is done."); +} + +void FabricSyncGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr, *this /* callback */, + ReadClient::InteractionType::Read); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(mEndpointId, Clusters::CommissionerControl::Id, + Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::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 read SupportedDeviceCategories from the bridged device."); + OnDone(nullptr); + return; + } +} + +void FabricSyncGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "FabricSyncGetter failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + + OnDone(nullptr); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/FabricSyncGetter.h b/examples/fabric-sync/admin/FabricSyncGetter.h new file mode 100644 index 00000000000000..bed3c2fbb54385 --- /dev/null +++ b/examples/fabric-sync/admin/FabricSyncGetter.h @@ -0,0 +1,79 @@ +/* + * 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 admin { + +/** + * @brief Class used to get FabricSynchronization from SupportedDeviceCategories attribute of Commissioner Control Cluster. + * + * Functionality: + * - Establishes a CASE session to communicate with the remote bridge. + * - Retrieves the attribute data from the endpoint which host Aggregator. + * - Provides callbacks for success, error, and completion when retrieving data. + */ +class FabricSyncGetter : public chip::app::ReadClient::Callback +{ +public: + using OnDoneCallback = std::function; + + FabricSyncGetter(); + + /** + * @brief Initiates the process of retrieving fabric synchronization data from the target device. + * + * @param onDoneCallback A callback function to be invoked when the data retrieval is complete. + * @param controller The device controller used to establish a session with the target device. + * @param nodeId The Node ID of the target device. + * @param endpointId The Endpoint ID from which to retrieve the fabric synchronization data. + * @return CHIP_ERROR Returns an error if the process fails, CHIP_NO_ERROR on success. + */ + CHIP_ERROR GetFabricSynchronizationData(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 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::EndpointId mEndpointId; + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; +}; + +} // namespace admin diff --git a/examples/fabric-sync/admin/PairingManager.cpp b/examples/fabric-sync/admin/PairingManager.cpp index a3f4af43dafd84..ba360051a27b84 100644 --- a/examples/fabric-sync/admin/PairingManager.cpp +++ b/examples/fabric-sync/admin/PairingManager.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -17,6 +16,8 @@ */ #include "PairingManager.h" +#include "DeviceManager.h" +#include "DeviceSynchronization.h" #include #include @@ -284,6 +285,10 @@ void PairingManager::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { // print to console fprintf(stderr, "New device with Node ID: " ChipLogFormatX64 " has been successfully added.\n", ChipLogValueX64(nodeId)); + + // mCommissioner has a lifetime that is the entire life of the application itself + // so it is safe to provide to StartDeviceSynchronization. + DeviceSynchronizer::Instance().StartDeviceSynchronization(mCommissioner, nodeId, false); } else { diff --git a/examples/fabric-sync/admin/PairingManager.h b/examples/fabric-sync/admin/PairingManager.h index b9b404ee76bbfd..9d109911e195df 100644 --- a/examples/fabric-sync/admin/PairingManager.h +++ b/examples/fabric-sync/admin/PairingManager.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * diff --git a/examples/fabric-sync/admin/UniqueIdGetter.cpp b/examples/fabric-sync/admin/UniqueIdGetter.cpp new file mode 100644 index 00000000000000..cc3567deda6bd2 --- /dev/null +++ b/examples/fabric-sync/admin/UniqueIdGetter.cpp @@ -0,0 +1,145 @@ +/* + * 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 "UniqueIdGetter.h" + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace admin { + +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 + +UniqueIdGetter::UniqueIdGetter() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR UniqueIdGetter::GetUniqueId(OnDoneCallback onDoneCallback, Controller::DeviceController & controller, NodeId nodeId, + 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 UniqueIdGetter::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 UniqueIdGetter::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error Getting UID: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void UniqueIdGetter::OnDone(ReadClient * apReadClient) +{ + mCurrentlyGettingUid = false; + mOnDoneCallback(mUniqueIdHasValue ? std::make_optional(mUniqueId) : std::nullopt); +} + +void UniqueIdGetter::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 read unique ID from the bridged device."); + OnDone(nullptr); + return; + } +} + +void UniqueIdGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + VerifyOrDie(mCurrentlyGettingUid); + ChipLogError(NotSpecified, "UniqueIdGetter failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + + OnDone(nullptr); +} + +} // namespace admin diff --git a/examples/fabric-sync/admin/UniqueIdGetter.h b/examples/fabric-sync/admin/UniqueIdGetter.h new file mode 100644 index 00000000000000..eba4451599c3ee --- /dev/null +++ b/examples/fabric-sync/admin/UniqueIdGetter.h @@ -0,0 +1,79 @@ +/* + * 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 admin { + +/** + * @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)>; + + UniqueIdGetter(); + + CHIP_ERROR GetUniqueId(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 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; +}; + +} // namespace admin diff --git a/examples/fabric-sync/bridge/BUILD.gn b/examples/fabric-sync/bridge/BUILD.gn index 310496bc54d06a..8fb79b89f2ea3b 100644 --- a/examples/fabric-sync/bridge/BUILD.gn +++ b/examples/fabric-sync/bridge/BUILD.gn @@ -17,7 +17,11 @@ import("${chip_root}/src/app/chip_data_model.gni") import("${chip_root}/src/lib/lib.gni") config("config") { - include_dirs = [ "include" ] + include_dirs = [ + ".", + "${chip_root}/examples/common", + "${chip_root}/examples/platform/linux", + ] } chip_data_model("fabric-bridge-zap") { @@ -41,15 +45,22 @@ source_set("fabric-bridge-lib") { public_configs = [ ":config" ] sources = [ + "include/Bridge.h", "include/BridgedAdministratorCommissioning.h", "include/BridgedDevice.h", "include/BridgedDeviceBasicInformationImpl.h", "include/BridgedDeviceManager.h", "include/CHIPProjectAppConfig.h", + "include/CommissionerControlDelegate.h", + "include/FabricAdminDelegate.h", + "include/FabricBridge.h", + "src/Bridge.cpp", "src/BridgedAdministratorCommissioning.cpp", "src/BridgedDevice.cpp", "src/BridgedDeviceBasicInformationImpl.cpp", "src/BridgedDeviceManager.cpp", + "src/CommissionerControlDelegate.cpp", + "src/FabricBridge.cpp", ] deps = [ diff --git a/examples/fabric-sync/bridge/include/Bridge.h b/examples/fabric-sync/bridge/include/Bridge.h new file mode 100644 index 00000000000000..d6ff91ededc4ec --- /dev/null +++ b/examples/fabric-sync/bridge/include/Bridge.h @@ -0,0 +1,54 @@ +/* + * 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 "CommissionableInit.h" +#include "CommissionerControlDelegate.h" +#include "FabricAdminDelegate.h" + +namespace bridge { + +/** + * @brief Initializes the local fabric bridge system. + * + * This function sets up and initializes all necessary components required for + * device management and commissioning within the local fabric bridge. It interacts + * with the provided FabricAdminDelegate instance to manage fabric-level operations. + * Specifically, it registers command handlers, initializes device attributes, and + * prepares the bridge for commissioning operations. + * + * @param delegate A pointer to a FabricAdminDelegate instance, allowing the bridge + * to initialize and manage fabric operations. + * + * @return CHIP_NO_ERROR if all initializations are successful, or an appropriate + * CHIP_ERROR code if an initialization step fails. + */ +CHIP_ERROR BridgeInit(FabricAdminDelegate * delegate); + +/** + * @brief Shuts down the local fabric bridge system. + * + * This function performs cleanup operations and shuts down the bridge system components + * responsible for device management and commissioning. It stops the Commissioner Control + * Server and handles any errors that may occur during shutdown. + * + * @return CHIP_NO_ERROR if shutdown is successful, or an appropriate CHIP_ERROR code if any component fails to shut down. + */ +CHIP_ERROR BridgeShutdown(); + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/include/BridgedDevice.h b/examples/fabric-sync/bridge/include/BridgedDevice.h index ed5c9710624225..903d853ec8dce2 100644 --- a/examples/fabric-sync/bridge/include/BridgedDevice.h +++ b/examples/fabric-sync/bridge/include/BridgedDevice.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * diff --git a/examples/fabric-sync/bridge/include/BridgedDeviceManager.h b/examples/fabric-sync/bridge/include/BridgedDeviceManager.h index 6d172767662a69..67efe74addb038 100644 --- a/examples/fabric-sync/bridge/include/BridgedDeviceManager.h +++ b/examples/fabric-sync/bridge/include/BridgedDeviceManager.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -31,6 +30,12 @@ class BridgedDeviceManager public: BridgedDeviceManager() = default; + static BridgedDeviceManager & Instance() + { + static BridgedDeviceManager instance; + return instance; + } + /** * @brief Initializes the BridgedDeviceManager. * @@ -112,29 +117,14 @@ class BridgedDeviceManager BridgedDevice * GetDeviceByUniqueId(const std::string & id); private: - friend BridgedDeviceManager & BridgeDeviceMgr(); - /** * Creates a new unique ID that is not used by any other mDevice */ std::string GenerateUniqueId(); - static BridgedDeviceManager sInstance; - chip::EndpointId mCurrentEndpointId; chip::EndpointId mFirstDynamicEndpointId; std::unique_ptr mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; }; -/** - * Returns the public interface of the BridgedDeviceManager singleton object. - * - * Applications should use this to access features of the BridgedDeviceManager - * object. - */ -inline BridgedDeviceManager & BridgeDeviceMgr() -{ - return BridgedDeviceManager::sInstance; -} - } // namespace bridge diff --git a/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h index 58f45c03052b17..ff6052169b488d 100644 --- a/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h +++ b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * diff --git a/examples/fabric-sync/bridge/include/CommissionerControlDelegate.h b/examples/fabric-sync/bridge/include/CommissionerControlDelegate.h new file mode 100644 index 00000000000000..45a927307bb9a7 --- /dev/null +++ b/examples/fabric-sync/bridge/include/CommissionerControlDelegate.h @@ -0,0 +1,102 @@ +/* + * 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 "FabricAdminDelegate.h" + +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace CommissionerControl { + +inline constexpr EndpointId kAggregatorEndpointId = 1; + +class CommissionerControlDelegate : public Delegate +{ +public: + CommissionerControlDelegate(bridge::FabricAdminDelegate * fabricAdmin) : mFabricAdmin(fabricAdmin) {} + + CHIP_ERROR HandleCommissioningApprovalRequest(const CommissioningApprovalRequest & request) override; + // TODO(#35627) clientNodeId should move towards ScopedNodeId. + CHIP_ERROR ValidateCommissionNodeCommand(NodeId clientNodeId, uint64_t requestId) override; + CHIP_ERROR GetCommissioningWindowParams(CommissioningWindowParams & outParams) override; + CHIP_ERROR HandleCommissionNode(const CommissioningWindowParams & params) override; + + ~CommissionerControlDelegate() = default; + +private: + enum class Step : uint8_t + { + // Ready to start reverse commissioning. + kIdle, + // Wait for the commission node command. + kWaitCommissionNodeRequest, + // Need to commission node. + kStartCommissionNode, + }; + + static const char * GetStateString(Step step) + { + switch (step) + { + case Step::kIdle: + return "kIdle"; + case Step::kWaitCommissionNodeRequest: + return "kWaitCommissionNodeRequest"; + case Step::kStartCommissionNode: + return "kStartCommissionNode"; + default: + return "Unknown"; + } + } + + void ResetDelegateState(); + + static constexpr size_t kLabelBufferSize = 64; + + Step mNextStep = Step::kIdle; + uint64_t mRequestId = 0; + NodeId mClientNodeId = kUndefinedNodeId; + VendorId mVendorId = VendorId::Unspecified; + uint16_t mProductId = 0; + char mLabelBuffer[kLabelBufferSize + 1]; + Optional mLabel; + + // Parameters needed for non-basic commissioning. + uint8_t mPBKDFSaltBuffer[Crypto::kSpake2p_Max_PBKDF_Salt_Length]; + ByteSpan mPBKDFSalt; + Crypto::Spake2pVerifierSerialized mPAKEPasscodeVerifierBuffer; + ByteSpan mPAKEPasscodeVerifier; + + bridge::FabricAdminDelegate * mFabricAdmin; +}; + +} // namespace CommissionerControl +} // namespace Clusters +} // namespace app +} // namespace chip + +namespace bridge { + +CHIP_ERROR CommissionerControlInit(bridge::FabricAdminDelegate * fabricAdmin); +CHIP_ERROR CommissionerControlShutdown(); + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/include/FabricAdminDelegate.h b/examples/fabric-sync/bridge/include/FabricAdminDelegate.h new file mode 100644 index 00000000000000..8b67ffd5b29ed7 --- /dev/null +++ b/examples/fabric-sync/bridge/include/FabricAdminDelegate.h @@ -0,0 +1,55 @@ +/* + * 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 +#include + +namespace bridge { + +class FabricAdminDelegate +{ +public: + virtual ~FabricAdminDelegate() = default; + + /** + * Reverse commission a bridge using the specified parameters. + * + * This function initiates the commissioning process for a bridge node, utilizing + * the provided passcode parameters, vendor ID, and product ID. + * + * @param params Parameters required for commissioning the device using passcode. + * @param vendorId The Vendor ID (VID) of the device being commissioned. This identifies + * the manufacturer of the device. + * @param productId The Product ID (PID) of the device being commissioned. This identifies + * the specific product within the vendor's lineup. + * + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully sent and the commissioning process was initiated. + * - CHIP_ERROR_INTERNAL: An internal error occurred during the preparation or sending of the command. + */ + virtual CHIP_ERROR CommissionRemoteBridge(chip::Controller::CommissioningWindowPasscodeParams params, chip::VendorId vendorId, + uint16_t productId) = 0; + + virtual CHIP_ERROR KeepActive(chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) = 0; +}; + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/include/FabricBridge.h b/examples/fabric-sync/bridge/include/FabricBridge.h new file mode 100644 index 00000000000000..48a3ddae4fc0c2 --- /dev/null +++ b/examples/fabric-sync/bridge/include/FabricBridge.h @@ -0,0 +1,161 @@ +/* + * 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 "FabricAdminDelegate.h" + +#include +#include +#include +#include +#include + +namespace bridge { + +#define ScopedNodeId_init_default chip::ScopedNodeId() +#define SynchronizedDevice_init_default \ + { \ + ScopedNodeId_init_default, /* id */ \ + std::nullopt, /* uniqueId */ \ + std::nullopt, /* vendorName */ \ + std::nullopt, /* vendorId */ \ + std::nullopt, /* productName */ \ + std::nullopt, /* productId */ \ + std::nullopt, /* nodeLabel */ \ + std::nullopt, /* hardwareVersion */ \ + std::nullopt, /* hardwareVersionString */ \ + std::nullopt, /* softwareVersion */ \ + std::nullopt, /* softwareVersionString */ \ + std::nullopt /* isIcd */ \ + } + +#define AdministratorCommissioningChanged_init_default \ + { \ + ScopedNodeId_init_default, /* id */ \ + chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen, /* windowStatus */ \ + std::nullopt, /* openerFabricIndex */ \ + std::nullopt /* openerVendorId */ \ + } + +struct SynchronizedDevice +{ + chip::ScopedNodeId id; + + std::optional uniqueId; + std::optional vendorName; + std::optional vendorId; + std::optional productName; + std::optional productId; + std::optional nodeLabel; + std::optional hardwareVersion; + std::optional hardwareVersionString; + std::optional softwareVersion; + std::optional softwareVersionString; + std::optional isIcd; +}; + +struct AdministratorCommissioningChanged +{ + chip::ScopedNodeId id; + chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum windowStatus; + std::optional openerFabricIndex; + std::optional openerVendorId; +}; + +class FabricBridge final +{ +public: + static FabricBridge & Instance(); + + void SetDelegate(FabricAdminDelegate * delegate) { mFabricAdmin = delegate; } + FabricAdminDelegate * GetDelegate() { return mFabricAdmin; } + + /** + * @brief Adds a synchronized device to the RPC client. + * + * This function attempts to add a device identified by its `nodeId` to the synchronized device list. + * It logs the progress and checks if an `AddSynchronizedDevice` operation is already in progress. + * If an operation is in progress, it returns `CHIP_ERROR_BUSY`. + * + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully processed. + * - CHIP_ERROR_BUSY: Another operation is currently in progress. + * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. + */ + CHIP_ERROR AddSynchronizedDevice(const SynchronizedDevice & data); + + /** + * @brief Removes a synchronized device from the RPC client. + * + * This function attempts to remove a device identified by its `nodeId` from the synchronized device list. + * It logs the progress and checks if a `RemoveSynchronizedDevice` operation is already in progress. + * If an operation is in progress, it returns `CHIP_ERROR_BUSY`. + * + * @param scopedNodeId The Scoped Node ID of the device to be removed. + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully processed. + * - CHIP_ERROR_BUSY: Another operation is currently in progress. + * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. + */ + CHIP_ERROR RemoveSynchronizedDevice(chip::ScopedNodeId scopedNodeId); + + /** + * @brief Received StayActiveResponse on behalf of client that previously called KeepActive + * + * @param scopedNodeId The Scoped Node ID of the device we recieved a StayActiveResponse. + * @param promisedActiveDurationMs the computed duration (in milliseconds) that the ICD intends to stay active for. + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully processed. + * - CHIP_ERROR_BUSY: Another operation is currently in progress. + * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. + */ + CHIP_ERROR ActiveChanged(chip::ScopedNodeId scopedNodeId, uint32_t promisedActiveDurationMs); + + /** + * @brief CADMIN attribute has changed of one of the bridged devices that was previously added. + * + * @param data information regarding change in AdministratorCommissioning attributes + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully processed. + * - CHIP_ERROR_BUSY: Another operation is currently in progress. + * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. + */ + CHIP_ERROR AdminCommissioningAttributeChanged(const AdministratorCommissioningChanged & data); + + /** + * @brief Notify the system that the reachability status of a bridged device has changed. + * + * @param scopedNodeId Identifier of the bridged device whose reachability has changed. + * @param reachability Boolean indicating the new reachability status of the device. + * - `true`: Device is reachable. + * - `false`: Device is not reachable. + * + * @return CHIP_ERROR Error code representing the outcome of the operation. + * - CHIP_NO_ERROR: The operation was successful. + * - CHIP_ERROR_BUSY: Another operation is currently in progress, preventing this action. + * - CHIP_ERROR_INTERNAL: An internal error occurred while processing the reachability change. + */ + CHIP_ERROR DeviceReachableChanged(chip::ScopedNodeId scopedNodeId, bool reachability); + +private: + static FabricBridge sInstance; + + FabricAdminDelegate * mFabricAdmin; +}; + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/src/Bridge.cpp b/examples/fabric-sync/bridge/src/Bridge.cpp new file mode 100644 index 00000000000000..3d0a4af56ff064 --- /dev/null +++ b/examples/fabric-sync/bridge/src/Bridge.cpp @@ -0,0 +1,147 @@ +/* + * 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 "Bridge.h" + +#include "BridgedAdministratorCommissioning.h" +#include "BridgedDevice.h" +#include "BridgedDeviceBasicInformationImpl.h" +#include "BridgedDeviceManager.h" +#include "FabricBridge.h" + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::AdministratorCommissioning; +using namespace chip::app::Clusters::BridgedDeviceBasicInformation; + +// This is declared here and not in a header because zap/embr assumes all clusters +// are defined in a static endpoint in the .zap file. From there, the codegen will +// automatically use PluginApplicationCallbacksHeader.jinja to declare and call +// the respective Init callbacks. However, because EcosystemInformation cluster is only +// ever on a dynamic endpoint, this doesn't get declared and called for us, so we +// need to declare and call it ourselves where the application is initialized. +void MatterEcosystemInformationPluginServerInitCallback(); + +namespace bridge { + +namespace { + +class BridgedDeviceInformationCommandHandler : public CommandHandlerInterface +{ +public: + // Register for the BridgedDeviceBasicInformation cluster on all endpoints. + BridgedDeviceInformationCommandHandler() : + CommandHandlerInterface(Optional::Missing(), BridgedDeviceBasicInformation::Id) + {} + + void InvokeCommand(HandlerContext & handlerContext) override; +}; + +void BridgedDeviceInformationCommandHandler::InvokeCommand(HandlerContext & handlerContext) +{ + using Protocols::InteractionModel::Status; + VerifyOrReturn(handlerContext.mRequestPath.mCommandId == BridgedDeviceBasicInformation::Commands::KeepActive::Id); + + EndpointId endpointId = handlerContext.mRequestPath.mEndpointId; + ChipLogProgress(NotSpecified, "Received command to KeepActive on Endpoint: %d", endpointId); + + handlerContext.SetCommandHandled(); + + BridgedDeviceBasicInformation::Commands::KeepActive::DecodableType commandData; + if (DataModel::Decode(handlerContext.mPayload, commandData) != CHIP_NO_ERROR) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::InvalidCommand); + return; + } + + const uint32_t kMinTimeoutMs = 30 * 1000; + const uint32_t kMaxTimeoutMs = 60 * 60 * 1000; + if (commandData.timeoutMs < kMinTimeoutMs || commandData.timeoutMs > kMaxTimeoutMs) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::ConstraintError); + return; + } + + BridgedDevice * device = BridgedDeviceManager::Instance().GetDevice(endpointId); + if (device == nullptr || !device->IsIcd()) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::Failure); + return; + } + + Status status = Status::Failure; + FabricAdminDelegate * adminDelegate = FabricBridge::Instance().GetDelegate(); + + if (adminDelegate) + { + CHIP_ERROR err = + adminDelegate->KeepActive(device->GetScopedNodeId(), commandData.stayActiveDuration, commandData.timeoutMs); + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "KeepActive successfully processed"); + status = Status::Success; + } + else + { + ChipLogProgress(NotSpecified, "KeepActive failed to process: %s", ErrorStr(err)); + } + } + else + { + ChipLogProgress(NotSpecified, "Operation failed: adminDelegate is null"); + } + + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, status); +} + +BridgedAdministratorCommissioning gBridgedAdministratorCommissioning; +BridgedDeviceBasicInformationImpl gBridgedDeviceBasicInformationAttributes; +BridgedDeviceInformationCommandHandler gBridgedDeviceInformationCommandHandler; + +} // namespace + +CHIP_ERROR BridgeInit(FabricAdminDelegate * delegate) +{ + MatterEcosystemInformationPluginServerInitCallback(); + CommandHandlerInterfaceRegistry::Instance().RegisterCommandHandler(&gBridgedDeviceInformationCommandHandler); + AttributeAccessInterfaceRegistry::Instance().Register(&gBridgedDeviceBasicInformationAttributes); + + BridgedDeviceManager::Instance().Init(); + FabricBridge::Instance().SetDelegate(delegate); + ReturnErrorOnFailure(gBridgedAdministratorCommissioning.Init()); + ReturnErrorOnFailure(CommissionerControlInit(delegate)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BridgeShutdown() +{ + CHIP_ERROR err = CommissionerControlShutdown(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to shutdown Commissioner Control Server"); + } + + return err; +} + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp b/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp index 3299df75a9039e..6cfb5a5caaedd7 100644 --- a/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp +++ b/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp @@ -45,7 +45,7 @@ CHIP_ERROR BridgedAdministratorCommissioning::Read(const ConcreteReadAttributePa { VerifyOrDie(aPath.mClusterId == Clusters::AdministratorCommissioning::Id); EndpointId endpointId = aPath.mEndpointId; - BridgedDevice * device = BridgeDeviceMgr().GetDevice(endpointId); + BridgedDevice * device = BridgedDeviceManager::Instance().GetDevice(endpointId); if (!device) { diff --git a/examples/fabric-sync/bridge/src/BridgedDevice.cpp b/examples/fabric-sync/bridge/src/BridgedDevice.cpp index bd88c89145930e..1368f19bdadf05 100644 --- a/examples/fabric-sync/bridge/src/BridgedDevice.cpp +++ b/examples/fabric-sync/bridge/src/BridgedDevice.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * diff --git a/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp index d021671c8bf1bd..3a03d8f84a81a0 100644 --- a/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp +++ b/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp @@ -36,7 +36,7 @@ CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePa // Registration is done for the bridged device basic information only VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); - BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + BridgedDevice * dev = BridgedDeviceManager::Instance().GetDevice(path.mEndpointId); VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); switch (path.mAttributeId) @@ -93,7 +93,7 @@ CHIP_ERROR BridgedDeviceBasicInformationImpl::Write(const ConcreteDataAttributeP { VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); - BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + BridgedDevice * dev = BridgedDeviceManager::Instance().GetDevice(path.mEndpointId); VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); if (!dev->IsReachable()) diff --git a/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp b/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp index 09c1b643c00efb..0ead453572aa4f 100644 --- a/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp +++ b/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -176,9 +175,6 @@ const EmberAfDeviceType sBridgedDeviceTypes[] = { { DEVICE_TYPE_BRIDGED_NODE, DE } // namespace -// Define the static member -BridgedDeviceManager BridgedDeviceManager::sInstance; - void BridgedDeviceManager::Init() { mFirstDynamicEndpointId = static_cast( diff --git a/examples/fabric-sync/bridge/src/CommissionerControlDelegate.cpp b/examples/fabric-sync/bridge/src/CommissionerControlDelegate.cpp new file mode 100644 index 00000000000000..12851177bcb212 --- /dev/null +++ b/examples/fabric-sync/bridge/src/CommissionerControlDelegate.cpp @@ -0,0 +1,267 @@ +/* + * 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 "CommissionerControlDelegate.h" + +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; + +namespace { + +// Constants +constexpr uint16_t kDiscriminator = 3840; +constexpr uint16_t kWindowTimeout = 300; +constexpr uint16_t kIteration = 1000; +constexpr uint32_t kSetupPinCode = 20202021; + +std::unique_ptr sCommissionerControlDelegate; + +} // namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace CommissionerControl { + +void CommissionerControlDelegate::ResetDelegateState() +{ + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Resetting delegate state"); + + // Reset the step to the initial state + mNextStep = Step::kIdle; + + // Reset identifiers and product information + mRequestId = 0; + mClientNodeId = kUndefinedNodeId; + mVendorId = VendorId::Unspecified; + mProductId = 0; + + // Clear the label buffer and optional label + memset(mLabelBuffer, 0, sizeof(mLabelBuffer)); + mLabel.ClearValue(); + + // Reset PBKDF salt and PAKE passcode verifier buffers + mPBKDFSalt = ByteSpan(); + memset(mPBKDFSaltBuffer, 0, sizeof(mPBKDFSaltBuffer)); + + mPAKEPasscodeVerifier = ByteSpan(); + memset(mPAKEPasscodeVerifierBuffer, 0, sizeof(mPAKEPasscodeVerifierBuffer)); +} + +CHIP_ERROR CommissionerControlDelegate::HandleCommissioningApprovalRequest(const CommissioningApprovalRequest & request) +{ + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering HandleCommissioningApprovalRequest, current state: %s", + GetStateString(mNextStep)); + + VerifyOrReturnError(mNextStep == Step::kIdle, CHIP_ERROR_INCORRECT_STATE); + + CommissionerControl::Events::CommissioningRequestResult::Type result; + result.requestID = request.requestId; + result.clientNodeID = request.clientNodeId; + result.fabricIndex = request.fabricIndex; + result.statusCode = static_cast(Protocols::InteractionModel::Status::Success); + + mRequestId = request.requestId; + mClientNodeId = request.clientNodeId; + mVendorId = request.vendorId; + mProductId = request.productId; + + if (request.label.HasValue()) + { + const CharSpan & labelSpan = request.label.Value(); + size_t labelLength = labelSpan.size(); + + if (labelLength >= kLabelBufferSize) + { + ChipLogError(Zcl, "Label too long to fit in buffer"); + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + if (labelLength == 0) + { + mLabel.ClearValue(); + } + else + { + memcpy(mLabelBuffer, labelSpan.data(), labelLength); + mLabelBuffer[labelLength] = '\0'; // Null-terminate the copied string + mLabel.SetValue(CharSpan(mLabelBuffer, labelLength)); + } + } + else + { + mLabel.ClearValue(); + } + + CHIP_ERROR err = CommissionerControlServer::Instance().GenerateCommissioningRequestResultEvent(kAggregatorEndpointId, result); + + if (err == CHIP_NO_ERROR) + { + mNextStep = Step::kWaitCommissionNodeRequest; + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: State transitioned to %s", GetStateString(mNextStep)); + } + else + { + ResetDelegateState(); + } + + return err; +} + +CHIP_ERROR CommissionerControlDelegate::ValidateCommissionNodeCommand(NodeId clientNodeId, uint64_t requestId) +{ + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering ValidateCommissionNodeCommand, current state: %s", + GetStateString(mNextStep)); + + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(mNextStep == Step::kWaitCommissionNodeRequest, CHIP_ERROR_INCORRECT_STATE); + + // Verify if the CommissionNode command is sent from the same NodeId as the RequestCommissioningApproval. + VerifyOrExit(mClientNodeId == clientNodeId, err = CHIP_ERROR_WRONG_NODE_ID); + + // Verify if the provided RequestId matches the value provided to the RequestCommissioningApproval. + VerifyOrExit(mRequestId == requestId, err = CHIP_ERROR_INCORRECT_STATE); + + mNextStep = Step::kStartCommissionNode; + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: State transitioned to %s", GetStateString(mNextStep)); + +exit: + return err; +} + +CHIP_ERROR CommissionerControlDelegate::GetCommissioningWindowParams(CommissioningWindowParams & outParams) +{ + // Populate outParams with the required details. + outParams.iterations = kIteration; + outParams.commissioningTimeout = kWindowTimeout; + outParams.discriminator = kDiscriminator; + + ReturnErrorOnFailure(Crypto::DRBG_get_bytes(mPBKDFSaltBuffer, sizeof(mPBKDFSaltBuffer))); + mPBKDFSalt = ByteSpan(mPBKDFSaltBuffer); + outParams.salt = mPBKDFSalt; + + Crypto::Spake2pVerifier verifier; + uint32_t setupPIN = kSetupPinCode; + ReturnErrorOnFailure(PASESession::GeneratePASEVerifier(verifier, kIteration, mPBKDFSalt, false, setupPIN)); + + MutableByteSpan serializedVerifierSpan(mPAKEPasscodeVerifierBuffer); + ReturnErrorOnFailure(verifier.Serialize(serializedVerifierSpan)); + mPAKEPasscodeVerifier = serializedVerifierSpan; + outParams.PAKEPasscodeVerifier = mPAKEPasscodeVerifier; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionerControlDelegate::HandleCommissionNode(const CommissioningWindowParams & params) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering HandleCommissionNode, current state: %s", + GetStateString(mNextStep)); + + VerifyOrReturnError(mNextStep == Step::kStartCommissionNode, CHIP_ERROR_INCORRECT_STATE); + + // Attempt to reverse commission the bridge using provided commissioning parameters. + err = mFabricAdmin->CommissionRemoteBridge(Controller::CommissioningWindowPasscodeParams() + .SetSetupPIN(kSetupPinCode) + .SetTimeout(params.commissioningTimeout) + .SetDiscriminator(params.discriminator) + .SetIteration(params.iterations) + .SetSalt(params.salt), + mVendorId, mProductId); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to reverse commission the fabric bridge. Error: %" CHIP_ERROR_FORMAT, err.Format()); + } + + // Reset the delegate's state to prepare for a new commissioning sequence. + ResetDelegateState(); + + return err; +} + +} // namespace CommissionerControl +} // namespace Clusters +} // namespace app +} // namespace chip + +namespace bridge { + +CHIP_ERROR CommissionerControlInit(bridge::FabricAdminDelegate * fabricAdmin) +{ + CHIP_ERROR err; + + if (sCommissionerControlDelegate) + { + ChipLogError(NotSpecified, "Commissioner Control Delegate already exists."); + return CHIP_ERROR_INCORRECT_STATE; + } + + sCommissionerControlDelegate = std::make_unique(fabricAdmin); + if (!sCommissionerControlDelegate) + { + ChipLogError(NotSpecified, "Failed to allocate memory for Commissioner Control Delegate."); + return CHIP_ERROR_NO_MEMORY; + } + + err = Clusters::CommissionerControl::CommissionerControlServer::Instance().Init(*sCommissionerControlDelegate); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Initialization failed on Commissioner Control Delegate."); + sCommissionerControlDelegate.reset(); + return err; + } + + ChipLogProgress(Zcl, "Initializing SupportedDeviceCategories of Commissioner Control Cluster for this device."); + + BitMask supportedDeviceCategories; + supportedDeviceCategories.SetField(Clusters::CommissionerControl::SupportedDeviceCategoryBitmap::kFabricSynchronization, 1); + + Protocols::InteractionModel::Status status = + Clusters::CommissionerControl::CommissionerControlServer::Instance().SetSupportedDeviceCategoriesValue( + Clusters::CommissionerControl::kAggregatorEndpointId, supportedDeviceCategories); + + if (status != Protocols::InteractionModel::Status::Success) + { + ChipLogError(NotSpecified, "Failed to set SupportedDeviceCategories: %d", static_cast(status)); + sCommissionerControlDelegate.reset(); + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionerControlShutdown() +{ + if (sCommissionerControlDelegate) + { + sCommissionerControlDelegate.reset(); + } + + return CHIP_NO_ERROR; +} + +} // namespace bridge diff --git a/examples/fabric-sync/bridge/src/FabricBridge.cpp b/examples/fabric-sync/bridge/src/FabricBridge.cpp new file mode 100644 index 00000000000000..aa856ccf129ccc --- /dev/null +++ b/examples/fabric-sync/bridge/src/FabricBridge.cpp @@ -0,0 +1,223 @@ +/* + * 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 "FabricBridge.h" +#include "BridgedDevice.h" +#include "BridgedDeviceManager.h" + +#include +#include + +#include +#include + +using namespace chip; + +namespace bridge { + +FabricBridge FabricBridge::sInstance; + +FabricBridge & FabricBridge::Instance() +{ + return sInstance; +} + +CHIP_ERROR FabricBridge::AddSynchronizedDevice(const SynchronizedDevice & data) +{ + ChipLogProgress(NotSpecified, "Received AddSynchronizedDevice: Id=[%d:" ChipLogFormatX64 "]", data.id.GetFabricIndex(), + ChipLogValueX64(data.id.GetNodeId())); + + // Create a new BridgedDevice and set it as reachable + auto device = std::make_unique(data.id); + device->SetReachable(true); + + // Initialize BridgedDevice attributes from data + BridgedDevice::BridgedAttributes attributes; + + if (data.uniqueId.has_value()) + { + attributes.uniqueId = data.uniqueId.value(); + } + + if (data.vendorName.has_value()) + { + attributes.vendorName = data.vendorName.value(); + } + + if (data.vendorId.has_value()) + { + attributes.vendorId = data.vendorId.value(); + } + + if (data.productName.has_value()) + { + attributes.productName = data.productName.value(); + } + + if (data.productId.has_value()) + { + attributes.productId = data.productId.value(); + } + + if (data.nodeLabel.has_value()) + { + attributes.nodeLabel = data.nodeLabel.value(); + } + + if (data.hardwareVersion.has_value()) + { + attributes.hardwareVersion = data.hardwareVersion.value(); + } + + if (data.hardwareVersionString.has_value()) + { + attributes.hardwareVersionString = data.hardwareVersionString.value(); + } + + if (data.softwareVersion.has_value()) + { + attributes.softwareVersion = data.softwareVersion.value(); + } + + if (data.softwareVersionString.has_value()) + { + attributes.softwareVersionString = data.softwareVersionString.value(); + } + + // Set bridged device attributes and ICD status + device->SetBridgedAttributes(attributes); + device->SetIcd(data.isIcd.value_or(false)); + + // Add the device to the bridge manager with a parent endpoint + auto result = BridgedDeviceManager::Instance().AddDeviceEndpoint(std::move(device), /* parentEndpointId= */ 1); + if (!result.has_value()) + { + ChipLogError(NotSpecified, "Failed to add device with Id=[%d:0x" ChipLogFormatX64 "]", data.id.GetFabricIndex(), + ChipLogValueX64(data.id.GetNodeId())); + return CHIP_ERROR_ENDPOINT_POOL_FULL; + } + + // Retrieve and verify the added device by ScopedNodeId + BridgedDevice * addedDevice = BridgedDeviceManager::Instance().GetDeviceByScopedNodeId(data.id); + VerifyOrDie(addedDevice); + + ChipLogProgress(NotSpecified, "Added device with Id=[%d:0x" ChipLogFormatX64 "]", data.id.GetFabricIndex(), + ChipLogValueX64(data.id.GetNodeId())); + + // Add the Ecosystem Information Cluster to the device's endpoint + CHIP_ERROR err = + app::Clusters::EcosystemInformation::EcosystemInformationServer::Instance().AddEcosystemInformationClusterToEndpoint( + addedDevice->GetEndpointId()); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to add Ecosystem Information Cluster to endpoint %u: %" CHIP_ERROR_FORMAT, + addedDevice->GetEndpointId(), err.Format()); + } + + return err; +} + +CHIP_ERROR FabricBridge::RemoveSynchronizedDevice(ScopedNodeId scopedNodeId) +{ + ChipLogProgress(NotSpecified, "Received RemoveSynchronizedDevice: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + + auto removedIdx = BridgedDeviceManager::Instance().RemoveDeviceByScopedNodeId(scopedNodeId); + if (!removedIdx.has_value()) + { + ChipLogError(NotSpecified, "Failed to remove device with Id=[%d:0x" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + return CHIP_ERROR_NOT_FOUND; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FabricBridge::ActiveChanged(ScopedNodeId scopedNodeId, uint32_t promisedActiveDurationMs) +{ + ChipLogProgress(NotSpecified, "Received ActiveChanged: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + + auto * device = BridgedDeviceManager::Instance().GetDeviceByScopedNodeId(scopedNodeId); + if (device == nullptr) + { + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); + return CHIP_ERROR_NOT_FOUND; + } + + device->LogActiveChangeEvent(promisedActiveDurationMs); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FabricBridge::AdminCommissioningAttributeChanged(const AdministratorCommissioningChanged & data) +{ + ChipLogProgress(NotSpecified, "Received CADMIN attribute change: Id=[%d:" ChipLogFormatX64 "]", data.id.GetFabricIndex(), + ChipLogValueX64(data.id.GetNodeId())); + + auto * device = BridgedDeviceManager::Instance().GetDeviceByScopedNodeId(data.id); + if (device == nullptr) + { + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + data.id.GetFabricIndex(), ChipLogValueX64(data.id.GetNodeId())); + return CHIP_ERROR_NOT_FOUND; + } + + BridgedDevice::AdminCommissioningAttributes adminCommissioningAttributes; + + VerifyOrReturnError(data.windowStatus < + app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kUnknownEnumValue, + CHIP_ERROR_INVALID_ARGUMENT); + + adminCommissioningAttributes.commissioningWindowStatus = data.windowStatus; + if (data.openerFabricIndex.has_value()) + { + VerifyOrReturnError(data.openerFabricIndex >= kMinValidFabricIndex, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(data.openerFabricIndex <= kMaxValidFabricIndex, CHIP_ERROR_INVALID_ARGUMENT); + adminCommissioningAttributes.openerFabricIndex = data.openerFabricIndex; + } + + if (data.openerVendorId.has_value()) + { + VerifyOrReturnError(data.openerVendorId != VendorId::NotSpecified, CHIP_ERROR_INVALID_ARGUMENT); + adminCommissioningAttributes.openerVendorId = data.openerVendorId; + } + + device->SetAdminCommissioningAttributes(adminCommissioningAttributes); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FabricBridge::DeviceReachableChanged(ScopedNodeId scopedNodeId, bool reachability) +{ + ChipLogProgress(NotSpecified, "Received device reachable changed: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + + auto * device = BridgedDeviceManager::Instance().GetDeviceByScopedNodeId(scopedNodeId); + if (device == nullptr) + { + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); + return CHIP_ERROR_NOT_FOUND; + } + + device->ReachableChanged(reachability); + + return CHIP_NO_ERROR; +} + +} // namespace bridge diff --git a/examples/fabric-sync/main.cpp b/examples/fabric-sync/main.cpp index 3cd5ab8c20f1c9..8772400ff2ae16 100644 --- a/examples/fabric-sync/main.cpp +++ b/examples/fabric-sync/main.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * @@ -17,7 +16,9 @@ */ #include +#include #include +#include #if defined(ENABLE_CHIP_SHELL) #include "ShellCommands.h" @@ -82,12 +83,21 @@ void ApplicationInit() // Redirect logs to the custom logging callback Logging::SetLogRedirectCallback(LoggingCallback); + + CHIP_ERROR err = bridge::BridgeInit(&admin::FabricAdmin::Instance()); + VerifyOrDieWithMsg(err == CHIP_NO_ERROR, NotSpecified, "Fabric-Sync: Failed to initialize bridge, error: %s", ErrorStr(err)); } void ApplicationShutdown() { ChipLogDetail(NotSpecified, "Fabric-Sync: ApplicationShutdown()"); CloseLogFile(); + + CHIP_ERROR err = bridge::BridgeShutdown(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Fabric-Sync: Failed to shutdown bridge, error: %s", ErrorStr(err)); + } } int main(int argc, char * argv[]) diff --git a/examples/fabric-sync/shell/AddBridgeCommand.cpp b/examples/fabric-sync/shell/AddBridgeCommand.cpp index 936ac1c321ca50..e6b9dd060351e6 100644 --- a/examples/fabric-sync/shell/AddBridgeCommand.cpp +++ b/examples/fabric-sync/shell/AddBridgeCommand.cpp @@ -48,12 +48,21 @@ void AddBridgeCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) if (err == CHIP_NO_ERROR) { - admin::DeviceMgr().SetRemoteBridgeNodeId(mBridgeNodeId); + admin::DeviceManager::Instance().SetRemoteBridgeNodeId(mBridgeNodeId); ChipLogProgress(NotSpecified, "Successfully paired bridge device: NodeId: " ChipLogFormatX64, ChipLogValueX64(mBridgeNodeId)); - admin::DeviceMgr().UpdateLastUsedNodeId(mBridgeNodeId); + admin::DeviceManager::Instance().UpdateLastUsedNodeId(mBridgeNodeId); + admin::DeviceManager::Instance().SubscribeRemoteFabricBridge(); + + // After successful commissioning of the Commissionee, initiate Reverse Commissioning + // via the Commissioner Control Cluster. However, we must first verify that the + // remote Fabric-Bridge supports Fabric Synchronization. + // + // Note: The Fabric-Admin MUST NOT send the RequestCommissioningApproval command + // if the remote Fabric-Bridge lacks Fabric Synchronization support. + DeviceLayer::SystemLayer().ScheduleLambda([]() { admin::DeviceManager::Instance().ReadSupportedDeviceCategories(); }); } else { @@ -66,16 +75,19 @@ void AddBridgeCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) CHIP_ERROR AddBridgeCommand::RunCommand() { - if (admin::DeviceMgr().IsFabricSyncReady()) + if (admin::DeviceManager::Instance().IsFabricSyncReady()) { // print to console fprintf(stderr, "Remote Fabric Bridge has already been configured.\n"); - return CHIP_NO_ERROR; + return CHIP_ERROR_INCORRECT_STATE; } admin::PairingManager::Instance().SetPairingDelegate(this); - return admin::DeviceMgr().PairRemoteFabricBridge(mBridgeNodeId, mSetupPINCode, mRemoteAddr, mRemotePort); + ChipLogProgress(NotSpecified, "Running AddBridgeCommand with Node ID: %lu, PIN Code: %u, Address: %s, Port: %u", mBridgeNodeId, + mSetupPINCode, mRemoteAddr, mRemotePort); + + return admin::DeviceManager::Instance().PairRemoteFabricBridge(mBridgeNodeId, mSetupPINCode, mRemoteAddr, mRemotePort); } } // namespace commands diff --git a/examples/fabric-sync/shell/AddDeviceCommand.cpp b/examples/fabric-sync/shell/AddDeviceCommand.cpp index 218691e74401ea..a79e4696caaf4e 100644 --- a/examples/fabric-sync/shell/AddDeviceCommand.cpp +++ b/examples/fabric-sync/shell/AddDeviceCommand.cpp @@ -51,7 +51,7 @@ void AddDeviceCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) { ChipLogProgress(NotSpecified, "Successfully paired device: NodeId: " ChipLogFormatX64, ChipLogValueX64(mNodeId)); - admin::DeviceMgr().UpdateLastUsedNodeId(mNodeId); + admin::DeviceManager::Instance().UpdateLastUsedNodeId(mNodeId); } else { @@ -64,16 +64,19 @@ void AddDeviceCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR err) CHIP_ERROR AddDeviceCommand::RunCommand() { - if (admin::DeviceMgr().IsCurrentBridgeDevice(mNodeId)) + if (admin::DeviceManager::Instance().IsCurrentBridgeDevice(mNodeId)) { // print to console fprintf(stderr, "The specified node ID has been reserved by the Fabric Bridge.\n"); return CHIP_ERROR_INVALID_ARGUMENT; } + ChipLogProgress(NotSpecified, "Running AddDeviceCommand with Node ID: %lu, PIN Code: %u, Address: %s, Port: %u", mNodeId, + mSetupPINCode, mRemoteAddr, mRemotePort); + admin::PairingManager::Instance().SetPairingDelegate(this); - return admin::DeviceMgr().PairRemoteDevice(mNodeId, mSetupPINCode, mRemoteAddr, mRemotePort); + return admin::DeviceManager::Instance().PairRemoteDevice(mNodeId, mSetupPINCode, mRemoteAddr, mRemotePort); } } // namespace commands diff --git a/examples/fabric-sync/shell/BUILD.gn b/examples/fabric-sync/shell/BUILD.gn index b3726ee178f9e0..436f8b5160e66c 100644 --- a/examples/fabric-sync/shell/BUILD.gn +++ b/examples/fabric-sync/shell/BUILD.gn @@ -31,6 +31,7 @@ source_set("shell") { "AddBridgeCommand.h", "AddDeviceCommand.cpp", "AddDeviceCommand.h", + "CommandRegistry.cpp", "CommandRegistry.h", "RemoveBridgeCommand.cpp", "RemoveBridgeCommand.h", diff --git a/examples/fabric-sync/shell/CommandRegistry.cpp b/examples/fabric-sync/shell/CommandRegistry.cpp new file mode 100644 index 00000000000000..34c01357eafd57 --- /dev/null +++ b/examples/fabric-sync/shell/CommandRegistry.cpp @@ -0,0 +1,48 @@ +/* + * 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 "CommandRegistry.h" + +#include + +using namespace ::chip; + +namespace commands { + +void CommandRegistry::SetActiveCommand(std::unique_ptr command, uint32_t timeoutSeconds) +{ + mActiveCommand = std::move(command); + + // Cancel any previous timer to avoid multiple timers running simultaneously + DeviceLayer::SystemLayer().CancelTimer(OnTimeout, this); + + // Start a new timer for the specified timeout + CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(timeoutSeconds * 1000), OnTimeout, this); + if (err != CHIP_NO_ERROR) + { + ResetActiveCommand(); + } +} + +void CommandRegistry::ResetActiveCommand() +{ + DeviceLayer::SystemLayer().CancelTimer(OnTimeout, this); + mActiveCommand.reset(); +} + +} // namespace commands diff --git a/examples/fabric-sync/shell/CommandRegistry.h b/examples/fabric-sync/shell/CommandRegistry.h index ec53e17960d98c..0043c267a5104e 100644 --- a/examples/fabric-sync/shell/CommandRegistry.h +++ b/examples/fabric-sync/shell/CommandRegistry.h @@ -38,16 +38,23 @@ class CommandRegistry return instance; } - void SetActiveCommand(std::unique_ptr command) { mActiveCommand = std::move(command); } + void SetActiveCommand(std::unique_ptr command, uint32_t timeoutSeconds = 30); Command * GetActiveCommand() { return mActiveCommand.get(); } - void ResetActiveCommand() { mActiveCommand.reset(); } + void ResetActiveCommand(); bool IsCommandActive() const { return mActiveCommand != nullptr; } private: CommandRegistry() = default; + + static void OnTimeout(chip::System::Layer * layer, void * appState) + { + // Callback function to reset the command when the timer expires + static_cast(appState)->ResetActiveCommand(); + } + std::unique_ptr mActiveCommand; }; diff --git a/examples/fabric-sync/shell/RemoveBridgeCommand.cpp b/examples/fabric-sync/shell/RemoveBridgeCommand.cpp index 2eaaf6fc34476f..9a33b0b11ba94e 100644 --- a/examples/fabric-sync/shell/RemoveBridgeCommand.cpp +++ b/examples/fabric-sync/shell/RemoveBridgeCommand.cpp @@ -35,7 +35,7 @@ void RemoveBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err) if (err == CHIP_NO_ERROR) { - admin::DeviceMgr().SetRemoteBridgeNodeId(kUndefinedNodeId); + admin::DeviceManager::Instance().SetRemoteBridgeNodeId(kUndefinedNodeId); // print to console fprintf(stderr, "Successfully removed bridge device: NodeId: " ChipLogFormatX64 "\n", ChipLogValueX64(mBridgeNodeId)); @@ -51,20 +51,22 @@ void RemoveBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err) CHIP_ERROR RemoveBridgeCommand::RunCommand() { - NodeId bridgeNodeId = admin::DeviceMgr().GetRemoteBridgeNodeId(); + NodeId bridgeNodeId = admin::DeviceManager::Instance().GetRemoteBridgeNodeId(); if (bridgeNodeId == kUndefinedNodeId) { // print to console fprintf(stderr, "Remote Fabric Bridge is not configured yet, nothing to remove.\n"); - return CHIP_NO_ERROR; + return CHIP_ERROR_INCORRECT_STATE; } mBridgeNodeId = bridgeNodeId; + ChipLogProgress(NotSpecified, "Running RemoveBridgeCommand"); + admin::PairingManager::Instance().SetPairingDelegate(this); - return admin::DeviceMgr().UnpairRemoteFabricBridge(); + return admin::DeviceManager::Instance().UnpairRemoteFabricBridge(); } } // namespace commands diff --git a/examples/fabric-sync/shell/RemoveDeviceCommand.cpp b/examples/fabric-sync/shell/RemoveDeviceCommand.cpp index 266a2ad1065569..5e316658d5b303 100644 --- a/examples/fabric-sync/shell/RemoveDeviceCommand.cpp +++ b/examples/fabric-sync/shell/RemoveDeviceCommand.cpp @@ -52,7 +52,7 @@ void RemoveDeviceCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err) CHIP_ERROR RemoveDeviceCommand::RunCommand() { - if (admin::DeviceMgr().IsCurrentBridgeDevice(mNodeId)) + if (admin::DeviceManager::Instance().IsCurrentBridgeDevice(mNodeId)) { // print to console fprintf(stderr, "The specified node ID has been reserved by the Fabric Bridge.\n"); @@ -61,7 +61,9 @@ CHIP_ERROR RemoveDeviceCommand::RunCommand() admin::PairingManager::Instance().SetPairingDelegate(this); - return admin::DeviceMgr().UnpairRemoteDevice(mNodeId); + ChipLogProgress(NotSpecified, "Running RemoveDeviceCommand with Node ID: %lu", mNodeId); + + return admin::DeviceManager::Instance().UnpairRemoteDevice(mNodeId); } } // namespace commands diff --git a/examples/fabric-sync/shell/ShellCommands.cpp b/examples/fabric-sync/shell/ShellCommands.cpp index fa859a34d5261e..3bab442aa5fc47 100644 --- a/examples/fabric-sync/shell/ShellCommands.cpp +++ b/examples/fabric-sync/shell/ShellCommands.cpp @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -134,7 +133,7 @@ static CHIP_ERROR HandleAddDeviceCommand(int argc, char ** argv) const char * remoteAddr = argv[3]; uint16_t remotePort = static_cast(strtoul(argv[4], nullptr, 10)); - auto command = std::make_unique(nodeId, setupPINCode, remoteAddr, remotePort); + auto command = std::make_unique(nodeId, setupPINCode, remoteAddr, remotePort); CHIP_ERROR result = command->RunCommand(); if (result == CHIP_NO_ERROR) diff --git a/examples/fabric-sync/shell/ShellCommands.h b/examples/fabric-sync/shell/ShellCommands.h index ab957bc8cd92d7..b5bd5085fba3dc 100644 --- a/examples/fabric-sync/shell/ShellCommands.h +++ b/examples/fabric-sync/shell/ShellCommands.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h +++ b/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h +++ b/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h index 2653e97705fe39..33a42909f464ea 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h +++ b/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -168,15 +168,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/light-switch-app/esp32/main/CMakeLists.txt b/examples/light-switch-app/esp32/main/CMakeLists.txt index b4b6f5946eb2f9..92be83565a138e 100644 --- a/examples/light-switch-app/esp32/main/CMakeLists.txt +++ b/examples/light-switch-app/esp32/main/CMakeLists.txt @@ -30,6 +30,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" diff --git a/examples/light-switch-app/silabs/build_for_wifi_args.gni b/examples/light-switch-app/silabs/build_for_wifi_args.gni index ac70e16a8b484f..ed368c024847b7 100644 --- a/examples/light-switch-app/silabs/build_for_wifi_args.gni +++ b/examples/light-switch-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/light-switch-app/light-switch-common" diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index d3dc3421cc105f..1ad5bc1aa37c9e 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -34,6 +34,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 59bf2f26bed466..dd5b65afe632df 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -51,6 +51,7 @@ target_sources(app PRIVATE main/AppTask.cpp main/main.cpp main/ZclCallbacks.cpp + ${CHIP_ROOT}/src/app/util/persistence/DeferredAttributePersistenceProvider.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp ${NRFCONNECT_COMMON}/util/PWMDevice.cpp) diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 88964d9aa1d3c8..014849780caf06 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -26,13 +26,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/examples/lighting-app/qpg/BUILD.gn b/examples/lighting-app/qpg/BUILD.gn index 886c8aa313d097..b4a2998f02dc7f 100644 --- a/examples/lighting-app/qpg/BUILD.gn +++ b/examples/lighting-app/qpg/BUILD.gn @@ -66,6 +66,7 @@ qpg_executable("lighting_app") { "${chip_root}/examples/lighting-app/lighting-common:color-format", "${chip_root}/examples/lighting-app/qpg/zap/", "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/app/util/persistence:deferred", "${chip_root}/src/lib", "${chip_root}/src/platform/logging:default", "${chip_root}/src/setup_payload", diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 90f2e30ecb03c5..0c09e97a6a5681 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/examples/lighting-app/silabs/build_for_wifi_args.gni b/examples/lighting-app/silabs/build_for_wifi_args.gni index 7e33551c30a97c..f8cc0089c8d416 100644 --- a/examples/lighting-app/silabs/build_for_wifi_args.gni +++ b/examples/lighting-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") # Not needed for the Lighting-app chip_enable_read_client = false diff --git a/examples/lit-icd-app/esp32/main/CMakeLists.txt b/examples/lit-icd-app/esp32/main/CMakeLists.txt index 5f2850feff98b6..4d8fe2ab4bb163 100644 --- a/examples/lit-icd-app/esp32/main/CMakeLists.txt +++ b/examples/lit-icd-app/esp32/main/CMakeLists.txt @@ -29,6 +29,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/lit-icd-app/silabs/build_for_wifi_args.gni b/examples/lit-icd-app/silabs/build_for_wifi_args.gni index c8048dc71e3b4b..57843c9b5408eb 100644 --- a/examples/lit-icd-app/silabs/build_for_wifi_args.gni +++ b/examples/lit-icd-app/silabs/build_for_wifi_args.gni @@ -18,7 +18,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/lit-icd-app/lit-icd-common" diff --git a/examples/lock-app/esp32/main/CMakeLists.txt b/examples/lock-app/esp32/main/CMakeLists.txt index 5c5f46abdd1860..028a92ae8dbd27 100644 --- a/examples/lock-app/esp32/main/CMakeLists.txt +++ b/examples/lock-app/esp32/main/CMakeLists.txt @@ -49,6 +49,7 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" @@ -162,6 +163,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" diff --git a/examples/lock-app/silabs/build_for_wifi_args.gni b/examples/lock-app/silabs/build_for_wifi_args.gni index cbc84b30bbe627..bb6da0b53563f5 100644 --- a/examples/lock-app/silabs/build_for_wifi_args.gni +++ b/examples/lock-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/lock-app/silabs/data_model:silabs-lock" diff --git a/examples/ota-provider-app/esp32/main/CMakeLists.txt b/examples/ota-provider-app/esp32/main/CMakeLists.txt index 41acd9e9316e00..d651ac77065803 100644 --- a/examples/ota-provider-app/esp32/main/CMakeLists.txt +++ b/examples/ota-provider-app/esp32/main/CMakeLists.txt @@ -26,6 +26,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/ota-requestor-app/esp32/main/CMakeLists.txt b/examples/ota-requestor-app/esp32/main/CMakeLists.txt index fbda70f2cec48f..2688fea4977eab 100644 --- a/examples/ota-requestor-app/esp32/main/CMakeLists.txt +++ b/examples/ota-requestor-app/esp32/main/CMakeLists.txt @@ -31,6 +31,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn b/examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn index d49e9e7638c817..1034d91febf465 100644 --- a/examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn +++ b/examples/platform/nxp/mcxw71_k32w1/app/support/BUILD.gn @@ -42,12 +42,14 @@ config("support_config") { source_set("freertos_memory_utils") { sources = [ - "FreeRtosHooks.c", - "FreeRtosHooks.h", + "FreeRtosHooks.cpp", "Memconfig.cpp", ] - deps = [ "${chip_root}/src/lib/support" ] + deps = [ + "${chip_root}/src/lib/support", + "${chip_root}/src/platform:platform_config_header", + ] cflags = [ "-Wconversion" ] @@ -57,5 +59,8 @@ source_set("freertos_memory_utils") { defines = [ "CHIP_PLAT_NVM_SUPPORT=3" ] } - public_configs = [ ":support_config" ] + public_configs = [ + ":support_config", + "${chip_root}/src:includes", + ] } diff --git a/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.c b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.cpp similarity index 95% rename from examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.c rename to examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.cpp index bc5acf2e88401b..193b262231499d 100644 --- a/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.c +++ b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.cpp @@ -27,6 +27,9 @@ #include #include +/* Include CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR */ +#include + #if (CHIP_PLAT_NVM_SUPPORT == 1) #include "NVM_Interface.h" #elif (CHIP_PLAT_NVM_SUPPORT == 3) @@ -55,6 +58,8 @@ #define APP_DBG_LOG(...) #endif +extern "C" { + static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex) { assert(p_mutex != NULL); @@ -73,7 +78,7 @@ static inline int mutex_lock(mbedtls_threading_mutex_t * p_mutex) { assert(p_mutex != NULL); assert(*p_mutex != NULL); - return xSemaphoreTake(*p_mutex, portMAX_DELAY) != pdTRUE; + return xSemaphoreTake((SemaphoreHandle_t) (*p_mutex), portMAX_DELAY) != pdTRUE; } static inline int mutex_unlock(mbedtls_threading_mutex_t * p_mutex) @@ -153,3 +158,5 @@ void vApplicationIdleHook(void) OTAIdleActivities(); #endif } + +} // extern "C" diff --git a/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h index a27f72d498f81d..963b38973dd0f0 100644 --- a/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h +++ b/examples/platform/nxp/mcxw71_k32w1/app/support/FreeRtosHooks.h @@ -20,17 +20,15 @@ typedef void * mbedtls_threading_mutex_t; -extern void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), - void (*mutex_free)(mbedtls_threading_mutex_t *), - int (*mutex_lock)(mbedtls_threading_mutex_t *), - int (*mutex_unlock)(mbedtls_threading_mutex_t *)); - -extern void mbedtls_threading_free_alt(void); - #ifdef __cplusplus extern "C" { #endif +void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), void (*mutex_free)(mbedtls_threading_mutex_t *), + int (*mutex_lock)(mbedtls_threading_mutex_t *), int (*mutex_unlock)(mbedtls_threading_mutex_t *)); + +void mbedtls_threading_free_alt(void); + /**@brief Function for initializing alternative MbedTLS mutexes to enable the usage of the FreeRTOS implementation. */ void freertos_mbedtls_mutex_init(void); diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index b8a240f5e01a21..905bd48d1673fd 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -64,10 +64,9 @@ #include #ifdef SL_WIFI -#include "WifiInterfaceAbstraction.h" -#include "wfx_host_events.h" #include #include +#include #endif // SL_WIFI #ifdef DIC_ENABLE diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 2045c83afad0c2..8c0488f74c1bd0 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -25,7 +25,7 @@ #include #ifdef SL_WIFI -#include "wfx_host_events.h" +#include #endif /* SL_WIFI */ #if PW_RPC_ENABLED @@ -41,8 +41,8 @@ #endif #if defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1 -#include "SiWxPlatformInterface.h" -#include "WiseconnectInterfaceAbstraction.h" +#include +#include #endif // SLI_SI91X_MCU_INTERFACE #include diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 5045989389af0e..2d6d3574ea3506 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -18,7 +18,7 @@ import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") import("${chip_root}/examples/platform/silabs/args.gni") import("${chip_root}/src/lib/lib.gni") import("${chip_root}/src/platform/device.gni") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") import("${chip_root}/third_party/silabs/silabs_board.gni") import("${silabs_sdk_build_root}/SiWx917_sdk.gni") @@ -28,19 +28,6 @@ declare_args() { # OTA timeout in seconds ota_periodic_query_timeout_sec = 86400 - # Wifi related stuff - they are overridden by gn -args="use_wf200=true" - sl_wfx_config_softap = false - sl_wfx_config_scan = true - - # Argument to force enable WPA3 security on rs91x - rs91x_wpa3_transition = true - - #default WiFi SSID - chip_default_wifi_ssid = "" - - #default Wifi Password - chip_default_wifi_psk = "" - # The EnableKey in hex string format used by TestEventTrigger command in # GeneralDiagnostics cluster. The length of the string should be 16 bytes. sl_test_event_trigger_enable_key = "00112233445566778899AABBCCDDEEFF" @@ -105,41 +92,6 @@ source_set("matter-shell") { ] } -config("wifi-interface-config") { - include_dirs = [ - "${silabs_plat_dir}/wifi", - "${silabs_common_plat_dir}/wifi", - ] -} - -source_set("wifi-interface") { - sources = [ - "${silabs_common_plat_dir}/wifi/WifiInterfaceAbstraction.cpp", - "${silabs_common_plat_dir}/wifi/WiseconnectInterfaceAbstraction.cpp", - "SiWxWifiInterface.cpp", - - # Wi-Fi Config - Using the file sdk support until the wiseconnect file is fixed - "${sdk_support_root}/components/service/network_manager/src/sl_net_for_lwip.c", - ] - - public_deps = [ - "${chip_root}/src/app/icd/server:icd-server-config", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - "${chip_root}/src/platform:platform", - "${chip_root}/src/platform/silabs/SiWx917:SiWx917", - "${lwip_root}:lwip", - ] - - public_configs = [ - ":siwx917-common-config", - "${silabs_sdk_build_root}:silabs_config", - ":chip_examples_project_config", - ":wifi-interface-config", - ":silabs-wifi-config", - ] -} - config("siwx917-common-config") { defines = [ "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_sec}" ] @@ -164,46 +116,10 @@ config("siwx917-common-config") { ldflags = [ "-Wl,--no-warn-rwx-segment" ] } -config("silabs-wifi-config") { - defines = [] - include_dirs = [] - - if (chip_default_wifi_ssid != "") { - defines += [ - "SL_ONNETWORK_PAIRING=1", - "SL_WIFI_SSID=\"${chip_default_wifi_ssid}\"", - ] - } - if (chip_default_wifi_psk != "") { - assert(chip_default_wifi_ssid != "", - "ssid can't be null if psk is provided") - defines += [ "SL_WIFI_PSK=\"${chip_default_wifi_psk}\"" ] - } - - if (sl_wfx_config_softap) { - defines += [ "SL_WFX_CONFIG_SOFTAP" ] - } - - if (sl_wfx_config_scan) { - defines += [ "SL_WFX_CONFIG_SCAN" ] - } - - if (chip_enable_wifi_ipv4) { - defines += [ "CHIP_DEVICE_CONFIG_ENABLE_IPV4" ] - } - - if (rs91x_wpa3_transition) { - defines += [ "WIFI_ENABLE_SECURITY_WPA3_TRANSITION=1" ] - } -} - source_set("siwx917-common") { deps = [ "${silabs_common_plat_dir}/provision:storage" ] defines = [] - public_deps = [ - ":wifi-interface", - "${lwip_root}:lwip", - ] + public_deps = [] public_configs = [ ":siwx917-common-config", @@ -250,10 +166,6 @@ source_set("siwx917-common") { sources += [ "${silabs_common_plat_dir}/MemMonitoring.cpp" ] } - if (chip_enable_wifi) { - public_configs += [ ":silabs-wifi-config" ] - } - if (chip_build_libshell) { deps += [ ":matter-shell" ] diff --git a/examples/platform/silabs/display/demo-ui.c b/examples/platform/silabs/display/demo-ui.c index d909cb1f885172..fb41a5b3097583 100644 --- a/examples/platform/silabs/display/demo-ui.c +++ b/examples/platform/silabs/display/demo-ui.c @@ -27,9 +27,8 @@ #include "sl_memlcd.h" #include #if SL_WIFI && !SLI_SI91X_MCU_INTERFACE -#include "spi_multiplex.h" +#include #endif // SL_WIFI && !SLI_SI91X_MCU_INTERFACE -#include #include // Main Logo and App image diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 9e6b700cfde727..e0e7b45070d2fc 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -27,19 +27,6 @@ declare_args() { # OTA timeout in seconds ota_periodic_query_timeout_sec = 86400 - # Wifi related stuff - they are overridden by gn -args="use_wf200=true" - sl_wfx_config_softap = false - sl_wfx_config_scan = true - - # Argument to force enable WPA3 security on rs91x - rs91x_wpa3_transition = true - - #default WiFi SSID - chip_default_wifi_ssid = "" - - #default Wifi Password - chip_default_wifi_psk = "" - # The EnableKey in hex string format used by TestEventTrigger command in # GeneralDiagnostics cluster. The length of the string should be 16 bytes. sl_test_event_trigger_enable_key = "00112233445566778899AABBCCDDEEFF" @@ -53,20 +40,6 @@ assert(!(use_rs9116 && chip_enable_openthread)) assert(!(use_SiWx917 && chip_enable_openthread)) assert(!(use_wf200 && chip_enable_openthread)) -if (chip_enable_wifi) { - assert(use_rs9116 || use_wf200 || use_SiWx917) - import("${chip_root}/src/platform/silabs/wifi_args.gni") - - if (use_rs9116) { - import("rs911x/rs911x.gni") - } else if (use_SiWx917) { - import("rs911x/rs9117.gni") - } - if (use_wf200) { - import("wf200/wf200.gni") - } -} - config("chip_examples_project_config") { include_dirs = [ "project_include" ] @@ -167,40 +140,6 @@ config("efr32-common-config") { ldflags = [ "-Wl,--no-warn-rwx-segment" ] } -config("silabs-wifi-config") { - defines = [] - include_dirs = [] - - if (chip_default_wifi_ssid != "") { - defines += [ - "SL_ONNETWORK_PAIRING=1", - "SL_WIFI_SSID=\"${chip_default_wifi_ssid}\"", - ] - } - if (chip_default_wifi_psk != "") { - assert(chip_default_wifi_ssid != "", - "ssid can't be null if psk is provided") - defines += [ "SL_WIFI_PSK=\"${chip_default_wifi_psk}\"" ] - } - - if (sl_wfx_config_softap) { - defines += [ "SL_WFX_CONFIG_SOFTAP" ] - } - - if (sl_wfx_config_scan) { - defines += [ "SL_WFX_CONFIG_SCAN" ] - } - - if (chip_enable_wifi_ipv4) { - defines += [ "CHIP_DEVICE_CONFIG_ENABLE_IPV4" ] - } - - if (rs91x_wpa3_transition) { - # TODO: Change this macro once WF200 support is provided - defines += [ "WIFI_ENABLE_SECURITY_WPA3_TRANSITION=1" ] - } -} - source_set("efr32-common") { deps = [ "${silabs_common_plat_dir}/provision:storage" ] defines = [] @@ -265,32 +204,6 @@ source_set("efr32-common") { ] } - if (chip_enable_wifi) { - if (use_rs9116) { - sources += rs911x_src_plat - - # All the stuff from wiseconnect - sources += rs911x_src_sapi - include_dirs += rs911x_inc_plat - - #add compilation flags for rs991x build. This will be addressed directly in wiseconnect sdk in the next version release of that sdk - cflags = rs911x_cflags - } else if (use_SiWx917) { - sources += rs911x_src_plat - - # All the stuff from wiseconnect - sources += rs9117_src_sapi - include_dirs += rs9117_inc_plat - - #add compilation flags for rs991x build. This will be addressed directly in wiseconnect sdk in the next version release of that sdk - } else if (use_wf200) { - sources += wf200_plat_src - include_dirs += wf200_plat_incs - } - - public_configs += [ ":silabs-wifi-config" ] - } - if (chip_build_libshell) { deps += [ ":matter-shell" ] diff --git a/examples/platform/silabs/efr32/wf200/sl_wfx_configuration.h b/examples/platform/silabs/efr32/wf200/sl_wfx_configuration.h deleted file mode 100644 index deb468d1a6af73..00000000000000 --- a/examples/platform/silabs/efr32/wf200/sl_wfx_configuration.h +++ /dev/null @@ -1,30 +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. - */ - -#pragma once - -// SL_WFX_DEFAULT_REQUEST_TIMEOUT_MS> Timeout period in milliseconds<250-10000> -// Default: 5000 -// Timeout period in milliseconds for requests. -#define SL_WFX_DEFAULT_REQUEST_TIMEOUT_MS (5000) - -// WFx Secure Link configuration - -// SL_WFX_SLK_CURVE25519> Use crypto curves -// Default: 1 -// If this option is enabled ECDH crypto is used, KDF otherwise. -#define SL_WFX_SLK_CURVE25519 (1) diff --git a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h b/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h deleted file mode 100644 index 1d4b2163c77abe..00000000000000 --- a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h +++ /dev/null @@ -1,106 +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. - */ -#pragma once - -#include -#include -#include -#include -#include - -/* - * Interface to RSI Sapis - */ - -#define WFX_RSI_DHCP_POLL_INTERVAL (250) /* Poll interval in ms for DHCP */ -#define MAX_JOIN_RETRIES_COUNT (5) - -enum class WifiState : uint16_t -{ - kStationInit = (1 << 0), - kAPReady = (1 << 1), - kStationProvisioned = (1 << 2), - kStationConnecting = (1 << 3), - kStationConnected = (1 << 4), - kStationDhcpDone = (1 << 6), /* Requested to do DHCP after conn */ - kStationMode = (1 << 7), /* Enable Station Mode */ - kAPMode = (1 << 8), /* Enable AP Mode */ - kStationReady = (kStationConnected | kStationDhcpDone), - kStationStarted = (1 << 9), /* RSI task started */ - kScanStarted = (1 << 10), /* Scan Started */ -}; - -enum class WifiEvent : uint8_t -{ - kStationConnect = 0, - kStationDisconnect = 1, - kAPStart = 2, - kAPStop = 3, - kScan = 4, /* This is used as scan result and start */ - kStationStartJoin = 5, - kStationDoDhcp = 6, - kStationDhcpDone = 7, - kStationDhcpPoll = 8 -}; - -typedef struct wfx_rsi_s -{ - chip::BitFlags dev_state; - uint16_t ap_chan; /* The chan our STA is using */ - wfx_wifi_provision_t sec; -#ifdef SL_WFX_CONFIG_SCAN - void (*scan_cb)(wfx_wifi_scan_result_t *); - char * scan_ssid; /* Which one are we scanning for */ - size_t scan_ssid_length; -#endif -#ifdef SL_WFX_CONFIG_SOFTAP - sl_wfx_mac_address_t softap_mac; -#endif - sl_wfx_mac_address_t sta_mac; - sl_wfx_mac_address_t ap_mac; /* To which our STA is connected */ - sl_wfx_mac_address_t ap_bssid; /* To which our STA is connected */ - uint16_t join_retries; - uint8_t ip4_addr[4]; /* Not sure if this is enough */ -} WfxRsi_t; - -extern WfxRsi_t wfx_rsi; - -void sl_matter_wifi_task(void * arg); - -#if CHIP_DEVICE_CONFIG_ENABLE_IPV4 -void wfx_ip_changed_notify(int got_ip); -#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ - -int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap); -int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t * extra_info); -int32_t wfx_rsi_reset_count(); -int32_t sl_wifi_platform_disconnect(); - -#if CHIP_CONFIG_ENABLE_ICD_SERVER -#if SLI_SI917 -int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); -#else -int32_t wfx_rsi_power_save(); -#endif /* SLI_SI917 */ -#endif /* SL_ICD_ENABLED */ - -/** - * @brief Posts an event to the Wi-Fi task - * - * @param[in] event Event to process. - */ -void sl_matter_wifi_post_event(WifiEvent event); diff --git a/examples/pump-app/silabs/build_for_wifi_args.gni b/examples/pump-app/silabs/build_for_wifi_args.gni index c9544469215d2a..9e6aeced58d2c0 100644 --- a/examples/pump-app/silabs/build_for_wifi_args.gni +++ b/examples/pump-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/pump-app/silabs/data_model:silabs-pump" diff --git a/examples/refrigerator-app/silabs/build_for_wifi_args.gni b/examples/refrigerator-app/silabs/build_for_wifi_args.gni index e82cf8be12fc97..a12daf827a774f 100644 --- a/examples/refrigerator-app/silabs/build_for_wifi_args.gni +++ b/examples/refrigerator-app/silabs/build_for_wifi_args.gni @@ -15,7 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_wifi = true chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/refrigerator-app/silabs/data_model:silabs-refrigerator" diff --git a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni index e5097f8a1d82b7..bdebe11b9789f3 100644 --- a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni +++ b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni @@ -16,7 +16,7 @@ import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = diff --git a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt index 8bc94f7b97969a..8036700df626a0 100644 --- a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt +++ b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt @@ -29,6 +29,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/administrator-commissioning-server" diff --git a/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h +++ b/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h index dd73c6c9eaaedd..61be0867102324 100644 --- a/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h +++ b/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -167,15 +167,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h index 2653e97705fe39..33a42909f464ea 100644 --- a/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h +++ b/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -168,15 +168,6 @@ */ // #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_MAX_BINDINGS - * - * Maximum number of simultaneously active bindings per ChipExchangeManager - * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 - * in the worst case. Keeping another 4 as buffer. - */ -#define CHIP_CONFIG_MAX_BINDINGS 6 - /** * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD * diff --git a/examples/thermostat/silabs/build_for_wifi_args.gni b/examples/thermostat/silabs/build_for_wifi_args.gni index db1e280b0b31d2..76a77c24cdc1d8 100644 --- a/examples/thermostat/silabs/build_for_wifi_args.gni +++ b/examples/thermostat/silabs/build_for_wifi_args.gni @@ -15,7 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_wifi = true chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/thermostat/thermostat-common" diff --git a/examples/thread-br-app/esp32/main/CMakeLists.txt b/examples/thread-br-app/esp32/main/CMakeLists.txt index c0cb1234b0cca3..c1f82285e4ac7f 100644 --- a/examples/thread-br-app/esp32/main/CMakeLists.txt +++ b/examples/thread-br-app/esp32/main/CMakeLists.txt @@ -30,6 +30,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util/persistence" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/access-control-server" diff --git a/examples/window-app/silabs/build_for_wifi_args.gni b/examples/window-app/silabs/build_for_wifi_args.gni index d6a8a54afbedb2..6f445aeb798eb9 100644 --- a/examples/window-app/silabs/build_for_wifi_args.gni +++ b/examples/window-app/silabs/build_for_wifi_args.gni @@ -15,7 +15,7 @@ import("//build_overrides/chip.gni") silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_openthread = false -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") chip_enable_ota_requestor = true app_data_model = "${chip_root}/examples/window-app/common:window-common" diff --git a/examples/window-app/silabs/src/WindowManager.cpp b/examples/window-app/silabs/src/WindowManager.cpp index 8ae78b3d2e99b8..62e96802c323c8 100644 --- a/examples/window-app/silabs/src/WindowManager.cpp +++ b/examples/window-app/silabs/src/WindowManager.cpp @@ -35,9 +35,9 @@ #include #ifdef SL_WIFI -#include "wfx_host_events.h" #include #include +#include #endif #ifdef DISPLAY_ENABLED diff --git a/integrations/docker/images/chip-cert-bins/Dockerfile b/integrations/docker/images/chip-cert-bins/Dockerfile index 59c127dc1f8191..07c366231b8213 100644 --- a/integrations/docker/images/chip-cert-bins/Dockerfile +++ b/integrations/docker/images/chip-cert-bins/Dockerfile @@ -258,30 +258,36 @@ RUN apt-get update -y RUN apt-get install -y libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev avahi-utils iproute2 libcairo2-dev libgirepository1.0-dev python3-pip WORKDIR /root/ COPY --from=chip-build-cert-bins /root/.sdk-sha-version .sdk-sha-version -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tool chip-tool -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-shell chip-shell -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-cert chip-cert -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app chip-all-clusters-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app-nlfaultinject chip-all-clusters-app-nlfaultinject -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-minimal-app chip-all-clusters-minimal-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lighting-app chip-lighting-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tv-casting-app chip-tv-casting-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tv-app chip-tv-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-bridge-app chip-bridge-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/thermostat-app thermostat-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-ota-provider-app chip-ota-provider-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-ota-requestor-app chip-ota-requestor-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lock-app chip-lock-app -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-app1 chip-app1 -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/lit-icd-app lit-icd-app -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 -COPY --from=chip-build-cert-bins /root/connectedhomeip/out/matter-network-manager-app matter-network-manager-app +RUN mkdir apps +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tool apps/chip-tool +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-shell apps/chip-shell +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-cert apps/chip-cert +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app apps/chip-all-clusters-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app-nlfaultinject apps/hip-all-clusters-app-nlfaultinject +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-minimal-app apps/chip-all-clusters-minimal-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lighting-app apps/chip-lighting-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tv-casting-app apps/chip-tv-casting-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tv-app apps/chip-tv-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-bridge-app apps/chip-bridge-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/thermostat-app apps/thermostat-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-ota-provider-app apps/chip-ota-provider-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-ota-requestor-app apps/chip-ota-requestor-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lock-app apps/chip-lock-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-app1 apps/chip-app1 +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/lit-icd-app apps/lit-icd-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-energy-management-app apps/chip-energy-management-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-microwave-oven-app apps/chip-microwave-oven-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-rvc-app apps/chip-rvc-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/examples/fabric-admin/scripts/fabric-sync-app.py apps/fabric-sync-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/fabric-bridge-app apps/fabric-bridge-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/fabric-admin apps/fabric-admin +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lighting-data-model-no-unique-id-app apps/chip-lighting-data-model-no-unique-id-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/matter-network-manager-app apps/matter-network-manager-app + +# Create symbolic links for now since this allows users to use existing configurations +# for running just `app-name` instead of `apps/app-name` +RUN ln -s apps/* . + # Stage 3.1: Setup the Matter Python environment COPY --from=chip-build-cert-bins /root/connectedhomeip/out/python_lib python_lib diff --git a/src/BUILD.gn b/src/BUILD.gn index 722e0c8278582a..3676c92c97e8a4 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -100,7 +100,10 @@ if (chip_build_tests) { } if (chip_device_platform != "efr32") { - tests += [ "${chip_root}/src/app/tests" ] + tests += [ + "${chip_root}/src/app/tests", + "${chip_root}/src/app/util/persistence/tests", + ] # Disabled for EFR32 because _open is not implemented. # https://github.com/project-chip/connectedhomeip/issues/35624 diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index b0cde0960c9013..8b008c4e9b238b 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -389,6 +389,18 @@ source_set("command-handler-impl") { ] } +source_set("attribute-persistence") { + sources = [ "SafeAttributePersistenceProvider.h" ] + + public_deps = [ + ":paths", + "${chip_root}/src/app/data-model:nullable", + "${chip_root}/src/app/util:types", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:span", + ] +} + # Note to developpers, instead of continuously adding files in the app librabry, it is recommand to create smaller source_sets that app can depend on. # This way, we can have a better understanding of dependencies and other componenets can depend on the different source_sets without needing to depend on the entire app library. static_library("app") { @@ -398,15 +410,10 @@ static_library("app") { "AttributePathExpandIterator.cpp", "AttributePathExpandIterator.h", "AttributePathExpandIterator.h", - "AttributePersistenceProvider.h", "ChunkedWriteCallback.cpp", "ChunkedWriteCallback.h", "CommandResponseHelper.h", "CommandResponseSender.cpp", - "DefaultAttributePersistenceProvider.cpp", - "DefaultAttributePersistenceProvider.h", - "DeferredAttributePersistenceProvider.cpp", - "DeferredAttributePersistenceProvider.h", "EventLogging.h", "EventManagement.cpp", "EventManagement.h", @@ -416,7 +423,6 @@ static_library("app") { "GenericEventManagementTestEventTriggerHandler.h", "OTAUserConsentCommon.h", "ReadHandler.cpp", - "SafeAttributePersistenceProvider.h", "TimerDelegates.cpp", "TimerDelegates.h", "WriteHandler.cpp", diff --git a/src/app/SafeAttributePersistenceProvider.h b/src/app/SafeAttributePersistenceProvider.h index 8d11d95d47b02d..b1e7148c79b1bb 100644 --- a/src/app/SafeAttributePersistenceProvider.h +++ b/src/app/SafeAttributePersistenceProvider.h @@ -18,12 +18,13 @@ #include #include #include -#include -#include #include #include #include +#include +#include + namespace chip { namespace app { diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index 75e2d8a349668a..0f628428952da8 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -164,6 +164,7 @@ function(chip_configure_data_model APP_TARGET) ${CHIP_APP_BASE_DIR}/util/generic-callback-stubs.cpp ${CHIP_APP_BASE_DIR}/util/privilege-storage.cpp ${CHIP_APP_BASE_DIR}/util/util.cpp + ${CHIP_APP_BASE_DIR}/util/persistence/DefaultAttributePersistenceProvider.cpp ${CODEGEN_DATA_MODEL_SOURCES} ${APP_GEN_FILES} ${APP_TEMPLATES_GEN_FILES} diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 9f4ed594ccb912..3be8df5710616c 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -460,6 +460,7 @@ template("chip_data_model") { "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/common:enums", "${chip_root}/src/app/util:types", + "${chip_root}/src/app/util/persistence", "${chip_root}/src/controller", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", diff --git a/src/app/clusters/mode-base-server/mode-base-server.h b/src/app/clusters/mode-base-server/mode-base-server.h index f787e9fc19f11f..06c22f3a42cd3e 100644 --- a/src/app/clusters/mode-base-server/mode-base-server.h +++ b/src/app/clusters/mode-base-server/mode-base-server.h @@ -20,8 +20,8 @@ #include "mode-base-cluster-objects.h" #include -#include #include +#include #include namespace chip { diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index bda97c5cb1f22f..a1f0d27779571f 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -220,6 +220,292 @@ int16_t EnforceCoolingSetpointLimits(int16_t CoolingSetpoint, EndpointId endpoin return CoolingSetpoint; } +struct SetpointLimits +{ + bool autoSupported = false; + bool heatSupported = false; + bool coolSupported = false; + bool occupancySupported = false; + + int16_t absMinHeatSetpointLimit; + int16_t absMaxHeatSetpointLimit; + int16_t minHeatSetpointLimit; + int16_t maxHeatSetpointLimit; + int16_t absMinCoolSetpointLimit; + int16_t absMaxCoolSetpointLimit; + int16_t minCoolSetpointLimit; + int16_t maxCoolSetpointLimit; + int16_t deadBand = 0; + int16_t occupiedCoolingSetpoint; + int16_t occupiedHeatingSetpoint; + int16_t unoccupiedCoolingSetpoint; + int16_t unoccupiedHeatingSetpoint; +}; + +/** + * @brief Reads all the attributes for enforcing setpoint limits + * + * @param endpoint The endpoint for the server whose limits are being enforced + * @param setpointLimits The SetpointLimits to populate + * @return Success if the limits were read completely, otherwise an error code + */ +Status GetSetpointLimits(EndpointId endpoint, SetpointLimits & setpointLimits) +{ + uint32_t flags; + if (FeatureMap::Get(endpoint, &flags) != Status::Success) + { + ChipLogError(Zcl, "GetSetpointLimits: could not get feature flags"); + flags = FEATURE_MAP_DEFAULT; + } + + auto featureMap = BitMask(flags); + setpointLimits.autoSupported = featureMap.Has(Feature::kAutoMode); + setpointLimits.heatSupported = featureMap.Has(Feature::kHeating); + setpointLimits.coolSupported = featureMap.Has(Feature::kCooling); + setpointLimits.occupancySupported = featureMap.Has(Feature::kOccupancy); + + if (setpointLimits.autoSupported) + { + int8_t deadBand; + if (MinSetpointDeadBand::Get(endpoint, &deadBand) != Status::Success) + { + deadBand = kDefaultDeadBand; + } + setpointLimits.deadBand = static_cast(deadBand * 10); + } + + if (AbsMinCoolSetpointLimit::Get(endpoint, &setpointLimits.absMinCoolSetpointLimit) != Status::Success) + setpointLimits.absMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; + + if (AbsMaxCoolSetpointLimit::Get(endpoint, &setpointLimits.absMaxCoolSetpointLimit) != Status::Success) + setpointLimits.absMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + + if (MinCoolSetpointLimit::Get(endpoint, &setpointLimits.minCoolSetpointLimit) != Status::Success) + setpointLimits.minCoolSetpointLimit = setpointLimits.absMinCoolSetpointLimit; + + if (MaxCoolSetpointLimit::Get(endpoint, &setpointLimits.maxCoolSetpointLimit) != Status::Success) + setpointLimits.maxCoolSetpointLimit = setpointLimits.absMaxCoolSetpointLimit; + + if (AbsMinHeatSetpointLimit::Get(endpoint, &setpointLimits.absMinHeatSetpointLimit) != Status::Success) + setpointLimits.absMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + + if (AbsMaxHeatSetpointLimit::Get(endpoint, &setpointLimits.absMaxHeatSetpointLimit) != Status::Success) + setpointLimits.absMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + + if (MinHeatSetpointLimit::Get(endpoint, &setpointLimits.minHeatSetpointLimit) != Status::Success) + setpointLimits.minHeatSetpointLimit = setpointLimits.absMinHeatSetpointLimit; + + if (MaxHeatSetpointLimit::Get(endpoint, &setpointLimits.maxHeatSetpointLimit) != Status::Success) + setpointLimits.maxHeatSetpointLimit = setpointLimits.absMaxHeatSetpointLimit; + + if (setpointLimits.coolSupported) + { + if (OccupiedCoolingSetpoint::Get(endpoint, &setpointLimits.occupiedCoolingSetpoint) != Status::Success) + { + // We're substituting the failure code here for backwards-compatibility reasons + ChipLogError(Zcl, "Error: Can not read Occupied Cooling Setpoint"); + return Status::Failure; + } + } + + if (setpointLimits.heatSupported) + { + if (OccupiedHeatingSetpoint::Get(endpoint, &setpointLimits.occupiedHeatingSetpoint) != Status::Success) + { + // We're substituting the failure code here for backwards-compatibility reasons + ChipLogError(Zcl, "Error: Can not read Occupied Heating Setpoint"); + return Status::Failure; + } + } + + if (setpointLimits.coolSupported && setpointLimits.occupancySupported) + { + if (UnoccupiedCoolingSetpoint::Get(endpoint, &setpointLimits.unoccupiedCoolingSetpoint) != Status::Success) + { + // We're substituting the failure code here for backwards-compatibility reasons + ChipLogError(Zcl, "Error: Can not read Unoccupied Cooling Setpoint"); + return Status::Failure; + } + } + + if (setpointLimits.heatSupported && setpointLimits.occupancySupported) + { + if (UnoccupiedHeatingSetpoint::Get(endpoint, &setpointLimits.unoccupiedHeatingSetpoint) != Status::Success) + { + // We're substituting the failure code here for backwards-compatibility reasons + ChipLogError(Zcl, "Error: Can not read Unoccupied Heating Setpoint"); + return Status::Failure; + } + } + return Status::Success; +} + +/** + * @brief Checks to see if it's possible to adjust the heating setpoint to preserve a given deadband + * if the cooling setpoint is changed + * + * @param autoSupported Whether or not the thermostat supports Auto mode + * @param newCoolingSetpoing The desired cooling setpoint + * @param minHeatingSetpoint The minimum allowed heating setpoint + * @param deadband The deadband to preserve + * @return Success if the deadband can be preserved, InvalidValue if it cannot + */ +Status CheckHeatingSetpointDeadband(bool autoSupported, int16_t newCoolingSetpoint, int16_t minHeatingSetpoint, int16_t deadband) +{ + if (!autoSupported) + { + return Status::Success; + } + int16_t maxValidHeatingSetpoint = static_cast(newCoolingSetpoint - deadband); + if (maxValidHeatingSetpoint < minHeatingSetpoint) + { + // If we need to adjust the heating setpoint to preserve the deadband, it will go below the min heat setpoint + return Status::InvalidValue; + } + // It's possible to adjust the heating setpoint, if needed + return Status::Success; +} + +/** + * @brief Checks to see if it's possible to adjust the cooling setpoint to preserve a given deadband + * if the heating setpoint is changed + * + * @param autoSupported Whether or not the thermostat supports Auto mode + * @param newHeatingSetpoint The desired heating setpoint + * @param maxCoolingSetpoint The maximum allowed cooling setpoint + * @param deadband The deadband to preserve + * @return Success if the deadband can be preserved, InvalidValue if it cannot + */ +Status CheckCoolingSetpointDeadband(bool autoSupported, int16_t newHeatingSetpoint, int16_t maxCoolingSetpoint, int16_t deadband) +{ + if (!autoSupported) + { + return Status::Success; + } + int16_t minValidCoolingSetpoint = static_cast(newHeatingSetpoint + deadband); + if (minValidCoolingSetpoint > maxCoolingSetpoint) + { + // If we need to adjust the cooling setpoint to preserve the deadband, it will go above the max cool setpoint + return Status::InvalidValue; + } + // It's possible to adjust the cooling setpoint, if needed + return Status::Success; +} + +typedef Status (*SetpointSetter)(EndpointId endpoint, int16_t value); + +/** + * @brief Attempts to ensure that a change to the heating setpoint maintains the deadband with the cooling setpoint + * by adjusting the cooling setpoint + * + * @param endpoint The endpoint on which the heating setpoint has been changed + * @param currentCoolingSetpoint The current cooling setpoint + * @param newHeatingSetpoint The newly adjusted heating setpoint + * @param maxCoolingSetpoint The maximum allowed cooling setpoint + * @param deadband The deadband to preserve + * @param setter A function for setting the cooling setpoint + */ +void EnsureCoolingSetpointDeadband(EndpointId endpoint, int16_t currentCoolingSetpoint, int16_t newHeatingSetpoint, + int16_t maxCoolingSetpoint, int16_t deadband, SetpointSetter setter) +{ + int16_t minValidCoolingSetpoint = static_cast(newHeatingSetpoint + deadband); + if (currentCoolingSetpoint >= minValidCoolingSetpoint) + { + // The current cooling setpoint doesn't violate the deadband + return; + } + if (minValidCoolingSetpoint > maxCoolingSetpoint) + { + // Adjusting the cool setpoint to preserve the deadband would violate the max cool setpoint + // This should have been caught in CheckCoolingSetpointDeadband, so log and exit + ChipLogError(Zcl, "Failed ensuring cooling setpoint deadband"); + return; + } + // Adjust the cool setpoint to preserve deadband + auto status = setter(endpoint, minValidCoolingSetpoint); + if (status != Status::Success) + { + ChipLogError(Zcl, "Error: EnsureCoolingSetpointDeadband failed!"); + } +} + +/** + * @brief Attempts to ensure that a change to the cooling setpoint maintains the deadband with the heating setpoint + * by adjusting the heating setpoint + * + * @param endpoint The endpoint on which the cooling setpoint has been changed + * @param currentHeatingSetpointThe current heating setpoint + * @param newCoolingSetpoint The newly adjusted cooling setpoint + * @param minHeatingSetpoint The minimum allowed cooling setpoint + * @param deadband The deadband to preserve + * @param setter A function for setting the heating setpoint + */ +void EnsureHeatingSetpointDeadband(EndpointId endpoint, int16_t currentHeatingSetpoint, int16_t newCoolingSetpoint, + int16_t minHeatingSetpoint, int16_t deadband, SetpointSetter setter) +{ + int16_t maxValidHeatingSetpoint = static_cast(newCoolingSetpoint - deadband); + if (currentHeatingSetpoint <= maxValidHeatingSetpoint) + { + // The current heating setpoint doesn't violate the deadband + return; + } + if (maxValidHeatingSetpoint < minHeatingSetpoint) + { + // Adjusting the heating setpoint to preserve the deadband would violate the min heating setpoint + // This should have been caught in CheckHeatingSetpointDeadband, so log and exit + ChipLogError(Zcl, "Failed ensuring heating setpoint deadband"); + return; + } + // Adjust the heating setpoint to preserve deadband + auto status = setter(endpoint, maxValidHeatingSetpoint); + if (status != Status::Success) + { + ChipLogError(Zcl, "Error: EnsureHeatingSetpointDeadband failed!"); + } +} + +/** + * @brief For thermostats that support auto, shift setpoints to maintain the current deadband + * Note: this assumes that the shift is possible; setpoint changes which prevent the deadband + * from being maintained due to the min/max limits for setpoints should be rejected by + * MatterThermostatClusterServerPreAttributeChangedCallback + * + * @param attributePath + */ +void EnsureDeadband(const ConcreteAttributePath & attributePath) +{ + auto endpoint = attributePath.mEndpointId; + SetpointLimits setpointLimits; + auto status = GetSetpointLimits(endpoint, setpointLimits); + if (status != Status::Success) + { + return; + } + if (!setpointLimits.autoSupported) + { + return; + } + switch (attributePath.mAttributeId) + { + case OccupiedHeatingSetpoint::Id: + EnsureCoolingSetpointDeadband(endpoint, setpointLimits.occupiedCoolingSetpoint, setpointLimits.occupiedHeatingSetpoint, + setpointLimits.maxCoolSetpointLimit, setpointLimits.deadBand, OccupiedCoolingSetpoint::Set); + break; + case OccupiedCoolingSetpoint::Id: + EnsureHeatingSetpointDeadband(endpoint, setpointLimits.occupiedHeatingSetpoint, setpointLimits.occupiedCoolingSetpoint, + setpointLimits.minHeatSetpointLimit, setpointLimits.deadBand, OccupiedHeatingSetpoint::Set); + break; + case UnoccupiedHeatingSetpoint::Id: + EnsureCoolingSetpointDeadband(endpoint, setpointLimits.unoccupiedCoolingSetpoint, setpointLimits.unoccupiedHeatingSetpoint, + setpointLimits.maxCoolSetpointLimit, setpointLimits.deadBand, UnoccupiedCoolingSetpoint::Set); + break; + case UnoccupiedCoolingSetpoint::Id: + EnsureHeatingSetpointDeadband(endpoint, setpointLimits.unoccupiedHeatingSetpoint, setpointLimits.unoccupiedCoolingSetpoint, + setpointLimits.minHeatSetpointLimit, setpointLimits.deadBand, UnoccupiedHeatingSetpoint::Set); + break; + } +} + Delegate * GetDelegate(EndpointId endpoint) { uint16_t ep = @@ -477,14 +763,9 @@ void MatterThermostatClusterServerAttributeChangedCallback(const ConcreteAttribu return; } - auto featureMap = BitMask(flags); - if (!featureMap.Has(Feature::kPresets)) - { - // This server does not support presets, so nothing to do - return; - } - - bool occupied = true; + auto featureMap = BitMask(flags); + bool supportsPresets = featureMap.Has(Feature::kPresets); + bool occupied = true; if (featureMap.Has(Feature::kOccupancy)) { BitMask occupancy; @@ -499,19 +780,20 @@ void MatterThermostatClusterServerAttributeChangedCallback(const ConcreteAttribu { case OccupiedHeatingSetpoint::Id: case OccupiedCoolingSetpoint::Id: - clearActivePreset = occupied; + clearActivePreset = supportsPresets && occupied; + EnsureDeadband(attributePath); break; case UnoccupiedHeatingSetpoint::Id: case UnoccupiedCoolingSetpoint::Id: - clearActivePreset = !occupied; + clearActivePreset = supportsPresets && !occupied; + EnsureDeadband(attributePath); break; } - if (!clearActivePreset) + if (clearActivePreset) { - return; + ChipLogProgress(Zcl, "Setting active preset to null"); + gThermostatAttrAccess.SetActivePreset(attributePath.mEndpointId, std::nullopt); } - ChipLogProgress(Zcl, "Setting active preset to null"); - gThermostatAttrAccess.SetActivePreset(attributePath.mEndpointId, std::nullopt); } } // namespace Thermostat @@ -535,15 +817,15 @@ void emberAfThermostatClusterServerInitCallback(chip::EndpointId endpoint) // or should this just be the responsibility of the thermostat application? } -Protocols::InteractionModel::Status -MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttributePath & attributePath, - EmberAfAttributeType attributeType, uint16_t size, uint8_t * value) +Status MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value) { EndpointId endpoint = attributePath.mEndpointId; int16_t requested; // Limits will be needed for all checks // so we just get them all now + // TODO: use GetSetpointLimits to fetch this information int16_t AbsMinHeatSetpointLimit; int16_t AbsMaxHeatSetpointLimit; int16_t MinHeatSetpointLimit; @@ -649,12 +931,8 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit || requested > MaxHeatSetpointLimit) return Status::InvalidValue; - if (AutoSupported) - { - if (requested > OccupiedCoolingSetpoint - DeadBandTemp) - return Status::InvalidValue; - } - return Status::Success; + return CheckCoolingSetpointDeadband(AutoSupported, requested, std::min(MaxCoolSetpointLimit, AbsMaxCoolSetpointLimit), + DeadBandTemp); } case OccupiedCoolingSetpoint::Id: { @@ -664,12 +942,8 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit || requested > MaxCoolSetpointLimit) return Status::InvalidValue; - if (AutoSupported) - { - if (requested < OccupiedHeatingSetpoint + DeadBandTemp) - return Status::InvalidValue; - } - return Status::Success; + return CheckHeatingSetpointDeadband(AutoSupported, requested, std::max(MinHeatSetpointLimit, AbsMinHeatSetpointLimit), + DeadBandTemp); } case UnoccupiedHeatingSetpoint::Id: { @@ -679,12 +953,8 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit || requested > MaxHeatSetpointLimit) return Status::InvalidValue; - if (AutoSupported) - { - if (requested > UnoccupiedCoolingSetpoint - DeadBandTemp) - return Status::InvalidValue; - } - return Status::Success; + return CheckCoolingSetpointDeadband(AutoSupported, requested, std::min(MaxCoolSetpointLimit, AbsMaxCoolSetpointLimit), + DeadBandTemp); } case UnoccupiedCoolingSetpoint::Id: { requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); @@ -693,12 +963,8 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit || requested > MaxCoolSetpointLimit) return Status::InvalidValue; - if (AutoSupported) - { - if (requested < UnoccupiedHeatingSetpoint + DeadBandTemp) - return Status::InvalidValue; - } - return Status::Success; + return CheckHeatingSetpointDeadband(AutoSupported, requested, std::max(MinHeatSetpointLimit, AbsMinHeatSetpointLimit), + DeadBandTemp); } case MinHeatSetpointLimit::Id: { diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index 2a1bc6a5d4fb86..242b81ef24a562 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -542,5 +542,14 @@ CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & paylo iterator->Release(); return CHIP_ERROR_NOT_FOUND; } + +void DefaultICDClientStorage::Shutdown() +{ + mICDClientInfoIterators.ReleaseAll(); + mpClientInfoStore = nullptr; + mpKeyStore = nullptr; + mFabricList.clear(); +} + } // namespace app } // namespace chip diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h index 13064fe649c61b..09431b701460c7 100644 --- a/src/app/icd/client/DefaultICDClientStorage.h +++ b/src/app/icd/client/DefaultICDClientStorage.h @@ -120,6 +120,12 @@ class DefaultICDClientStorage : public ICDClientStorage CHIP_ERROR ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo, Protocols::SecureChannel::CounterType & counter) override; + /** + * Shut down DefaultICDClientStorage + * + */ + void Shutdown(); + #if CONFIG_BUILD_FOR_HOST_UNIT_TEST size_t GetFabricListSize() { return mFabricList.size(); } diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 42c4caf05cad78..43c970843ba66d 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -58,6 +58,7 @@ static_library("server") { "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/app/icd/server:icd-server-config", "${chip_root}/src/app/icd/server:observer", + "${chip_root}/src/app/util/persistence", "${chip_root}/src/lib/address_resolve", "${chip_root}/src/lib/dnssd", "${chip_root}/src/lib/dnssd:naming", diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 2f61197fcee2dd..fc6f7ac10750d3 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -81,6 +80,11 @@ #endif // CHIP_CONFIG_ENABLE_ICD_CIP #endif // CHIP_CONFIG_ENABLE_ICD_SERVER +// TODO: https://github.com/project-chip/connectedhomeip/issues/36472 +// this strongly couples Server to Ember and this dependency should +// be removed +#include + namespace chip { inline constexpr size_t kMaxBlePendingPackets = 1; diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 6f55c7bb6fafd1..105d09f7ad6fc8 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -198,7 +198,6 @@ chip_test_suite("tests") { "TestAttributeAccessInterfaceCache.cpp", "TestAttributePathExpandIterator.cpp", "TestAttributePathParams.cpp", - "TestAttributePersistenceProvider.cpp", "TestAttributeValueDecoder.cpp", "TestAttributeValueEncoder.cpp", "TestBasicCommandPathRegistry.cpp", diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index 51c01c7e43fa80..4d9cc2368f6900 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/src/app/AttributePersistenceProvider.h b/src/app/util/persistence/AttributePersistenceProvider.h similarity index 100% rename from src/app/AttributePersistenceProvider.h rename to src/app/util/persistence/AttributePersistenceProvider.h diff --git a/src/app/util/persistence/BUILD.gn b/src/app/util/persistence/BUILD.gn new file mode 100644 index 00000000000000..dbc8dbe31b0c58 --- /dev/null +++ b/src/app/util/persistence/BUILD.gn @@ -0,0 +1,47 @@ +# 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/chip.gni") + +source_set("persistence") { + sources = [ + "AttributePersistenceProvider.h", + "DefaultAttributePersistenceProvider.cpp", + "DefaultAttributePersistenceProvider.h", + ] + + public_deps = [ + "${chip_root}/src/app:attribute-persistence", + "${chip_root}/src/app:paths", + "${chip_root}/src/app/util:types", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:span", + ] +} + +source_set("deferred") { + sources = [ + "DeferredAttributePersistenceProvider.cpp", + "DeferredAttributePersistenceProvider.h", + ] + + public_deps = [ + ":persistence", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:span", + "${chip_root}/src/platform", + "${chip_root}/src/system", + ] +} diff --git a/src/app/DefaultAttributePersistenceProvider.cpp b/src/app/util/persistence/DefaultAttributePersistenceProvider.cpp similarity index 98% rename from src/app/DefaultAttributePersistenceProvider.cpp rename to src/app/util/persistence/DefaultAttributePersistenceProvider.cpp index 40ce5213628944..70488e80e7e1d7 100644 --- a/src/app/DefaultAttributePersistenceProvider.cpp +++ b/src/app/util/persistence/DefaultAttributePersistenceProvider.cpp @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include -#include #include #include #include diff --git a/src/app/DefaultAttributePersistenceProvider.h b/src/app/util/persistence/DefaultAttributePersistenceProvider.h similarity index 97% rename from src/app/DefaultAttributePersistenceProvider.h rename to src/app/util/persistence/DefaultAttributePersistenceProvider.h index 3e18808f366d37..a4796f2b63b11d 100644 --- a/src/app/DefaultAttributePersistenceProvider.h +++ b/src/app/util/persistence/DefaultAttributePersistenceProvider.h @@ -15,8 +15,8 @@ */ #pragma once -#include #include +#include #include #include diff --git a/src/app/DeferredAttributePersistenceProvider.cpp b/src/app/util/persistence/DeferredAttributePersistenceProvider.cpp similarity index 97% rename from src/app/DeferredAttributePersistenceProvider.cpp rename to src/app/util/persistence/DeferredAttributePersistenceProvider.cpp index 26adcb18c8dcf7..6b1822f29257ac 100644 --- a/src/app/DeferredAttributePersistenceProvider.cpp +++ b/src/app/util/persistence/DeferredAttributePersistenceProvider.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include diff --git a/src/app/DeferredAttributePersistenceProvider.h b/src/app/util/persistence/DeferredAttributePersistenceProvider.h similarity index 98% rename from src/app/DeferredAttributePersistenceProvider.h rename to src/app/util/persistence/DeferredAttributePersistenceProvider.h index 6c641dc17d4400..592408b96b39ac 100644 --- a/src/app/DeferredAttributePersistenceProvider.h +++ b/src/app/util/persistence/DeferredAttributePersistenceProvider.h @@ -15,7 +15,7 @@ */ #pragma once -#include +#include #include #include #include diff --git a/examples/platform/silabs/efr32/wf200/wf200.gni b/src/app/util/persistence/tests/BUILD.gn similarity index 54% rename from examples/platform/silabs/efr32/wf200/wf200.gni rename to src/app/util/persistence/tests/BUILD.gn index c7ebbb8647788c..7a0bd524305623 100644 --- a/examples/platform/silabs/efr32/wf200/wf200.gni +++ b/src/app/util/persistence/tests/BUILD.gn @@ -12,19 +12,23 @@ # 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/efr32_sdk.gni") -import("${silabs_sdk_build_root}/efr32_sdk.gni") +import("//build_overrides/pigweed.gni") -wf200_plat_incs = [ - "${examples_plat_dir}/wf200", - "${silabs_common_plat_dir}/wifi", -] +import("${chip_root}/build/chip/chip_test_suite.gni") -wf200_plat_src = [ - "${examples_plat_dir}/wf200/sl_wfx_task.c", - "${examples_plat_dir}/wf200/wf200_init.c", - "${examples_plat_dir}/wf200/efr_spi.c", - "${examples_plat_dir}/wf200/Wf200WifiInterface.cpp", - "${silabs_common_plat_dir}/wifi/WifiInterfaceAbstraction.cpp", -] +chip_test_suite("tests") { + output_name = "libAppUtilPersistenceTests" + + test_sources = [ "TestAttributePersistenceProvider.cpp" ] + + cflags = [ "-Wconversion" ] + + public_deps = [ + "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/util/persistence", + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/support:testing", + ] +} diff --git a/src/app/tests/TestAttributePersistenceProvider.cpp b/src/app/util/persistence/tests/TestAttributePersistenceProvider.cpp similarity index 99% rename from src/app/tests/TestAttributePersistenceProvider.cpp rename to src/app/util/persistence/tests/TestAttributePersistenceProvider.cpp index 1b8c7ee3d3872c..1324f37a7138c3 100644 --- a/src/app/tests/TestAttributePersistenceProvider.cpp +++ b/src/app/util/persistence/tests/TestAttributePersistenceProvider.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include diff --git a/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml index 24c66bcc7a7a9c..516fe8753a3ef8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml @@ -18,7 +18,7 @@ limitations under the License. XML generated by Alchemy; DO NOT EDIT. Source: src/app_clusters/CameraAVStreamManagement.adoc Parameters: in-progress -Git: 1.3-3824-g29c49ca54 +Git: 1.3-3830-g1f08d6f40 --> @@ -239,62 +239,48 @@ Git: 1.3-3824-g29c49ca54 - - CurrentVideoCodecs - - - - - - CurrentSnapshotConfig - - - - - FabricsUsingCamera - + FabricsUsingCamera + AllocatedVideoStreams - + AllocatedAudioStreams - + AllocatedSnapshotStreams - + RankedVideoStreamPrioritiesList - - - + SoftRecordingPrivacyModeEnabled - + SoftLivestreamPrivacyModeEnabled - + HardPrivacyModeOn - + NightVision @@ -305,7 +291,7 @@ Git: 1.3-3824-g29c49ca54 - + NightVisionIllum @@ -316,7 +302,7 @@ Git: 1.3-3824-g29c49ca54 - + Viewport @@ -324,7 +310,7 @@ Git: 1.3-3824-g29c49ca54 - + SpeakerMuted @@ -335,7 +321,7 @@ Git: 1.3-3824-g29c49ca54 - + SpeakerVolumeLevel @@ -346,7 +332,7 @@ Git: 1.3-3824-g29c49ca54 - + SpeakerMaxLevel @@ -356,7 +342,7 @@ Git: 1.3-3824-g29c49ca54 - + SpeakerMinLevel @@ -366,7 +352,7 @@ Git: 1.3-3824-g29c49ca54 - + MicrophoneMuted @@ -374,7 +360,7 @@ Git: 1.3-3824-g29c49ca54 - + MicrophoneVolumeLevel @@ -382,21 +368,21 @@ Git: 1.3-3824-g29c49ca54 - + MicrophoneMaxLevel - + MicrophoneMinLevel - + MicrophoneAGCEnabled @@ -404,7 +390,7 @@ Git: 1.3-3824-g29c49ca54 - + ImageRotation @@ -412,7 +398,7 @@ Git: 1.3-3824-g29c49ca54 - + ImageFlipHorizontal @@ -420,7 +406,7 @@ Git: 1.3-3824-g29c49ca54 - + ImageFlipVertical @@ -428,7 +414,7 @@ Git: 1.3-3824-g29c49ca54 - + LocalVideoRecordingEnabled @@ -439,7 +425,7 @@ Git: 1.3-3824-g29c49ca54 - + LocalSnapshotRecordingEnabled @@ -450,13 +436,13 @@ Git: 1.3-3824-g29c49ca54 - + StatusLightEnabled - + StatusLightBrightness @@ -546,7 +532,7 @@ Git: 1.3-3824-g29c49ca54 This command SHALL allocate a snapshot stream on the device and return an allocated snapshot stream identifier. - + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 39301cdc30cecc..0912be1df2db37 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -677,7 +677,6 @@ "MinViewport", "MicrophoneCapabilities", "SpeakerCapabilities", - "CurrentSnapshotConfig", "Viewport" ] }, diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index c2de6acabf2951..3a62c4c84ca6eb 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -671,7 +671,6 @@ "MinViewport", "MicrophoneCapabilities", "SpeakerCapabilities", - "CurrentSnapshotConfig", "Viewport" ] }, diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 95f102ce08c545..31da395b05cd31 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9705,35 +9705,33 @@ provisional cluster CameraAvStreamManagement = 1361 { readonly attribute int32u maxNetworkBandwidth = 11; readonly attribute optional int16u currentFrameRate = 12; attribute access(read: manage, write: manage) optional boolean HDRModeEnabled = 13; - readonly attribute optional VideoCodecEnum currentVideoCodecs[] = 14; - readonly attribute optional SnapshotParamsStruct currentSnapshotConfig = 15; - readonly attribute fabric_idx fabricsUsingCamera[] = 16; - readonly attribute optional VideoStreamStruct allocatedVideoStreams[] = 17; - readonly attribute optional AudioStreamStruct allocatedAudioStreams[] = 18; - readonly attribute optional SnapshotStreamStruct allocatedSnapshotStreams[] = 19; - attribute access(read: administer, write: administer) optional StreamTypeEnum rankedVideoStreamPrioritiesList[] = 20; - attribute optional boolean softRecordingPrivacyModeEnabled = 21; - attribute optional boolean softLivestreamPrivacyModeEnabled = 22; - readonly attribute optional boolean hardPrivacyModeOn = 23; - attribute access(read: manage, write: manage) optional TriStateAutoEnum nightVision = 24; - attribute access(read: manage, write: manage) optional TriStateAutoEnum nightVisionIllum = 25; - attribute access(read: manage, write: manage) optional ViewportStruct viewport = 26; - attribute access(read: manage, write: manage) optional boolean speakerMuted = 27; - attribute access(read: manage, write: manage) optional int8u speakerVolumeLevel = 28; - readonly attribute access(read: manage) optional int8u speakerMaxLevel = 29; - readonly attribute access(read: manage) optional int8u speakerMinLevel = 30; - attribute access(read: manage, write: manage) optional boolean microphoneMuted = 31; - attribute access(read: manage, write: manage) optional int8u microphoneVolumeLevel = 32; - readonly attribute access(read: manage) optional int8u microphoneMaxLevel = 33; - readonly attribute access(read: manage) optional int8u microphoneMinLevel = 34; - attribute access(read: manage, write: manage) optional boolean microphoneAGCEnabled = 35; - attribute access(read: manage, write: manage) optional int16u imageRotation = 36; - attribute access(read: manage, write: manage) optional boolean imageFlipHorizontal = 37; - attribute access(read: manage, write: manage) optional boolean imageFlipVertical = 38; - attribute access(read: manage, write: manage) optional boolean localVideoRecordingEnabled = 39; - attribute access(read: manage, write: manage) optional boolean localSnapshotRecordingEnabled = 40; - attribute access(read: manage, write: manage) optional boolean statusLightEnabled = 41; - attribute access(read: manage, write: manage) optional ThreeLevelAutoEnum statusLightBrightness = 42; + readonly attribute fabric_idx fabricsUsingCamera[] = 14; + readonly attribute optional VideoStreamStruct allocatedVideoStreams[] = 15; + readonly attribute optional AudioStreamStruct allocatedAudioStreams[] = 16; + readonly attribute optional SnapshotStreamStruct allocatedSnapshotStreams[] = 17; + readonly attribute optional StreamTypeEnum rankedVideoStreamPrioritiesList[] = 18; + attribute optional boolean softRecordingPrivacyModeEnabled = 19; + attribute optional boolean softLivestreamPrivacyModeEnabled = 20; + readonly attribute optional boolean hardPrivacyModeOn = 21; + attribute access(read: manage, write: manage) optional TriStateAutoEnum nightVision = 22; + attribute access(read: manage, write: manage) optional TriStateAutoEnum nightVisionIllum = 23; + attribute access(read: manage, write: manage) optional ViewportStruct viewport = 24; + attribute access(read: manage, write: manage) optional boolean speakerMuted = 25; + attribute access(read: manage, write: manage) optional int8u speakerVolumeLevel = 26; + readonly attribute access(read: manage) optional int8u speakerMaxLevel = 27; + readonly attribute access(read: manage) optional int8u speakerMinLevel = 28; + attribute access(read: manage, write: manage) optional boolean microphoneMuted = 29; + attribute access(read: manage, write: manage) optional int8u microphoneVolumeLevel = 30; + readonly attribute access(read: manage) optional int8u microphoneMaxLevel = 31; + readonly attribute access(read: manage) optional int8u microphoneMinLevel = 32; + attribute access(read: manage, write: manage) optional boolean microphoneAGCEnabled = 33; + attribute access(read: manage, write: manage) optional int16u imageRotation = 34; + attribute access(read: manage, write: manage) optional boolean imageFlipHorizontal = 35; + attribute access(read: manage, write: manage) optional boolean imageFlipVertical = 36; + attribute access(read: manage, write: manage) optional boolean localVideoRecordingEnabled = 37; + attribute access(read: manage, write: manage) optional boolean localSnapshotRecordingEnabled = 38; + attribute access(read: manage, write: manage) optional boolean statusLightEnabled = 39; + attribute access(read: manage, write: manage) optional ThreeLevelAutoEnum statusLightBrightness = 40; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -9790,7 +9788,7 @@ provisional cluster CameraAvStreamManagement = 1361 { request struct SnapshotStreamAllocateRequest { ImageCodecEnum imageCodec = 0; - int16u frameRate = 1; + int16u maxFrameRate = 1; int32u bitRate = 2; VideoResolutionStruct minResolution = 3; VideoResolutionStruct maxResolution = 4; diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 7f821fefc0c9ac..3eb6dd82e459cd 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -50,6 +50,7 @@ using namespace TLV; AndroidDeviceControllerWrapper::~AndroidDeviceControllerWrapper() { + getICDClientStorage()->Shutdown(); mController->Shutdown(); if (mKeypairBridge != nullptr) diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index a37be0ed915865..228e0236ed0785 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -59738,35 +59738,33 @@ public static class CameraAvStreamManagementCluster extends BaseChipCluster { private static final long MAX_NETWORK_BANDWIDTH_ATTRIBUTE_ID = 11L; private static final long CURRENT_FRAME_RATE_ATTRIBUTE_ID = 12L; private static final long HDR_MODE_ENABLED_ATTRIBUTE_ID = 13L; - private static final long CURRENT_VIDEO_CODECS_ATTRIBUTE_ID = 14L; - private static final long CURRENT_SNAPSHOT_CONFIG_ATTRIBUTE_ID = 15L; - private static final long FABRICS_USING_CAMERA_ATTRIBUTE_ID = 16L; - private static final long ALLOCATED_VIDEO_STREAMS_ATTRIBUTE_ID = 17L; - private static final long ALLOCATED_AUDIO_STREAMS_ATTRIBUTE_ID = 18L; - private static final long ALLOCATED_SNAPSHOT_STREAMS_ATTRIBUTE_ID = 19L; - private static final long RANKED_VIDEO_STREAM_PRIORITIES_LIST_ATTRIBUTE_ID = 20L; - private static final long SOFT_RECORDING_PRIVACY_MODE_ENABLED_ATTRIBUTE_ID = 21L; - private static final long SOFT_LIVESTREAM_PRIVACY_MODE_ENABLED_ATTRIBUTE_ID = 22L; - private static final long HARD_PRIVACY_MODE_ON_ATTRIBUTE_ID = 23L; - private static final long NIGHT_VISION_ATTRIBUTE_ID = 24L; - private static final long NIGHT_VISION_ILLUM_ATTRIBUTE_ID = 25L; - private static final long VIEWPORT_ATTRIBUTE_ID = 26L; - private static final long SPEAKER_MUTED_ATTRIBUTE_ID = 27L; - private static final long SPEAKER_VOLUME_LEVEL_ATTRIBUTE_ID = 28L; - private static final long SPEAKER_MAX_LEVEL_ATTRIBUTE_ID = 29L; - private static final long SPEAKER_MIN_LEVEL_ATTRIBUTE_ID = 30L; - private static final long MICROPHONE_MUTED_ATTRIBUTE_ID = 31L; - private static final long MICROPHONE_VOLUME_LEVEL_ATTRIBUTE_ID = 32L; - private static final long MICROPHONE_MAX_LEVEL_ATTRIBUTE_ID = 33L; - private static final long MICROPHONE_MIN_LEVEL_ATTRIBUTE_ID = 34L; - private static final long MICROPHONE_AGC_ENABLED_ATTRIBUTE_ID = 35L; - private static final long IMAGE_ROTATION_ATTRIBUTE_ID = 36L; - private static final long IMAGE_FLIP_HORIZONTAL_ATTRIBUTE_ID = 37L; - private static final long IMAGE_FLIP_VERTICAL_ATTRIBUTE_ID = 38L; - private static final long LOCAL_VIDEO_RECORDING_ENABLED_ATTRIBUTE_ID = 39L; - private static final long LOCAL_SNAPSHOT_RECORDING_ENABLED_ATTRIBUTE_ID = 40L; - private static final long STATUS_LIGHT_ENABLED_ATTRIBUTE_ID = 41L; - private static final long STATUS_LIGHT_BRIGHTNESS_ATTRIBUTE_ID = 42L; + private static final long FABRICS_USING_CAMERA_ATTRIBUTE_ID = 14L; + private static final long ALLOCATED_VIDEO_STREAMS_ATTRIBUTE_ID = 15L; + private static final long ALLOCATED_AUDIO_STREAMS_ATTRIBUTE_ID = 16L; + private static final long ALLOCATED_SNAPSHOT_STREAMS_ATTRIBUTE_ID = 17L; + private static final long RANKED_VIDEO_STREAM_PRIORITIES_LIST_ATTRIBUTE_ID = 18L; + private static final long SOFT_RECORDING_PRIVACY_MODE_ENABLED_ATTRIBUTE_ID = 19L; + private static final long SOFT_LIVESTREAM_PRIVACY_MODE_ENABLED_ATTRIBUTE_ID = 20L; + private static final long HARD_PRIVACY_MODE_ON_ATTRIBUTE_ID = 21L; + private static final long NIGHT_VISION_ATTRIBUTE_ID = 22L; + private static final long NIGHT_VISION_ILLUM_ATTRIBUTE_ID = 23L; + private static final long VIEWPORT_ATTRIBUTE_ID = 24L; + private static final long SPEAKER_MUTED_ATTRIBUTE_ID = 25L; + private static final long SPEAKER_VOLUME_LEVEL_ATTRIBUTE_ID = 26L; + private static final long SPEAKER_MAX_LEVEL_ATTRIBUTE_ID = 27L; + private static final long SPEAKER_MIN_LEVEL_ATTRIBUTE_ID = 28L; + private static final long MICROPHONE_MUTED_ATTRIBUTE_ID = 29L; + private static final long MICROPHONE_VOLUME_LEVEL_ATTRIBUTE_ID = 30L; + private static final long MICROPHONE_MAX_LEVEL_ATTRIBUTE_ID = 31L; + private static final long MICROPHONE_MIN_LEVEL_ATTRIBUTE_ID = 32L; + private static final long MICROPHONE_AGC_ENABLED_ATTRIBUTE_ID = 33L; + private static final long IMAGE_ROTATION_ATTRIBUTE_ID = 34L; + private static final long IMAGE_FLIP_HORIZONTAL_ATTRIBUTE_ID = 35L; + private static final long IMAGE_FLIP_VERTICAL_ATTRIBUTE_ID = 36L; + private static final long LOCAL_VIDEO_RECORDING_ENABLED_ATTRIBUTE_ID = 37L; + private static final long LOCAL_SNAPSHOT_RECORDING_ENABLED_ATTRIBUTE_ID = 38L; + private static final long STATUS_LIGHT_ENABLED_ATTRIBUTE_ID = 39L; + private static final long STATUS_LIGHT_BRIGHTNESS_ATTRIBUTE_ID = 40L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -59980,11 +59978,11 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void snapshotStreamAllocate(SnapshotStreamAllocateResponseCallback callback, Integer imageCodec, Integer frameRate, Long bitRate, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct minResolution, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct maxResolution, Integer quality) { - snapshotStreamAllocate(callback, imageCodec, frameRate, bitRate, minResolution, maxResolution, quality, 0); + public void snapshotStreamAllocate(SnapshotStreamAllocateResponseCallback callback, Integer imageCodec, Integer maxFrameRate, Long bitRate, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct minResolution, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct maxResolution, Integer quality) { + snapshotStreamAllocate(callback, imageCodec, maxFrameRate, bitRate, minResolution, maxResolution, quality, 0); } - public void snapshotStreamAllocate(SnapshotStreamAllocateResponseCallback callback, Integer imageCodec, Integer frameRate, Long bitRate, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct minResolution, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct maxResolution, Integer quality, int timedInvokeTimeoutMs) { + public void snapshotStreamAllocate(SnapshotStreamAllocateResponseCallback callback, Integer imageCodec, Integer maxFrameRate, Long bitRate, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct minResolution, ChipStructs.CameraAvStreamManagementClusterVideoResolutionStruct maxResolution, Integer quality, int timedInvokeTimeoutMs) { final long commandId = 7L; ArrayList elements = new ArrayList<>(); @@ -59992,9 +59990,9 @@ public void snapshotStreamAllocate(SnapshotStreamAllocateResponseCallback callba BaseTLVType imageCodectlvValue = new UIntType(imageCodec); elements.add(new StructElement(imageCodecFieldID, imageCodectlvValue)); - final long frameRateFieldID = 1L; - BaseTLVType frameRatetlvValue = new UIntType(frameRate); - elements.add(new StructElement(frameRateFieldID, frameRatetlvValue)); + final long maxFrameRateFieldID = 1L; + BaseTLVType maxFrameRatetlvValue = new UIntType(maxFrameRate); + elements.add(new StructElement(maxFrameRateFieldID, maxFrameRatetlvValue)); final long bitRateFieldID = 2L; BaseTLVType bitRatetlvValue = new UIntType(bitRate); @@ -60130,14 +60128,6 @@ public interface SupportedSnapshotParamsAttributeCallback extends BaseAttributeC void onSuccess(List value); } - public interface CurrentVideoCodecsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } - - public interface CurrentSnapshotConfigAttributeCallback extends BaseAttributeCallback { - void onSuccess(ChipStructs.CameraAvStreamManagementClusterSnapshotParamsStruct value); - } - public interface FabricsUsingCameraAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -60551,58 +60541,6 @@ public void onSuccess(byte[] tlv) { }, HDR_MODE_ENABLED_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readCurrentVideoCodecsAttribute( - CurrentVideoCodecsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_VIDEO_CODECS_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, CURRENT_VIDEO_CODECS_ATTRIBUTE_ID, true); - } - - public void subscribeCurrentVideoCodecsAttribute( - CurrentVideoCodecsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_VIDEO_CODECS_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, CURRENT_VIDEO_CODECS_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readCurrentSnapshotConfigAttribute( - CurrentSnapshotConfigAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_SNAPSHOT_CONFIG_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - ChipStructs.CameraAvStreamManagementClusterSnapshotParamsStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, CURRENT_SNAPSHOT_CONFIG_ATTRIBUTE_ID, true); - } - - public void subscribeCurrentSnapshotConfigAttribute( - CurrentSnapshotConfigAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_SNAPSHOT_CONFIG_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - ChipStructs.CameraAvStreamManagementClusterSnapshotParamsStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, CURRENT_SNAPSHOT_CONFIG_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readFabricsUsingCameraAttribute( FabricsUsingCameraAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FABRICS_USING_CAMERA_ATTRIBUTE_ID); @@ -60720,15 +60658,6 @@ public void onSuccess(byte[] tlv) { }, RANKED_VIDEO_STREAM_PRIORITIES_LIST_ATTRIBUTE_ID, true); } - public void writeRankedVideoStreamPrioritiesListAttribute(DefaultClusterCallback callback, ArrayList value) { - writeRankedVideoStreamPrioritiesListAttribute(callback, value, 0); - } - - public void writeRankedVideoStreamPrioritiesListAttribute(DefaultClusterCallback callback, ArrayList value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = ArrayType.generateArrayType(value, (elementvalue) -> new UIntType(elementvalue)); - writeAttribute(new WriteAttributesCallbackImpl(callback), RANKED_VIDEO_STREAM_PRIORITIES_LIST_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - public void subscribeRankedVideoStreamPrioritiesListAttribute( RankedVideoStreamPrioritiesListAttributeCallback callback, int minInterval, int maxInterval) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, RANKED_VIDEO_STREAM_PRIORITIES_LIST_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 0f40fb5c326ba0..86a43781fec889 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -17087,35 +17087,33 @@ public enum Attribute { MaxNetworkBandwidth(11L), CurrentFrameRate(12L), HDRModeEnabled(13L), - CurrentVideoCodecs(14L), - CurrentSnapshotConfig(15L), - FabricsUsingCamera(16L), - AllocatedVideoStreams(17L), - AllocatedAudioStreams(18L), - AllocatedSnapshotStreams(19L), - RankedVideoStreamPrioritiesList(20L), - SoftRecordingPrivacyModeEnabled(21L), - SoftLivestreamPrivacyModeEnabled(22L), - HardPrivacyModeOn(23L), - NightVision(24L), - NightVisionIllum(25L), - Viewport(26L), - SpeakerMuted(27L), - SpeakerVolumeLevel(28L), - SpeakerMaxLevel(29L), - SpeakerMinLevel(30L), - MicrophoneMuted(31L), - MicrophoneVolumeLevel(32L), - MicrophoneMaxLevel(33L), - MicrophoneMinLevel(34L), - MicrophoneAGCEnabled(35L), - ImageRotation(36L), - ImageFlipHorizontal(37L), - ImageFlipVertical(38L), - LocalVideoRecordingEnabled(39L), - LocalSnapshotRecordingEnabled(40L), - StatusLightEnabled(41L), - StatusLightBrightness(42L), + FabricsUsingCamera(14L), + AllocatedVideoStreams(15L), + AllocatedAudioStreams(16L), + AllocatedSnapshotStreams(17L), + RankedVideoStreamPrioritiesList(18L), + SoftRecordingPrivacyModeEnabled(19L), + SoftLivestreamPrivacyModeEnabled(20L), + HardPrivacyModeOn(21L), + NightVision(22L), + NightVisionIllum(23L), + Viewport(24L), + SpeakerMuted(25L), + SpeakerVolumeLevel(26L), + SpeakerMaxLevel(27L), + SpeakerMinLevel(28L), + MicrophoneMuted(29L), + MicrophoneVolumeLevel(30L), + MicrophoneMaxLevel(31L), + MicrophoneMinLevel(32L), + MicrophoneAGCEnabled(33L), + ImageRotation(34L), + ImageFlipHorizontal(35L), + ImageFlipVertical(36L), + LocalVideoRecordingEnabled(37L), + LocalSnapshotRecordingEnabled(38L), + StatusLightEnabled(39L), + StatusLightBrightness(40L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -17276,7 +17274,7 @@ public static VideoStreamDeallocateCommandField value(int id) throws NoSuchField } throw new NoSuchFieldError(); } - }public enum SnapshotStreamAllocateCommandField {ImageCodec(0),FrameRate(1),BitRate(2),MinResolution(3),MaxResolution(4),Quality(5),; + }public enum SnapshotStreamAllocateCommandField {ImageCodec(0),MaxFrameRate(1),BitRate(2),MinResolution(3),MaxResolution(4),Quality(5),; private final int id; SnapshotStreamAllocateCommandField(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 d60e57afa2496e..42e96815ef9b43 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -20252,48 +20252,6 @@ public void onError(Exception ex) { } } - public static class DelegatedCameraAvStreamManagementClusterCurrentVideoCodecsAttributeCallback implements ChipClusters.CameraAvStreamManagementCluster.CurrentVideoCodecsAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(List valueList) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); - responseValues.put(commandResponseInfo, valueList); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - - public static class DelegatedCameraAvStreamManagementClusterCurrentSnapshotConfigAttributeCallback implements ChipClusters.CameraAvStreamManagementCluster.CurrentSnapshotConfigAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(ChipStructs.CameraAvStreamManagementClusterSnapshotParamsStruct value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.CameraAvStreamManagementClusterSnapshotParamsStruct"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - public static class DelegatedCameraAvStreamManagementClusterFabricsUsingCameraAttributeCallback implements ChipClusters.CameraAvStreamManagementCluster.FabricsUsingCameraAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -29807,8 +29765,8 @@ public Map> getCommandMap() { CommandParameterInfo cameraAvStreamManagementsnapshotStreamAllocateimageCodecCommandParameterInfo = new CommandParameterInfo("imageCodec", Integer.class, Integer.class); cameraAvStreamManagementsnapshotStreamAllocateCommandParams.put("imageCodec",cameraAvStreamManagementsnapshotStreamAllocateimageCodecCommandParameterInfo); - CommandParameterInfo cameraAvStreamManagementsnapshotStreamAllocateframeRateCommandParameterInfo = new CommandParameterInfo("frameRate", Integer.class, Integer.class); - cameraAvStreamManagementsnapshotStreamAllocateCommandParams.put("frameRate",cameraAvStreamManagementsnapshotStreamAllocateframeRateCommandParameterInfo); + CommandParameterInfo cameraAvStreamManagementsnapshotStreamAllocatemaxFrameRateCommandParameterInfo = new CommandParameterInfo("maxFrameRate", Integer.class, Integer.class); + cameraAvStreamManagementsnapshotStreamAllocateCommandParams.put("maxFrameRate",cameraAvStreamManagementsnapshotStreamAllocatemaxFrameRateCommandParameterInfo); CommandParameterInfo cameraAvStreamManagementsnapshotStreamAllocatebitRateCommandParameterInfo = new CommandParameterInfo("bitRate", Long.class, Long.class); cameraAvStreamManagementsnapshotStreamAllocateCommandParams.put("bitRate",cameraAvStreamManagementsnapshotStreamAllocatebitRateCommandParameterInfo); @@ -29825,7 +29783,7 @@ public Map> getCommandMap() { commandArguments.get("imageCodec") , (Integer) - commandArguments.get("frameRate") + commandArguments.get("maxFrameRate") , (Long) commandArguments.get("bitRate") diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index eb1dcbafc176d5..85d8c246765215 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -18406,17 +18406,6 @@ private static Map readCameraAvStreamManagementInteract readCameraAvStreamManagementHDRModeEnabledCommandParams ); result.put("readHDRModeEnabledAttribute", readCameraAvStreamManagementHDRModeEnabledAttributeInteractionInfo); - Map readCameraAvStreamManagementCurrentVideoCodecsCommandParams = new LinkedHashMap(); - InteractionInfo readCameraAvStreamManagementCurrentVideoCodecsAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.CameraAvStreamManagementCluster) cluster).readCurrentVideoCodecsAttribute( - (ChipClusters.CameraAvStreamManagementCluster.CurrentVideoCodecsAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedCameraAvStreamManagementClusterCurrentVideoCodecsAttributeCallback(), - readCameraAvStreamManagementCurrentVideoCodecsCommandParams - ); - result.put("readCurrentVideoCodecsAttribute", readCameraAvStreamManagementCurrentVideoCodecsAttributeInteractionInfo); Map readCameraAvStreamManagementFabricsUsingCameraCommandParams = new LinkedHashMap(); InteractionInfo readCameraAvStreamManagementFabricsUsingCameraAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt index 9a8e562d2fda11..ffcad10cbf9ef1 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt @@ -133,29 +133,6 @@ class CameraAvStreamManagementCluster( object SubscriptionEstablished : SupportedSnapshotParamsAttributeSubscriptionState() } - class CurrentVideoCodecsAttribute(val value: List?) - - sealed class CurrentVideoCodecsAttributeSubscriptionState { - data class Success(val value: List?) : CurrentVideoCodecsAttributeSubscriptionState() - - data class Error(val exception: Exception) : CurrentVideoCodecsAttributeSubscriptionState() - - object SubscriptionEstablished : CurrentVideoCodecsAttributeSubscriptionState() - } - - class CurrentSnapshotConfigAttribute( - val value: CameraAvStreamManagementClusterSnapshotParamsStruct? - ) - - sealed class CurrentSnapshotConfigAttributeSubscriptionState { - data class Success(val value: CameraAvStreamManagementClusterSnapshotParamsStruct?) : - CurrentSnapshotConfigAttributeSubscriptionState() - - data class Error(val exception: Exception) : CurrentSnapshotConfigAttributeSubscriptionState() - - object SubscriptionEstablished : CurrentSnapshotConfigAttributeSubscriptionState() - } - class FabricsUsingCameraAttribute(val value: List) sealed class FabricsUsingCameraAttributeSubscriptionState { @@ -511,7 +488,7 @@ class CameraAvStreamManagementCluster( suspend fun snapshotStreamAllocate( imageCodec: UByte, - frameRate: UShort, + maxFrameRate: UShort, bitRate: UInt, minResolution: CameraAvStreamManagementClusterVideoResolutionStruct, maxResolution: CameraAvStreamManagementClusterVideoResolutionStruct, @@ -526,8 +503,8 @@ class CameraAvStreamManagementCluster( val TAG_IMAGE_CODEC_REQ: Int = 0 tlvWriter.put(ContextSpecificTag(TAG_IMAGE_CODEC_REQ), imageCodec) - val TAG_FRAME_RATE_REQ: Int = 1 - tlvWriter.put(ContextSpecificTag(TAG_FRAME_RATE_REQ), frameRate) + val TAG_MAX_FRAME_RATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MAX_FRAME_RATE_REQ), maxFrameRate) val TAG_BIT_RATE_REQ: Int = 2 tlvWriter.put(ContextSpecificTag(TAG_BIT_RATE_REQ), bitRate) @@ -2039,206 +2016,8 @@ class CameraAvStreamManagementCluster( } } - suspend fun readCurrentVideoCodecsAttribute(): CurrentVideoCodecsAttribute { - val ATTRIBUTE_ID: UInt = 14u - - 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) { "Currentvideocodecs attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: List? = - if (tlvReader.isNextTag(AnonymousTag)) { - buildList { - tlvReader.enterArray(AnonymousTag) - while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUByte(AnonymousTag)) - } - tlvReader.exitContainer() - } - } else { - null - } - - return CurrentVideoCodecsAttribute(decodedValue) - } - - suspend fun subscribeCurrentVideoCodecsAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 14u - 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( - CurrentVideoCodecsAttributeSubscriptionState.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) { - "Currentvideocodecs attribute not found in Node State update" - } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: List? = - if (tlvReader.isNextTag(AnonymousTag)) { - buildList { - tlvReader.enterArray(AnonymousTag) - while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUByte(AnonymousTag)) - } - tlvReader.exitContainer() - } - } else { - null - } - - decodedValue?.let { emit(CurrentVideoCodecsAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(CurrentVideoCodecsAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - - suspend fun readCurrentSnapshotConfigAttribute(): CurrentSnapshotConfigAttribute { - val ATTRIBUTE_ID: UInt = 15u - - 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) { "Currentsnapshotconfig attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: CameraAvStreamManagementClusterSnapshotParamsStruct? = - if (tlvReader.isNextTag(AnonymousTag)) { - CameraAvStreamManagementClusterSnapshotParamsStruct.fromTlv(AnonymousTag, tlvReader) - } else { - null - } - - return CurrentSnapshotConfigAttribute(decodedValue) - } - - suspend fun subscribeCurrentSnapshotConfigAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 15u - 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( - CurrentSnapshotConfigAttributeSubscriptionState.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) { - "Currentsnapshotconfig attribute not found in Node State update" - } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: CameraAvStreamManagementClusterSnapshotParamsStruct? = - if (tlvReader.isNextTag(AnonymousTag)) { - CameraAvStreamManagementClusterSnapshotParamsStruct.fromTlv(AnonymousTag, tlvReader) - } else { - null - } - - decodedValue?.let { emit(CurrentSnapshotConfigAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(CurrentSnapshotConfigAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readFabricsUsingCameraAttribute(): FabricsUsingCameraAttribute { - val ATTRIBUTE_ID: UInt = 16u + val ATTRIBUTE_ID: UInt = 14u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2279,7 +2058,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 16u + val ATTRIBUTE_ID: UInt = 14u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2335,7 +2114,7 @@ class CameraAvStreamManagementCluster( } suspend fun readAllocatedVideoStreamsAttribute(): AllocatedVideoStreamsAttribute { - val ATTRIBUTE_ID: UInt = 17u + val ATTRIBUTE_ID: UInt = 15u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2380,7 +2159,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 17u + val ATTRIBUTE_ID: UInt = 15u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2445,7 +2224,7 @@ class CameraAvStreamManagementCluster( } suspend fun readAllocatedAudioStreamsAttribute(): AllocatedAudioStreamsAttribute { - val ATTRIBUTE_ID: UInt = 18u + val ATTRIBUTE_ID: UInt = 16u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2490,7 +2269,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 18u + val ATTRIBUTE_ID: UInt = 16u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2555,7 +2334,7 @@ class CameraAvStreamManagementCluster( } suspend fun readAllocatedSnapshotStreamsAttribute(): AllocatedSnapshotStreamsAttribute { - val ATTRIBUTE_ID: UInt = 19u + val ATTRIBUTE_ID: UInt = 17u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2602,7 +2381,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 19u + val ATTRIBUTE_ID: UInt = 17u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2668,7 +2447,7 @@ class CameraAvStreamManagementCluster( suspend fun readRankedVideoStreamPrioritiesListAttribute(): RankedVideoStreamPrioritiesListAttribute { - val ATTRIBUTE_ID: UInt = 20u + val ATTRIBUTE_ID: UInt = 18u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2711,58 +2490,11 @@ class CameraAvStreamManagementCluster( return RankedVideoStreamPrioritiesListAttribute(decodedValue) } - suspend fun writeRankedVideoStreamPrioritiesListAttribute( - value: List, - timedWriteTimeout: Duration? = null, - ) { - val ATTRIBUTE_ID: UInt = 20u - - val tlvWriter = TlvWriter() - tlvWriter.startArray(AnonymousTag) - for (item in value.iterator()) { - tlvWriter.put(AnonymousTag, item) - } - tlvWriter.endArray() - - 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 subscribeRankedVideoStreamPrioritiesListAttribute( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 20u + val ATTRIBUTE_ID: UInt = 18u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2824,7 +2556,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSoftRecordingPrivacyModeEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 21u + val ATTRIBUTE_ID: UInt = 19u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2865,7 +2597,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 21u + val ATTRIBUTE_ID: UInt = 19u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -2908,7 +2640,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 21u + val ATTRIBUTE_ID: UInt = 19u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -2962,7 +2694,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSoftLivestreamPrivacyModeEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 22u + val ATTRIBUTE_ID: UInt = 20u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3003,7 +2735,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 22u + val ATTRIBUTE_ID: UInt = 20u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -3046,7 +2778,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 22u + val ATTRIBUTE_ID: UInt = 20u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3100,7 +2832,7 @@ class CameraAvStreamManagementCluster( } suspend fun readHardPrivacyModeOnAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 23u + val ATTRIBUTE_ID: UInt = 21u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3139,7 +2871,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 23u + val ATTRIBUTE_ID: UInt = 21u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3193,7 +2925,7 @@ class CameraAvStreamManagementCluster( } suspend fun readNightVisionAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 24u + val ATTRIBUTE_ID: UInt = 22u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3229,7 +2961,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeNightVisionAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 24u + val ATTRIBUTE_ID: UInt = 22u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -3272,7 +3004,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 24u + val ATTRIBUTE_ID: UInt = 22u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3324,7 +3056,7 @@ class CameraAvStreamManagementCluster( } suspend fun readNightVisionIllumAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 25u + val ATTRIBUTE_ID: UInt = 23u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3360,7 +3092,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeNightVisionIllumAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 25u + val ATTRIBUTE_ID: UInt = 23u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -3403,7 +3135,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 25u + val ATTRIBUTE_ID: UInt = 23u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3457,7 +3189,7 @@ class CameraAvStreamManagementCluster( } suspend fun readViewportAttribute(): ViewportAttribute { - val ATTRIBUTE_ID: UInt = 26u + val ATTRIBUTE_ID: UInt = 24u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3496,7 +3228,7 @@ class CameraAvStreamManagementCluster( value: CameraAvStreamManagementClusterViewportStruct, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 26u + val ATTRIBUTE_ID: UInt = 24u val tlvWriter = TlvWriter() value.toTlv(AnonymousTag, tlvWriter) @@ -3539,7 +3271,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 26u + val ATTRIBUTE_ID: UInt = 24u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3591,7 +3323,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSpeakerMutedAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 27u + val ATTRIBUTE_ID: UInt = 25u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3627,7 +3359,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeSpeakerMutedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 27u + val ATTRIBUTE_ID: UInt = 25u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -3670,7 +3402,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 27u + val ATTRIBUTE_ID: UInt = 25u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3722,7 +3454,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSpeakerVolumeLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 28u + val ATTRIBUTE_ID: UInt = 26u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3758,7 +3490,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeSpeakerVolumeLevelAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 28u + val ATTRIBUTE_ID: UInt = 26u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -3801,7 +3533,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 28u + val ATTRIBUTE_ID: UInt = 26u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3855,7 +3587,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSpeakerMaxLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 29u + val ATTRIBUTE_ID: UInt = 27u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3894,7 +3626,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 29u + val ATTRIBUTE_ID: UInt = 27u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3948,7 +3680,7 @@ class CameraAvStreamManagementCluster( } suspend fun readSpeakerMinLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 30u + val ATTRIBUTE_ID: UInt = 28u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -3987,7 +3719,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 30u + val ATTRIBUTE_ID: UInt = 28u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4041,7 +3773,7 @@ class CameraAvStreamManagementCluster( } suspend fun readMicrophoneMutedAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 31u + val ATTRIBUTE_ID: UInt = 29u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4077,7 +3809,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeMicrophoneMutedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 31u + val ATTRIBUTE_ID: UInt = 29u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4120,7 +3852,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 31u + val ATTRIBUTE_ID: UInt = 29u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4174,7 +3906,7 @@ class CameraAvStreamManagementCluster( } suspend fun readMicrophoneVolumeLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 32u + val ATTRIBUTE_ID: UInt = 30u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4213,7 +3945,7 @@ class CameraAvStreamManagementCluster( value: UByte, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 32u + val ATTRIBUTE_ID: UInt = 30u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4256,7 +3988,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 32u + val ATTRIBUTE_ID: UInt = 30u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4310,7 +4042,7 @@ class CameraAvStreamManagementCluster( } suspend fun readMicrophoneMaxLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 33u + val ATTRIBUTE_ID: UInt = 31u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4349,7 +4081,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 33u + val ATTRIBUTE_ID: UInt = 31u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4403,7 +4135,7 @@ class CameraAvStreamManagementCluster( } suspend fun readMicrophoneMinLevelAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 34u + val ATTRIBUTE_ID: UInt = 32u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4442,7 +4174,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 34u + val ATTRIBUTE_ID: UInt = 32u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4496,7 +4228,7 @@ class CameraAvStreamManagementCluster( } suspend fun readMicrophoneAGCEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 35u + val ATTRIBUTE_ID: UInt = 33u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4535,7 +4267,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 35u + val ATTRIBUTE_ID: UInt = 33u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4578,7 +4310,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 35u + val ATTRIBUTE_ID: UInt = 33u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4632,7 +4364,7 @@ class CameraAvStreamManagementCluster( } suspend fun readImageRotationAttribute(): UShort? { - val ATTRIBUTE_ID: UInt = 36u + val ATTRIBUTE_ID: UInt = 34u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4668,7 +4400,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeImageRotationAttribute(value: UShort, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 36u + val ATTRIBUTE_ID: UInt = 34u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4711,7 +4443,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 36u + val ATTRIBUTE_ID: UInt = 34u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4763,7 +4495,7 @@ class CameraAvStreamManagementCluster( } suspend fun readImageFlipHorizontalAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 37u + val ATTRIBUTE_ID: UInt = 35u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4802,7 +4534,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 37u + val ATTRIBUTE_ID: UInt = 35u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4845,7 +4577,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 37u + val ATTRIBUTE_ID: UInt = 35u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4899,7 +4631,7 @@ class CameraAvStreamManagementCluster( } suspend fun readImageFlipVerticalAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 38u + val ATTRIBUTE_ID: UInt = 36u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -4935,7 +4667,7 @@ class CameraAvStreamManagementCluster( } suspend fun writeImageFlipVerticalAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 38u + val ATTRIBUTE_ID: UInt = 36u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -4978,7 +4710,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 38u + val ATTRIBUTE_ID: UInt = 36u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5032,7 +4764,7 @@ class CameraAvStreamManagementCluster( } suspend fun readLocalVideoRecordingEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 39u + val ATTRIBUTE_ID: UInt = 37u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5071,7 +4803,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 39u + val ATTRIBUTE_ID: UInt = 37u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -5114,7 +4846,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 39u + val ATTRIBUTE_ID: UInt = 37u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5168,7 +4900,7 @@ class CameraAvStreamManagementCluster( } suspend fun readLocalSnapshotRecordingEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 40u + val ATTRIBUTE_ID: UInt = 38u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5209,7 +4941,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 40u + val ATTRIBUTE_ID: UInt = 38u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -5252,7 +4984,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 40u + val ATTRIBUTE_ID: UInt = 38u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5306,7 +5038,7 @@ class CameraAvStreamManagementCluster( } suspend fun readStatusLightEnabledAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 41u + val ATTRIBUTE_ID: UInt = 39u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5345,7 +5077,7 @@ class CameraAvStreamManagementCluster( value: Boolean, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 41u + val ATTRIBUTE_ID: UInt = 39u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -5388,7 +5120,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 41u + val ATTRIBUTE_ID: UInt = 39u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5442,7 +5174,7 @@ class CameraAvStreamManagementCluster( } suspend fun readStatusLightBrightnessAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 42u + val ATTRIBUTE_ID: UInt = 40u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -5481,7 +5213,7 @@ class CameraAvStreamManagementCluster( value: UByte, timedWriteTimeout: Duration? = null, ) { - val ATTRIBUTE_ID: UInt = 42u + val ATTRIBUTE_ID: UInt = 40u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -5524,7 +5256,7 @@ class CameraAvStreamManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 42u + val ATTRIBUTE_ID: UInt = 40u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index d307822772fe53..deddd974e4515e 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -40493,123 +40493,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } - case Attributes::CurrentVideoCodecs::Id: { - using TypeInfo = Attributes::CurrentVideoCodecs::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Integer"; - std::string newElement_0CtorSignature = "(I)V"; - jint jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::CurrentSnapshotConfig::Id: { - using TypeInfo = Attributes::CurrentSnapshotConfig::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - jobject value_resolution; - jobject value_resolution_width; - std::string value_resolution_widthClassName = "java/lang/Integer"; - std::string value_resolution_widthCtorSignature = "(I)V"; - jint jnivalue_resolution_width = static_cast(cppValue.resolution.width); - chip::JniReferences::GetInstance().CreateBoxedObject(value_resolution_widthClassName.c_str(), - value_resolution_widthCtorSignature.c_str(), - jnivalue_resolution_width, value_resolution_width); - jobject value_resolution_height; - std::string value_resolution_heightClassName = "java/lang/Integer"; - std::string value_resolution_heightCtorSignature = "(I)V"; - jint jnivalue_resolution_height = static_cast(cppValue.resolution.height); - chip::JniReferences::GetInstance().CreateBoxedObject(value_resolution_heightClassName.c_str(), - value_resolution_heightCtorSignature.c_str(), - jnivalue_resolution_height, value_resolution_height); - - { - jclass videoResolutionStructStructClass_1; - err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$CameraAvStreamManagementClusterVideoResolutionStruct", - videoResolutionStructStructClass_1); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Could not find class ChipStructs$CameraAvStreamManagementClusterVideoResolutionStruct"); - return nullptr; - } - - jmethodID videoResolutionStructStructCtor_1; - err = chip::JniReferences::GetInstance().FindMethod(env, videoResolutionStructStructClass_1, "", - "(Ljava/lang/Integer;Ljava/lang/Integer;)V", - &videoResolutionStructStructCtor_1); - if (err != CHIP_NO_ERROR || videoResolutionStructStructCtor_1 == nullptr) - { - ChipLogError(Zcl, - "Could not find ChipStructs$CameraAvStreamManagementClusterVideoResolutionStruct constructor"); - return nullptr; - } - - value_resolution = env->NewObject(videoResolutionStructStructClass_1, videoResolutionStructStructCtor_1, - value_resolution_width, value_resolution_height); - } - jobject value_maxFrameRate; - std::string value_maxFrameRateClassName = "java/lang/Integer"; - std::string value_maxFrameRateCtorSignature = "(I)V"; - jint jnivalue_maxFrameRate = static_cast(cppValue.maxFrameRate); - chip::JniReferences::GetInstance().CreateBoxedObject(value_maxFrameRateClassName.c_str(), - value_maxFrameRateCtorSignature.c_str(), - jnivalue_maxFrameRate, value_maxFrameRate); - jobject value_imageCodec; - std::string value_imageCodecClassName = "java/lang/Integer"; - std::string value_imageCodecCtorSignature = "(I)V"; - jint jnivalue_imageCodec = static_cast(cppValue.imageCodec); - chip::JniReferences::GetInstance().CreateBoxedObject( - value_imageCodecClassName.c_str(), value_imageCodecCtorSignature.c_str(), jnivalue_imageCodec, value_imageCodec); - - { - jclass snapshotParamsStructStructClass_0; - err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$CameraAvStreamManagementClusterSnapshotParamsStruct", - snapshotParamsStructStructClass_0); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Could not find class ChipStructs$CameraAvStreamManagementClusterSnapshotParamsStruct"); - return nullptr; - } - - jmethodID snapshotParamsStructStructCtor_0; - err = chip::JniReferences::GetInstance().FindMethod( - env, snapshotParamsStructStructClass_0, "", - "(Lchip/devicecontroller/ChipStructs$CameraAvStreamManagementClusterVideoResolutionStruct;Ljava/lang/" - "Integer;Ljava/lang/Integer;)V", - &snapshotParamsStructStructCtor_0); - if (err != CHIP_NO_ERROR || snapshotParamsStructStructCtor_0 == nullptr) - { - ChipLogError(Zcl, "Could not find ChipStructs$CameraAvStreamManagementClusterSnapshotParamsStruct constructor"); - return nullptr; - } - - value = env->NewObject(snapshotParamsStructStructClass_0, snapshotParamsStructStructCtor_0, value_resolution, - value_maxFrameRate, value_imageCodec); - } - return value; - } case Attributes::FabricsUsingCamera::Id: { using TypeInfo = Attributes::FabricsUsingCamera::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index ac906271d32e02..971bb232a097f3 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -12447,7 +12447,7 @@ class ChipClusters: "commandName": "SnapshotStreamAllocate", "args": { "imageCodec": "int", - "frameRate": "int", + "maxFrameRate": "int", "bitRate": "int", "minResolution": "VideoResolutionStruct", "maxResolution": "VideoResolutionStruct", @@ -12564,193 +12564,180 @@ class ChipClusters: "writable": True, }, 0x0000000E: { - "attributeName": "CurrentVideoCodecs", + "attributeName": "FabricsUsingCamera", "attributeId": 0x0000000E, "type": "int", "reportable": True, }, 0x0000000F: { - "attributeName": "CurrentSnapshotConfig", + "attributeName": "AllocatedVideoStreams", "attributeId": 0x0000000F, "type": "", "reportable": True, }, 0x00000010: { - "attributeName": "FabricsUsingCamera", + "attributeName": "AllocatedAudioStreams", "attributeId": 0x00000010, - "type": "int", + "type": "", "reportable": True, }, 0x00000011: { - "attributeName": "AllocatedVideoStreams", + "attributeName": "AllocatedSnapshotStreams", "attributeId": 0x00000011, "type": "", "reportable": True, }, 0x00000012: { - "attributeName": "AllocatedAudioStreams", + "attributeName": "RankedVideoStreamPrioritiesList", "attributeId": 0x00000012, - "type": "", + "type": "int", "reportable": True, }, 0x00000013: { - "attributeName": "AllocatedSnapshotStreams", + "attributeName": "SoftRecordingPrivacyModeEnabled", "attributeId": 0x00000013, - "type": "", + "type": "bool", "reportable": True, + "writable": True, }, 0x00000014: { - "attributeName": "RankedVideoStreamPrioritiesList", + "attributeName": "SoftLivestreamPrivacyModeEnabled", "attributeId": 0x00000014, - "type": "int", + "type": "bool", "reportable": True, "writable": True, }, 0x00000015: { - "attributeName": "SoftRecordingPrivacyModeEnabled", + "attributeName": "HardPrivacyModeOn", "attributeId": 0x00000015, "type": "bool", "reportable": True, - "writable": True, }, 0x00000016: { - "attributeName": "SoftLivestreamPrivacyModeEnabled", + "attributeName": "NightVision", "attributeId": 0x00000016, - "type": "bool", + "type": "int", "reportable": True, "writable": True, }, 0x00000017: { - "attributeName": "HardPrivacyModeOn", + "attributeName": "NightVisionIllum", "attributeId": 0x00000017, - "type": "bool", + "type": "int", "reportable": True, + "writable": True, }, 0x00000018: { - "attributeName": "NightVision", + "attributeName": "Viewport", "attributeId": 0x00000018, - "type": "int", + "type": "", "reportable": True, "writable": True, }, 0x00000019: { - "attributeName": "NightVisionIllum", + "attributeName": "SpeakerMuted", "attributeId": 0x00000019, - "type": "int", + "type": "bool", "reportable": True, "writable": True, }, 0x0000001A: { - "attributeName": "Viewport", + "attributeName": "SpeakerVolumeLevel", "attributeId": 0x0000001A, - "type": "", + "type": "int", "reportable": True, "writable": True, }, 0x0000001B: { - "attributeName": "SpeakerMuted", + "attributeName": "SpeakerMaxLevel", "attributeId": 0x0000001B, - "type": "bool", + "type": "int", "reportable": True, - "writable": True, }, 0x0000001C: { - "attributeName": "SpeakerVolumeLevel", + "attributeName": "SpeakerMinLevel", "attributeId": 0x0000001C, "type": "int", "reportable": True, - "writable": True, }, 0x0000001D: { - "attributeName": "SpeakerMaxLevel", + "attributeName": "MicrophoneMuted", "attributeId": 0x0000001D, - "type": "int", + "type": "bool", "reportable": True, + "writable": True, }, 0x0000001E: { - "attributeName": "SpeakerMinLevel", + "attributeName": "MicrophoneVolumeLevel", "attributeId": 0x0000001E, "type": "int", "reportable": True, + "writable": True, }, 0x0000001F: { - "attributeName": "MicrophoneMuted", + "attributeName": "MicrophoneMaxLevel", "attributeId": 0x0000001F, - "type": "bool", + "type": "int", "reportable": True, - "writable": True, }, 0x00000020: { - "attributeName": "MicrophoneVolumeLevel", + "attributeName": "MicrophoneMinLevel", "attributeId": 0x00000020, "type": "int", "reportable": True, - "writable": True, }, 0x00000021: { - "attributeName": "MicrophoneMaxLevel", + "attributeName": "MicrophoneAGCEnabled", "attributeId": 0x00000021, - "type": "int", + "type": "bool", "reportable": True, + "writable": True, }, 0x00000022: { - "attributeName": "MicrophoneMinLevel", + "attributeName": "ImageRotation", "attributeId": 0x00000022, "type": "int", "reportable": True, + "writable": True, }, 0x00000023: { - "attributeName": "MicrophoneAGCEnabled", + "attributeName": "ImageFlipHorizontal", "attributeId": 0x00000023, "type": "bool", "reportable": True, "writable": True, }, 0x00000024: { - "attributeName": "ImageRotation", + "attributeName": "ImageFlipVertical", "attributeId": 0x00000024, - "type": "int", + "type": "bool", "reportable": True, "writable": True, }, 0x00000025: { - "attributeName": "ImageFlipHorizontal", + "attributeName": "LocalVideoRecordingEnabled", "attributeId": 0x00000025, "type": "bool", "reportable": True, "writable": True, }, 0x00000026: { - "attributeName": "ImageFlipVertical", + "attributeName": "LocalSnapshotRecordingEnabled", "attributeId": 0x00000026, "type": "bool", "reportable": True, "writable": True, }, 0x00000027: { - "attributeName": "LocalVideoRecordingEnabled", + "attributeName": "StatusLightEnabled", "attributeId": 0x00000027, "type": "bool", "reportable": True, "writable": True, }, 0x00000028: { - "attributeName": "LocalSnapshotRecordingEnabled", - "attributeId": 0x00000028, - "type": "bool", - "reportable": True, - "writable": True, - }, - 0x00000029: { - "attributeName": "StatusLightEnabled", - "attributeId": 0x00000029, - "type": "bool", - "reportable": True, - "writable": True, - }, - 0x0000002A: { "attributeName": "StatusLightBrightness", - "attributeId": 0x0000002A, + "attributeId": 0x00000028, "type": "int", "reportable": True, "writable": True, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index c9a162ac0b5af8..b27196c7512fce 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -44790,35 +44790,33 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maxNetworkBandwidth", Tag=0x0000000B, Type=uint), ClusterObjectFieldDescriptor(Label="currentFrameRate", Tag=0x0000000C, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="HDRModeEnabled", Tag=0x0000000D, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="currentVideoCodecs", Tag=0x0000000E, Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]]), - ClusterObjectFieldDescriptor(Label="currentSnapshotConfig", Tag=0x0000000F, Type=typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct]), - ClusterObjectFieldDescriptor(Label="fabricsUsingCamera", Tag=0x00000010, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="allocatedVideoStreams", Tag=0x00000011, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]]), - ClusterObjectFieldDescriptor(Label="allocatedAudioStreams", Tag=0x00000012, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]]), - ClusterObjectFieldDescriptor(Label="allocatedSnapshotStreams", Tag=0x00000013, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]]), - ClusterObjectFieldDescriptor(Label="rankedVideoStreamPrioritiesList", Tag=0x00000014, Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]]), - ClusterObjectFieldDescriptor(Label="softRecordingPrivacyModeEnabled", Tag=0x00000015, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="softLivestreamPrivacyModeEnabled", Tag=0x00000016, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="hardPrivacyModeOn", Tag=0x00000017, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="nightVision", Tag=0x00000018, Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]), - ClusterObjectFieldDescriptor(Label="nightVisionIllum", Tag=0x00000019, Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]), - ClusterObjectFieldDescriptor(Label="viewport", Tag=0x0000001A, Type=typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct]), - ClusterObjectFieldDescriptor(Label="speakerMuted", Tag=0x0000001B, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="speakerVolumeLevel", Tag=0x0000001C, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="speakerMaxLevel", Tag=0x0000001D, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="speakerMinLevel", Tag=0x0000001E, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="microphoneMuted", Tag=0x0000001F, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="microphoneVolumeLevel", Tag=0x00000020, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="microphoneMaxLevel", Tag=0x00000021, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="microphoneMinLevel", Tag=0x00000022, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="microphoneAGCEnabled", Tag=0x00000023, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="imageRotation", Tag=0x00000024, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="imageFlipHorizontal", Tag=0x00000025, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="imageFlipVertical", Tag=0x00000026, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="localVideoRecordingEnabled", Tag=0x00000027, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="localSnapshotRecordingEnabled", Tag=0x00000028, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="statusLightEnabled", Tag=0x00000029, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="statusLightBrightness", Tag=0x0000002A, Type=typing.Optional[Globals.Enums.ThreeLevelAutoEnum]), + ClusterObjectFieldDescriptor(Label="fabricsUsingCamera", Tag=0x0000000E, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="allocatedVideoStreams", Tag=0x0000000F, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]]), + ClusterObjectFieldDescriptor(Label="allocatedAudioStreams", Tag=0x00000010, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]]), + ClusterObjectFieldDescriptor(Label="allocatedSnapshotStreams", Tag=0x00000011, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]]), + ClusterObjectFieldDescriptor(Label="rankedVideoStreamPrioritiesList", Tag=0x00000012, Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]]), + ClusterObjectFieldDescriptor(Label="softRecordingPrivacyModeEnabled", Tag=0x00000013, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="softLivestreamPrivacyModeEnabled", Tag=0x00000014, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="hardPrivacyModeOn", Tag=0x00000015, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="nightVision", Tag=0x00000016, Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]), + ClusterObjectFieldDescriptor(Label="nightVisionIllum", Tag=0x00000017, Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]), + ClusterObjectFieldDescriptor(Label="viewport", Tag=0x00000018, Type=typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct]), + ClusterObjectFieldDescriptor(Label="speakerMuted", Tag=0x00000019, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="speakerVolumeLevel", Tag=0x0000001A, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="speakerMaxLevel", Tag=0x0000001B, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="speakerMinLevel", Tag=0x0000001C, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="microphoneMuted", Tag=0x0000001D, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="microphoneVolumeLevel", Tag=0x0000001E, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="microphoneMaxLevel", Tag=0x0000001F, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="microphoneMinLevel", Tag=0x00000020, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="microphoneAGCEnabled", Tag=0x00000021, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="imageRotation", Tag=0x00000022, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="imageFlipHorizontal", Tag=0x00000023, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="imageFlipVertical", Tag=0x00000024, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="localVideoRecordingEnabled", Tag=0x00000025, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="localSnapshotRecordingEnabled", Tag=0x00000026, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="statusLightEnabled", Tag=0x00000027, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="statusLightBrightness", Tag=0x00000028, Type=typing.Optional[Globals.Enums.ThreeLevelAutoEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), @@ -44840,8 +44838,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: maxNetworkBandwidth: uint = 0 currentFrameRate: typing.Optional[uint] = None HDRModeEnabled: typing.Optional[bool] = None - currentVideoCodecs: typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]] = None - currentSnapshotConfig: typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct] = None fabricsUsingCamera: typing.List[uint] = field(default_factory=lambda: []) allocatedVideoStreams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]] = None allocatedAudioStreams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]] = None @@ -45294,7 +45290,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ ClusterObjectFieldDescriptor(Label="imageCodec", Tag=0, Type=CameraAvStreamManagement.Enums.ImageCodecEnum), - ClusterObjectFieldDescriptor(Label="frameRate", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="maxFrameRate", Tag=1, Type=uint), ClusterObjectFieldDescriptor(Label="bitRate", Tag=2, Type=uint), ClusterObjectFieldDescriptor(Label="minResolution", Tag=3, Type=CameraAvStreamManagement.Structs.VideoResolutionStruct), ClusterObjectFieldDescriptor(Label="maxResolution", Tag=4, Type=CameraAvStreamManagement.Structs.VideoResolutionStruct), @@ -45302,7 +45298,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ]) imageCodec: CameraAvStreamManagement.Enums.ImageCodecEnum = 0 - frameRate: uint = 0 + maxFrameRate: uint = 0 bitRate: uint = 0 minResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) maxResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) @@ -45619,38 +45615,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.Optional[bool] = None - @dataclass - class CurrentVideoCodecs(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000551 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000000E - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]]) - - value: typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]] = None - - @dataclass - class CurrentSnapshotConfig(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000551 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000000F - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct]) - - value: typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct] = None - @dataclass class FabricsUsingCamera(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -45659,7 +45623,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000010 + return 0x0000000E @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45675,7 +45639,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000011 + return 0x0000000F @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45691,7 +45655,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000012 + return 0x00000010 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45707,7 +45671,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000013 + return 0x00000011 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45723,7 +45687,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000014 + return 0x00000012 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45739,7 +45703,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000015 + return 0x00000013 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45755,7 +45719,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000016 + return 0x00000014 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45771,7 +45735,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000017 + return 0x00000015 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45787,7 +45751,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000018 + return 0x00000016 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45803,7 +45767,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000019 + return 0x00000017 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45819,7 +45783,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001A + return 0x00000018 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45835,7 +45799,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001B + return 0x00000019 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45851,7 +45815,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001C + return 0x0000001A @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45867,7 +45831,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001D + return 0x0000001B @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45883,7 +45847,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001E + return 0x0000001C @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45899,7 +45863,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000001F + return 0x0000001D @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45915,7 +45879,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000020 + return 0x0000001E @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45931,7 +45895,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000021 + return 0x0000001F @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45947,7 +45911,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000022 + return 0x00000020 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45963,7 +45927,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000023 + return 0x00000021 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45979,7 +45943,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000024 + return 0x00000022 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -45995,7 +45959,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000025 + return 0x00000023 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46011,7 +45975,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000026 + return 0x00000024 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46027,7 +45991,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000027 + return 0x00000025 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46043,7 +46007,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000028 + return 0x00000026 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46059,7 +46023,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000029 + return 0x00000027 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46075,7 +46039,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x0000002A + return 0x00000028 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index 16df47b12d0411..247223cbe43fbb 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -17,6 +17,7 @@ #import #import +#import #import #import @@ -122,6 +123,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) */ @property (nonatomic, readonly, nullable, copy) NSNumber * productID MTR_NEWLY_AVAILABLE; +/** + * Network commissioning features supported by the device. + */ +@property (nonatomic, readonly) MTRNetworkCommissioningFeature networkCommissioningFeatures MTR_NEWLY_AVAILABLE; + /** * Set the delegate to receive asynchronous callbacks about the device. * diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 091d50a5d8fe8c..9169507634a88b 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -514,6 +514,12 @@ - (nullable NSNumber *)productID return [_pid copy]; } +- (MTRNetworkCommissioningFeature)networkCommissioningFeatures +{ + std::lock_guard lock(_descriptionLock); + return [_allNetworkFeatures unsignedIntValue]; +} + - (void)_notifyDelegateOfPrivateInternalPropertiesChanges { os_unfair_lock_assert_owner(&self->_lock); diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index b5fea425fa2d62..b5006336029d21 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -141,6 +141,11 @@ - (nullable NSNumber *)productID return [[self._internalState objectForKey:kMTRDeviceInternalPropertyKeyProductID] copy]; } +- (MTRNetworkCommissioningFeature)networkCommissioningFeatures +{ + return [[self._internalState objectForKey:kMTRDeviceInternalPropertyNetworkFeatures] unsignedIntValue]; +} + #pragma mark - Client Callbacks (MTRDeviceDelegate) // required methods for MTRDeviceDelegates diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 3f55a10f842d97..ce5c71d23f1d69 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5637,12 +5637,6 @@ static BOOL AttributeIsSpecifiedInCameraAVStreamManagementCluster(AttributeId aA case Attributes::HDRModeEnabled::Id: { return YES; } - case Attributes::CurrentVideoCodecs::Id: { - return YES; - } - case Attributes::CurrentSnapshotConfig::Id: { - return YES; - } case Attributes::FabricsUsingCamera::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 571793a7edb0f8..975c3b63f4a587 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -17210,48 +17210,6 @@ static id _Nullable DecodeAttributeValueForCameraAVStreamManagementCluster(Attri value = [NSNumber numberWithBool:cppValue]; return value; } - case Attributes::CurrentVideoCodecs::Id: { - using TypeInfo = Attributes::CurrentVideoCodecs::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0)]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - case Attributes::CurrentSnapshotConfig::Id: { - using TypeInfo = Attributes::CurrentSnapshotConfig::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nonnull value; - value = [MTRCameraAVStreamManagementClusterSnapshotParamsStruct new]; - value.resolution = [MTRCameraAVStreamManagementClusterVideoResolutionStruct new]; - value.resolution.width = [NSNumber numberWithUnsignedShort:cppValue.resolution.width]; - value.resolution.height = [NSNumber numberWithUnsignedShort:cppValue.resolution.height]; - value.maxFrameRate = [NSNumber numberWithUnsignedShort:cppValue.maxFrameRate]; - value.imageCodec = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.imageCodec)]; - return value; - } case Attributes::FabricsUsingCamera::Id: { using TypeInfo = Attributes::FabricsUsingCamera::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 92212cc373fd2f..32c79ee20f13cf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -14286,18 +14286,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeHDRModeEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeCurrentVideoCodecsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeCurrentVideoCodecsWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeCurrentVideoCodecsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - -- (void)readAttributeCurrentSnapshotConfigWithCompletion:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeCurrentSnapshotConfigWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeCurrentSnapshotConfigWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeFabricsUsingCameraWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeFabricsUsingCameraWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14323,8 +14311,6 @@ MTR_PROVISIONALLY_AVAILABLE + (void)readAttributeAllocatedSnapshotStreamsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeRankedVideoStreamPrioritiesListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSArray * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeRankedVideoStreamPrioritiesListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 07e00f7088e73b..ea02951aa50907 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -98867,78 +98867,6 @@ + (void)readAttributeHDRModeEnabledWithClusterStateCache:(MTRClusterStateCacheCo completion:completion]; } -- (void)readAttributeCurrentVideoCodecsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentVideoCodecs::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeCurrentVideoCodecsWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentVideoCodecs::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeCurrentVideoCodecsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentVideoCodecs::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - -- (void)readAttributeCurrentSnapshotConfigWithCompletion:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeCurrentSnapshotConfigWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeCurrentSnapshotConfigWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeFabricsUsingCameraWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = CameraAvStreamManagement::Attributes::FabricsUsingCamera::TypeInfo; @@ -99094,55 +99022,6 @@ - (void)readAttributeRankedVideoStreamPrioritiesListWithCompletion:(void (^)(NSA completion:completion]; } -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSArray * _Nonnull) value params:nil completion:completion]; -} -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSArray * _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 = CameraAvStreamManagement::Attributes::RankedVideoStreamPrioritiesList::TypeInfo; - TypeInfo::Type cppValue; - { - using ListType_0 = std::remove_reference_t; - using ListMemberType_0 = ListMemberTypeGetter::Type; - if (value.count != 0) { - auto * listHolder_0 = new ListHolder(value.count); - if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - listFreer.add(listHolder_0); - for (size_t i_0 = 0; i_0 < value.count; ++i_0) { - if ( ! [value[i_0] isKindOfClass: [NSNumber class]] ) { - // Wrong kind of value. - return CHIP_ERROR_INVALID_ARGUMENT; - } - auto element_0 = (NSNumber *)value[i_0]; - listHolder_0->mList[i_0] = static_castmList[i_0])>>(element_0.unsignedCharValue); - } - cppValue = ListType_0(listHolder_0->mList, value.count); - } else { - cppValue = ListType_0(); - } - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - - (void)subscribeAttributeRankedVideoStreamPrioritiesListWithParams:(MTRSubscribeParams * _Nonnull)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 7587e25a241fc0..e58a3a60d8eee1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -4649,35 +4649,33 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxNetworkBandwidthID MTR_PROVISIONALLY_AVAILABLE = 0x0000000B, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentFrameRateID MTR_PROVISIONALLY_AVAILABLE = 0x0000000C, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeHDRModeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x0000000D, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentVideoCodecsID MTR_PROVISIONALLY_AVAILABLE = 0x0000000E, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentSnapshotConfigID MTR_PROVISIONALLY_AVAILABLE = 0x0000000F, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeFabricsUsingCameraID MTR_PROVISIONALLY_AVAILABLE = 0x00000010, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedVideoStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x00000011, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedAudioStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x00000012, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedSnapshotStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x00000013, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRankedVideoStreamPrioritiesListID MTR_PROVISIONALLY_AVAILABLE = 0x00000014, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSoftRecordingPrivacyModeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000015, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSoftLivestreamPrivacyModeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000016, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeHardPrivacyModeOnID MTR_PROVISIONALLY_AVAILABLE = 0x00000017, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeNightVisionID MTR_PROVISIONALLY_AVAILABLE = 0x00000018, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeNightVisionIllumID MTR_PROVISIONALLY_AVAILABLE = 0x00000019, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeViewportID MTR_PROVISIONALLY_AVAILABLE = 0x0000001A, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMutedID MTR_PROVISIONALLY_AVAILABLE = 0x0000001B, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerVolumeLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001C, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMaxLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001D, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMinLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001E, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMutedID MTR_PROVISIONALLY_AVAILABLE = 0x0000001F, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneVolumeLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000020, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMaxLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000021, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMinLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000022, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneAGCEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000023, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageRotationID MTR_PROVISIONALLY_AVAILABLE = 0x00000024, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageFlipHorizontalID MTR_PROVISIONALLY_AVAILABLE = 0x00000025, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageFlipVerticalID MTR_PROVISIONALLY_AVAILABLE = 0x00000026, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeLocalVideoRecordingEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000027, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeLocalSnapshotRecordingEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000028, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeStatusLightEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000029, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeStatusLightBrightnessID MTR_PROVISIONALLY_AVAILABLE = 0x0000002A, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeFabricsUsingCameraID MTR_PROVISIONALLY_AVAILABLE = 0x0000000E, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedVideoStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x0000000F, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedAudioStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x00000010, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAllocatedSnapshotStreamsID MTR_PROVISIONALLY_AVAILABLE = 0x00000011, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRankedVideoStreamPrioritiesListID MTR_PROVISIONALLY_AVAILABLE = 0x00000012, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSoftRecordingPrivacyModeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000013, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSoftLivestreamPrivacyModeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000014, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeHardPrivacyModeOnID MTR_PROVISIONALLY_AVAILABLE = 0x00000015, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeNightVisionID MTR_PROVISIONALLY_AVAILABLE = 0x00000016, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeNightVisionIllumID MTR_PROVISIONALLY_AVAILABLE = 0x00000017, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeViewportID MTR_PROVISIONALLY_AVAILABLE = 0x00000018, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMutedID MTR_PROVISIONALLY_AVAILABLE = 0x00000019, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerVolumeLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001A, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMaxLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001B, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerMinLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001C, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMutedID MTR_PROVISIONALLY_AVAILABLE = 0x0000001D, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneVolumeLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001E, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMaxLevelID MTR_PROVISIONALLY_AVAILABLE = 0x0000001F, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneMinLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000020, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneAGCEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000021, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageRotationID MTR_PROVISIONALLY_AVAILABLE = 0x00000022, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageFlipHorizontalID MTR_PROVISIONALLY_AVAILABLE = 0x00000023, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeImageFlipVerticalID MTR_PROVISIONALLY_AVAILABLE = 0x00000024, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeLocalVideoRecordingEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000025, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeLocalSnapshotRecordingEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000026, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeStatusLightEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000027, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeStatusLightBrightnessID MTR_PROVISIONALLY_AVAILABLE = 0x00000028, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 0791fc4952832b..96b2c0cd3bf3e6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -7783,14 +7783,6 @@ result = @"HDRModeEnabled"; break; - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentVideoCodecsID: - result = @"CurrentVideoCodecs"; - break; - - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentSnapshotConfigID: - result = @"CurrentSnapshotConfig"; - break; - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeFabricsUsingCameraID: result = @"FabricsUsingCamera"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 4c28d0ddd343da..9babe0a6251f1e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -6674,10 +6674,6 @@ MTR_PROVISIONALLY_AVAILABLE - (void)writeAttributeHDRModeEnabledWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; - (void)writeAttributeHDRModeEnabledWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeCurrentVideoCodecsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - -- (NSDictionary * _Nullable)readAttributeCurrentSnapshotConfigWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeFabricsUsingCameraWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAllocatedVideoStreamsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6687,8 +6683,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAllocatedSnapshotStreamsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeRankedVideoStreamPrioritiesListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeSoftRecordingPrivacyModeEnabledWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (void)writeAttributeSoftRecordingPrivacyModeEnabledWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 500aa41148ae4e..1d6828deddb868 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -19397,16 +19397,6 @@ - (void)writeAttributeHDRModeEnabledWithValue:(NSDictionary *)da [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeHDRModeEnabledID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } -- (NSDictionary * _Nullable)readAttributeCurrentVideoCodecsWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentVideoCodecsID) params:params]; -} - -- (NSDictionary * _Nullable)readAttributeCurrentSnapshotConfigWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeCurrentSnapshotConfigID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeFabricsUsingCameraWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeFabricsUsingCameraID) params:params]; @@ -19432,17 +19422,6 @@ - (void)writeAttributeHDRModeEnabledWithValue:(NSDictionary *)da return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRankedVideoStreamPrioritiesListID) params:params]; } -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeRankedVideoStreamPrioritiesListWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeRankedVideoStreamPrioritiesListWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRankedVideoStreamPrioritiesListID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - - (NSDictionary * _Nullable)readAttributeSoftRecordingPrivacyModeEnabledWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSoftRecordingPrivacyModeEnabledID) params:params]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index c6dbb8e975f8f3..573d6581ced8f0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -11226,7 +11226,7 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSNumber * _Nonnull imageCodec MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nonnull frameRate MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull maxFrameRate MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull bitRate MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index b737f253cbd64b..6d8ddd60910f47 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -32619,7 +32619,7 @@ - (instancetype)init _imageCodec = @(0); - _frameRate = @(0); + _maxFrameRate = @(0); _bitRate = @(0); @@ -32639,7 +32639,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; auto other = [[MTRCameraAVStreamManagementClusterSnapshotStreamAllocateParams alloc] init]; other.imageCodec = self.imageCodec; - other.frameRate = self.frameRate; + other.maxFrameRate = self.maxFrameRate; other.bitRate = self.bitRate; other.minResolution = self.minResolution; other.maxResolution = self.maxResolution; @@ -32652,7 +32652,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: imageCodec:%@; frameRate:%@; bitRate:%@; minResolution:%@; maxResolution:%@; quality:%@; >", NSStringFromClass([self class]), _imageCodec, _frameRate, _bitRate, _minResolution, _maxResolution, _quality]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: imageCodec:%@; maxFrameRate:%@; bitRate:%@; minResolution:%@; maxResolution:%@; quality:%@; >", NSStringFromClass([self class]), _imageCodec, _maxFrameRate, _bitRate, _minResolution, _maxResolution, _quality]; return descriptionString; } @@ -32668,7 +32668,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.imageCodec = static_cast>(self.imageCodec.unsignedCharValue); } { - encodableStruct.frameRate = self.frameRate.unsignedShortValue; + encodableStruct.maxFrameRate = self.maxFrameRate.unsignedShortValue; } { encodableStruct.bitRate = self.bitRate.unsignedIntValue; diff --git a/src/platform/silabs/CHIPDevicePlatformEvent.h b/src/platform/silabs/CHIPDevicePlatformEvent.h index 8ab1e21b4573bb..090ada64037c6f 100644 --- a/src/platform/silabs/CHIPDevicePlatformEvent.h +++ b/src/platform/silabs/CHIPDevicePlatformEvent.h @@ -26,7 +26,7 @@ #include #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION -#include "wfx_host_events.h" +#include #endif namespace chip { diff --git a/src/platform/silabs/ConfigurationManagerImpl.cpp b/src/platform/silabs/ConfigurationManagerImpl.cpp index 0219852813f28e..3a144eb1160370 100644 --- a/src/platform/silabs/ConfigurationManagerImpl.cpp +++ b/src/platform/silabs/ConfigurationManagerImpl.cpp @@ -31,7 +31,7 @@ #include #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION -#include "wfx_host_events.h" +#include #endif namespace chip { diff --git a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp index 2dd946feb12a6d..0d9d63317ef637 100644 --- a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp +++ b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp @@ -40,7 +40,7 @@ #endif #include "CHIPDevicePlatformConfig.h" -#include "wfx_host_events.h" +#include using namespace ::chip; using namespace ::chip::Inet; diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.h b/src/platform/silabs/NetworkCommissioningWiFiDriver.h index f152edb343cbf2..12986b998736be 100644 --- a/src/platform/silabs/NetworkCommissioningWiFiDriver.h +++ b/src/platform/silabs/NetworkCommissioningWiFiDriver.h @@ -18,7 +18,7 @@ #pragma once #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION #include -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/platform/silabs/PlatformManagerImpl.cpp b/src/platform/silabs/PlatformManagerImpl.cpp index 20d7b94ada5edf..b3d7f80052dd3a 100644 --- a/src/platform/silabs/PlatformManagerImpl.cpp +++ b/src/platform/silabs/PlatformManagerImpl.cpp @@ -135,9 +135,17 @@ void PlatformManagerImpl::_Shutdown() Internal::GenericPlatformManagerImpl_CMSISOS::_Shutdown(); } +} // namespace DeviceLayer +} // namespace chip + #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION -void PlatformManagerImpl::HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData) +// This function needs to be global so it can be used from the platform implementation without depending on the platfrom itself. +// This is a workaround to avoid a circular dependency. +void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData) { + using namespace chip; + using namespace chip::DeviceLayer; + ChipDeviceEvent event; memset(&event, 0, sizeof(event)); event.Type = DeviceEventType::kWFXSystemEvent; @@ -200,9 +208,7 @@ void PlatformManagerImpl::HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wf } } - (void) sInstance.PostEvent(&event); + // TODO: We should add error processing here + (void) PlatformMgr().PostEvent(&event); } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION - -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/silabs/PlatformManagerImpl.h b/src/platform/silabs/PlatformManagerImpl.h index 1abbb9f07f5e7b..dddc491384a86f 100644 --- a/src/platform/silabs/PlatformManagerImpl.h +++ b/src/platform/silabs/PlatformManagerImpl.h @@ -26,10 +26,14 @@ #include #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION -#include "wfx_host_events.h" +#include #endif #include +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData); +#endif + namespace chip { namespace DeviceLayer { @@ -62,9 +66,6 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener public: // ===== Platform-specific members that may be accessed directly by the application. -#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION - void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData); -#endif System::Clock::Timestamp GetStartTime() { return mStartTime; } diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn index 0c2f9032e4bc81..826d8accd974d7 100644 --- a/src/platform/silabs/SiWx917/BUILD.gn +++ b/src/platform/silabs/SiWx917/BUILD.gn @@ -18,7 +18,7 @@ import("${chip_root}/src/platform/device.gni") import("${chip_root}/build/chip/buildconfig_header.gni") import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") import("${chip_root}/third_party/silabs/SiWx917_sdk.gni") import("${chip_root}/third_party/silabs/silabs_board.gni") @@ -30,10 +30,14 @@ if (chip_crypto == "platform") { import("//build_overrides/mbedtls.gni") } -config("siwx917-platform-wifi-config") { - include_dirs = [ "wifi" ] - defines = [] +source_set("logging") { + sources = [ "${chip_root}/src/platform/silabs/Logging.cpp" ] + deps = [ + "${chip_root}/src/platform:platform_base", + "${chip_root}/src/platform/logging:headers", + ] } + static_library("SiWx917") { sources = [ "${silabs_platform_dir}/BLEManagerImpl.h", @@ -45,6 +49,7 @@ static_library("SiWx917") { "${silabs_platform_dir}/ConfigurationManagerImpl.cpp", "${silabs_platform_dir}/ConfigurationManagerImpl.h", "${silabs_platform_dir}/ConnectivityManagerImpl.h", + "${silabs_platform_dir}/ConnectivityManagerImpl_WIFI.cpp", "${silabs_platform_dir}/DiagnosticDataProviderImpl.cpp", "${silabs_platform_dir}/DiagnosticDataProviderImpl.h", "${silabs_platform_dir}/InetPlatformConfig.h", @@ -52,6 +57,8 @@ static_library("SiWx917") { "${silabs_platform_dir}/KeyValueStoreManagerImpl.h", "${silabs_platform_dir}/MigrationManager.cpp", "${silabs_platform_dir}/MigrationManager.h", + "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.cpp", + "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.h", "${silabs_platform_dir}/PlatformManagerImpl.cpp", "${silabs_platform_dir}/PlatformManagerImpl.h", "${silabs_platform_dir}/SilabsConfig.cpp", @@ -66,6 +73,7 @@ static_library("SiWx917") { "../rs911x/rsi_ble_config.h", "../rs911x/wfx_sl_ble_init.cpp", "../rs911x/wfx_sl_ble_init.h", + "SiWxPlatformInterface.h", ] if (chip_enable_ota_requestor) { @@ -94,23 +102,7 @@ static_library("SiWx917") { public_deps += [ "${chip_root}/src/crypto", "${mbedtls_root}:mbedtls", + "${silabs_platform_dir}/wifi:wifi-platform", ] } - - sources += [ - "${silabs_platform_dir}/ConnectivityManagerImpl_WIFI.cpp", - "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.cpp", - "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.h", - "${silabs_platform_dir}/wifi/wfx_host_events.h", - "wifi/wfx_msgs.h", - ] - public_configs = [ ":siwx917-platform-wifi-config" ] -} - -source_set("logging") { - sources = [ "${chip_root}/src/platform/silabs/Logging.cpp" ] - deps = [ - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/platform/logging:headers", - ] } diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index bccb704ad18cab..bce64cbac87ff9 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -20,8 +20,8 @@ #include #include -#include "wfx_host_events.h" #include +#include #ifdef __cplusplus extern "C" { #endif diff --git a/examples/platform/silabs/SiWx917/SiWxPlatformInterface.h b/src/platform/silabs/SiWx917/SiWxPlatformInterface.h similarity index 59% rename from examples/platform/silabs/SiWx917/SiWxPlatformInterface.h rename to src/platform/silabs/SiWx917/SiWxPlatformInterface.h index 879ca3013c7b41..8589db3b3f4484 100644 --- a/examples/platform/silabs/SiWx917/SiWxPlatformInterface.h +++ b/src/platform/silabs/SiWx917/SiWxPlatformInterface.h @@ -27,13 +27,29 @@ extern "C" { #include "sl_si91x_button.h" #include "sl_si91x_button_pin_config.h" #include "sl_si91x_driver_gpio.h" + /** * @brief invoked when button press event is received when in sleep * @param[in] pin_intr GPIO pin interrupt number. * @return none. * @note this is a callback from the Wiseconnect SDK */ -void gpio_uulp_pin_interrupt_callback(uint32_t pin_intr); +void gpio_uulp_pin_interrupt_callback(uint32_t pin_intr) +{ + // UULP_GPIO_2 is used to detect the button 0 press + VerifyOrReturn(pin_intr == RTE_UULP_GPIO_2_PIN, ChipLogError(DeviceLayer, "invalid pin interrupt: %ld", pin_intr)); + sl_status_t status = SL_STATUS_OK; + uint8_t pin_intr_status = sl_si91x_gpio_get_uulp_npss_pin(pin_intr); + if (pin_intr_status == LOW) + { + // BTN_0 is pressed + // NOTE: the GPIO is masked since the interrupt is invoked before scheduler is started, thus this is required to hand over + // control to scheduler, the PIN is unmasked in the power manager flow before going to sleep + status = sl_si91x_gpio_driver_mask_uulp_npss_interrupt(BIT(pin_intr)); + VerifyOrReturn(status == SL_STATUS_OK, ChipLogError(DeviceLayer, "failed to mask interrupt: %ld", status)); + } +} + #endif // SLI_SI91X_MCU_INTERFACE #endif // CHIP_CONFIG_ENABLE_ICD_SERVER #ifdef __cplusplus @@ -64,7 +80,29 @@ inline void sl_si91x_btn_event_handler() * @param[in] none. * @note this requires hardware jumping of the GPIO PINs to work with the baseboard. */ -void sl_si91x_uart_power_requirement_handler(); +void sl_si91x_uart_power_requirement_handler() +{ +#ifdef ENABLE_CHIP_SHELL + // Checking the UULP PIN 1 status to reinit the UART and not allow the device to go to sleep + if (sl_si91x_gpio_get_uulp_npss_pin(RTE_UULP_GPIO_1_PIN)) + { + if (!ps_requirement_added) + { + sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); + ps_requirement_added = true; + } + } + else + { + if (ps_requirement_added) + { + sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); + ps_requirement_added = false; + } + } +#endif // ENABLE_CHIP_SHELL +} + #endif // SLI_SI91X_MCU_INTERFACE #endif // CHIP_CONFIG_ENABLE_ICD_SERVER } // namespace SiWxPlatformInterface diff --git a/src/platform/silabs/SiWx917/wifi/wfx_msgs.h b/src/platform/silabs/SiWx917/wifi/wfx_msgs.h deleted file mode 100644 index b87a7c070716a2..00000000000000 --- a/src/platform/silabs/SiWx917/wifi/wfx_msgs.h +++ /dev/null @@ -1,162 +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. - */ - -#ifndef _WFX_MSGS_H_ -#define _WFX_MSGS_H_ - -#include -/* - * Taken from sl_wfx firmware - so I can re-use. - * I need to do a better job than to use this stuff - * in the CPP files of Matter - */ -typedef struct -{ - uint8_t octet[6]; ///< Table to store a MAC address -} sl_wfx_mac_address_t; -/** - * @brief General Message header structure - * - */ -typedef struct __attribute__((__packed__)) sl_wfx_header_s -{ - uint16_t length; ///< Message length in bytes including this uint16_t. - ///< Maximum value is 8188 but maximum Request size is FW dependent and reported in the - ///< ::sl_wfx_startup_ind_body_t::size_inp_ch_buf. - uint8_t id; ///< Contains the message Id indexed by sl_wfx_general_commands_ids_t or sl_wfx_message_ids_t. - uint8_t info; ///< TODO comment missing -} sl_wfx_header_t; - -/** - * @brief Generic message structure for all requests, confirmations and indications - * - */ -typedef struct __attribute__((__packed__)) sl_wfx_generic_message_s -{ - sl_wfx_header_t header; ///< 4 bytes header - uint8_t body[]; ///< variable size payload of the message -} sl_wfx_generic_message_t; -#define SL_WFX_OPN_SIZE 14 -#define SL_WFX_UID_SIZE 8 -#define SL_WFX_DISABLED_CHANNEL_LIST_SIZE 2 -#define SL_WFX_FIRMWARE_LABEL_SIZE 128 -/** - * @brief Startup Indication message. - * This is the first message sent to the host to confirm boot success. - * It gives detailed information on the HW and FW versions and capabilities - */ -typedef struct __attribute__((__packed__)) sl_wfx_startup_ind_body_s -{ - uint32_t - status; ///< Initialization status. A value of zero indicates the boot is completed successfully (see enum sl_wfx_status_t) - uint16_t hardware_id; ///<=RO misc_read_reg7 register value - uint8_t mac_addr[6]; -} sl_wfx_startup_ind_body_t; - -typedef struct __attribute__((__packed__)) sl_wfx_startup_ind_s -{ - sl_wfx_header_t header; - sl_wfx_startup_ind_body_t body; -} sl_wfx_startup_ind_t; -/** - * @brief Indication message body for sl_wfx_connect_ind_t. - */ -typedef struct __attribute__((__packed__)) sl_wfx_connect_ind_body_s -{ - /** - * @brief Status of the connection request. - * @details WFM_STATUS_SUCCESS: the connection request was completed successfully. - *
any other value: the connection request failed. - *
See sl_wfx_fmac_status_t for enumeration values. - */ - uint32_t status; - /** - * @brief MAC address of the connected access point. - */ - uint8_t mac[6]; - /** - * @brief Channel of the connected access point. - * @details 1 - 13: Channel number. - */ - uint16_t channel; - /** - * @brief Beacon Interval of the connected access point. - */ - uint8_t beacon_interval; - /** - * @brief DTIM period of the connected access point. - * @details 1 - 255: DTIM period. - */ - uint8_t dtim_period; - /** - * @brief Maximum PHY data rate supported by the connection. - * @details See sl_wfx_rate_index_t for enumeration values. - */ - uint16_t max_phy_rate; -} sl_wfx_connect_ind_body_t; - -/** - * @brief Indication message used to signal the completion of a connection operation. - * @details The device will send this indication to signal the connection request initiated - * with sl_wfx_connect_req_t has been completed. The indication is also sent when - * the device autonomously roams to another access point. - * @ingroup WFM_GROUP_MODE_IDLE - */ -typedef struct __attribute__((__packed__)) sl_wfx_connect_ind_s -{ - /** Common message header. */ - sl_wfx_header_t header; - /** Indication message body. */ - sl_wfx_connect_ind_body_t body; -} sl_wfx_connect_ind_t; -/** - * @brief Indication message body for sl_wfx_disconnect_ind_t. - */ -typedef struct __attribute__((__packed__)) sl_wfx_disconnect_ind_body_s -{ - /** - * @brief MAC address of the access point. - */ - uint8_t mac[6]; - /** - * @brief Reason for disconnection. - * @details WFM_DISCONNECTED_REASON_UNSPECIFIED: The device disconnected because of an internal error. - *
WFM_DISCONNECTED_REASON_AP_LOST: The device lost the AP beacons for too long. - *
WFM_DISCONNECTED_REASON_REJECTED: The device was disconnected by the AP. - *
WFM_DISCONNECTED_REASON_LEAVING_BSS: Disconnection was requested through the device API. - *
WFM_DISCONNECTED_REASON_WPA_COUNTERMEASURES: WPA countermeasures triggered a disconnection - *
See sl_wfx_disconnected_reason_t for enumeration values. - */ - uint16_t reason; -} sl_wfx_disconnect_ind_body_t; - -/** - * @brief Indication message used to signal the completion of a disconnection operation. - * @details The device will send this indication to signal the disconnection request initiated - * with sl_wfx_disconnect_req_t has been completed. The indication is also sent when - * the device has lost the connection to an access point and has been unable to regain it. - * @ingroup WFM_GROUP_MODE_STA - */ -typedef struct __attribute__((__packed__)) sl_wfx_disconnect_ind_s -{ - /** Common message header. */ - sl_wfx_header_t header; - /** Indication message body. */ - sl_wfx_disconnect_ind_body_t body; -} sl_wfx_disconnect_ind_t; - -#endif /* _WFX_MSGS_H_ */ diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index b1e50faafca0e0..f39628d4845726 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -20,8 +20,6 @@ import("${chip_root}/src/platform/device.gni") import("${chip_root}/third_party/silabs/efr32_sdk.gni") import("${chip_root}/third_party/silabs/silabs_board.gni") -silabs_platform_dir = "${chip_root}/src/platform/silabs" - assert(chip_device_platform == "efr32") if (chip_enable_openthread) { @@ -32,9 +30,12 @@ if (chip_crypto == "platform") { import("//build_overrides/mbedtls.gni") } -config("efr32-platform-wifi-config") { - include_dirs = [ "wifi" ] - defines = [] +source_set("logging") { + sources = [ "${chip_root}/src/platform/silabs/Logging.cpp" ] + deps = [ + "${chip_root}/src/platform:platform_base", + "${chip_root}/src/platform/logging:headers", + ] } static_library("efr32") { @@ -159,27 +160,8 @@ static_library("efr32") { "${silabs_platform_dir}/ConnectivityManagerImpl_WIFI.cpp", "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.cpp", "${silabs_platform_dir}/NetworkCommissioningWiFiDriver.h", - "${silabs_platform_dir}/wifi/wfx_host_events.h", - "wifi/wfx_msgs.h", ] - if (use_wf200 || use_rs9116) { - sources += [ - "${silabs_platform_dir}/wifi/dhcp_client.cpp", - "wifi/ethernetif.cpp", - "wifi/ethernetif.h", - "wifi/lwip_netif.cpp", - ] - } - - public_configs += [ ":efr32-platform-wifi-config" ] + public_deps += [ "${silabs_platform_dir}/wifi:wifi-platform" ] } } - -source_set("logging") { - sources = [ "${chip_root}/src/platform/silabs/Logging.cpp" ] - deps = [ - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/platform/logging:headers", - ] -} diff --git a/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp b/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp index 4fc7f8d7424cdd..a884071560fb59 100644 --- a/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp @@ -19,17 +19,17 @@ #include #include #include +#include + +#if SL_WIFI +#include +#endif // SL_WIFI extern "C" { #include "btl_interface.h" #include "sl_core.h" -#if SL_WIFI -#include "spi_multiplex.h" -#endif // SL_WIFI } -#include - /// No error, operation OK #define SL_BOOTLOADER_OK 0L diff --git a/src/platform/silabs/wifi/BUILD.gn b/src/platform/silabs/wifi/BUILD.gn new file mode 100644 index 00000000000000..882a66deb4fa9f --- /dev/null +++ b/src/platform/silabs/wifi/BUILD.gn @@ -0,0 +1,150 @@ +# 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/chip.gni") +import("//build_overrides/lwip.gni") +import("${chip_root}/src/platform/device.gni") +import("${chip_root}/third_party/silabs/efr32_sdk.gni") +import("${chip_root}/third_party/silabs/silabs_board.gni") + +declare_args() { + # Wifi related stuff - they are overridden by gn -args="use_wf200=true" + sl_wfx_config_softap = false + sl_wfx_config_scan = true + + # Argument to force enable WPA3 security on rs91x + rs91x_wpa3_transition = true + + #default WiFi SSID + chip_default_wifi_ssid = "" + + #default Wifi Password + chip_default_wifi_psk = "" +} + +if (chip_enable_wifi && !wifi_soc) { + assert(use_rs9116 || use_wf200 || use_SiWx917) + import("${chip_root}/src/platform/silabs/wifi/args.gni") + + if (use_rs9116) { + import("${silabs_platform_dir}/wifi/rs911x/rs911x.gni") + } else if (use_SiWx917) { + import("${silabs_platform_dir}/wifi/rs911x/rs9117.gni") + } + if (use_wf200) { + import("${silabs_platform_dir}/wifi/wf200/wf200.gni") + } +} + +config("wifi-platform-config") { + defines = [] + include_dirs = [] + + if (use_rs9116) { + # All the stuff from wiseconnect + include_dirs += rs911x_inc_plat + } else if (use_SiWx917) { + # All the stuff from wiseconnect + include_dirs += rs9117_inc_plat + } + + if (chip_default_wifi_ssid != "") { + defines += [ + "SL_ONNETWORK_PAIRING=1", + "SL_WIFI_SSID=\"${chip_default_wifi_ssid}\"", + ] + } + if (chip_default_wifi_psk != "") { + assert(chip_default_wifi_ssid != "", + "ssid can't be null if psk is provided") + defines += [ "SL_WIFI_PSK=\"${chip_default_wifi_psk}\"" ] + } + + if (sl_wfx_config_softap) { + defines += [ "SL_WFX_CONFIG_SOFTAP" ] + } + + if (sl_wfx_config_scan) { + defines += [ "SL_WFX_CONFIG_SCAN" ] + } + + if (chip_enable_wifi_ipv4) { + defines += [ "CHIP_DEVICE_CONFIG_ENABLE_IPV4" ] + } + + if (rs91x_wpa3_transition) { + # TODO: Change this macro once WF200 support is provided + defines += [ "WIFI_ENABLE_SECURITY_WPA3_TRANSITION=1" ] + } + + # TODO: This defines needs to be here for the spi_multiplex.h configuration header. + # We need to find a better way to handle this. + if (!disable_lcd) { + defines += [ "DISPLAY_ENABLED" ] + } +} + +source_set("wifi-platform") { + sources = [ + "${silabs_platform_dir}/wifi/WifiInterfaceAbstraction.cpp", + "${silabs_platform_dir}/wifi/WifiInterfaceAbstraction.h", + "${silabs_platform_dir}/wifi/wfx_msgs.h", + ] + + public_configs = [ ":wifi-platform-config" ] + + public_deps = [ + "${chip_root}/src/app/icd/server:icd-server-config", + "${chip_root}/src/inet", + "${chip_root}/src/lib/support", + ] + + if (use_rs9116) { + sources += rs911x_src_plat + + # All the stuff from wiseconnect + sources += rs911x_src_sapi + } else if (use_SiWx917) { + sources += rs911x_src_plat + + # All the stuff from wiseconnect + sources += rs9117_src_sapi + + #add compilation flags for rs991x build. This will be addressed directly in wiseconnect sdk in the next version release of that sdk + } else if (use_wf200) { + sources += wf200_plat_src + } + + if (wifi_soc) { + sources += [ + "${silabs_platform_dir}/wifi/SiWx/WifiInterface.cpp", + "${silabs_platform_dir}/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp", + "${silabs_platform_dir}/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h", + + # Wi-Fi Config - Using the file sdk support until the wiseconnect file is fixed + "${sdk_support_root}/components/service/network_manager/src/sl_net_for_lwip.c", + ] + + public_deps += [ "${lwip_root}:lwip" ] + } + + if (use_wf200 || use_rs9116) { + sources += [ + "${silabs_platform_dir}/wifi/lwip-support/dhcp_client.cpp", + "${silabs_platform_dir}/wifi/lwip-support/ethernetif.cpp", + "${silabs_platform_dir}/wifi/lwip-support/ethernetif.h", + "${silabs_platform_dir}/wifi/lwip-support/lwip_netif.cpp", + ] + } +} diff --git a/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp similarity index 94% rename from examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp rename to src/platform/silabs/wifi/SiWx/WifiInterface.cpp index 962d1720b736cf..0b4135a50a7fd1 100644 --- a/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp @@ -28,22 +28,19 @@ #endif // SL_MATTER_GN_BUILD #include "FreeRTOS.h" -#include "WifiInterfaceAbstraction.h" -#include "WiseconnectInterfaceAbstraction.h" #include "ble_config.h" -#include "dhcp_client.h" #include "event_groups.h" -#include "sl_board_configuration.h" #include "sl_status.h" #include "sl_wifi_device.h" #include "task.h" -#include "wfx_host_events.h" #include #include #include #include #include #include +#include +#include extern "C" { #include "sl_si91x_driver.h" @@ -70,11 +67,10 @@ extern "C" { #if (EXP_BOARD) #include "rsi_bt_common_apis.h" +#include #endif #if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE -#include "SiWxPlatformInterface.h" - #include "rsi_rom_power_save.h" #include "sl_gpio_board.h" #include "sl_si91x_driver_gpio.h" @@ -554,48 +550,6 @@ int32_t sl_wifi_platform_disconnect(void) return sl_net_down((sl_net_interface_t) SL_NET_WIFI_CLIENT_INTERFACE); } -#if CHIP_CONFIG_ENABLE_ICD_SERVER -#if SLI_SI91X_MCU_INTERFACE -void gpio_uulp_pin_interrupt_callback(uint32_t pin_intr) -{ - // UULP_GPIO_2 is used to detect the button 0 press - VerifyOrReturn(pin_intr == RTE_UULP_GPIO_2_PIN, ChipLogError(DeviceLayer, "invalid pin interrupt: %ld", pin_intr)); - sl_status_t status = SL_STATUS_OK; - uint8_t pin_intr_status = sl_si91x_gpio_get_uulp_npss_pin(pin_intr); - if (pin_intr_status == LOW) - { - // BTN_0 is pressed - // NOTE: the GPIO is masked since the interrupt is invoked before scheduler is started, thus this is required to hand over - // control to scheduler, the PIN is unmasked in the power manager flow before going to sleep - status = sl_si91x_gpio_driver_mask_uulp_npss_interrupt(BIT(pin_intr)); - VerifyOrReturn(status == SL_STATUS_OK, ChipLogError(DeviceLayer, "failed to mask interrupt: %ld", status)); - } -} - -void chip::DeviceLayer::Silabs::SiWxPlatformInterface::sl_si91x_uart_power_requirement_handler(void) -{ -#ifdef ENABLE_CHIP_SHELL - // Checking the UULP PIN 1 status to reinit the UART and not allow the device to go to sleep - if (sl_si91x_gpio_get_uulp_npss_pin(RTE_UULP_GPIO_1_PIN)) - { - if (!ps_requirement_added) - { - sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); - ps_requirement_added = true; - } - } - else - { - if (ps_requirement_added) - { - sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); - ps_requirement_added = false; - } - } -#endif // ENABLE_CHIP_SHELL -} -#endif // SLI_SI91X_MCU_INTERFACE - /****************************************************************** * @fn wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) * @brief @@ -626,7 +580,6 @@ int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_ return status; } -#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER */ sl_status_t show_scan_results(sl_wifi_scan_result_t * scan_result) { diff --git a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.cpp b/src/platform/silabs/wifi/WifiInterfaceAbstraction.cpp similarity index 92% rename from examples/platform/silabs/wifi/WifiInterfaceAbstraction.cpp rename to src/platform/silabs/wifi/WifiInterfaceAbstraction.cpp index cd041d452ffe64..430b9bbddb7d38 100644 --- a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.cpp +++ b/src/platform/silabs/wifi/WifiInterfaceAbstraction.cpp @@ -17,14 +17,12 @@ // SL MATTER WI-FI INTERFACE -#include "WifiInterfaceAbstraction.h" #include "silabs_utils.h" -#include "wfx_host_events.h" #include #include #include #include -#include +#include #include #include #include @@ -35,6 +33,10 @@ using namespace chip::DeviceLayer; #define CONVERT_SEC_TO_MS(TimeInS) (TimeInS * 1000) +// TODO: This is a workaround because we depend on the platform lib which depends on the platform implementation. +// As such we can't depend on the platform here as well +extern void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData); + namespace { constexpr uint8_t kWlanMinRetryIntervalsInSec = 1; @@ -83,7 +85,7 @@ void sl_matter_wifi_task_started(void) wfx_get_wifi_mac_addr(SL_WFX_STA_INTERFACE, &mac); memcpy(&evt.body.mac_addr[0], &mac.octet[0], MAC_ADDRESS_FIRST_OCTET); - PlatformMgrImpl().HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); + HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); } /*********************************************************************************** @@ -110,7 +112,7 @@ void wfx_connected_notify(int32_t status, sl_wfx_mac_address_t * ap) #endif memcpy(&evt.body.mac[0], &ap->octet[0], MAC_ADDRESS_FIRST_OCTET); - PlatformMgrImpl().HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); + HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); } /************************************************************************************** @@ -128,7 +130,7 @@ void wfx_disconnected_notify(int32_t status) evt.header.id = SL_WFX_DISCONNECT_IND_ID; evt.header.length = sizeof evt; evt.body.reason = status; - PlatformMgrImpl().HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); + HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt); } /************************************************************************************** @@ -145,7 +147,7 @@ void wfx_ipv6_notify(int got_ip) memset(&eventData, 0, sizeof(eventData)); eventData.header.id = got_ip ? IP_EVENT_GOT_IP6 : IP_EVENT_STA_LOST_IP; eventData.header.length = sizeof(eventData.header); - PlatformMgrImpl().HandleWFXSystemEvent(IP_EVENT, &eventData); + HandleWFXSystemEvent(IP_EVENT, &eventData); } /************************************************************************************** @@ -162,7 +164,7 @@ void wfx_ip_changed_notify(int got_ip) memset(&eventData, 0, sizeof(eventData)); eventData.header.id = got_ip ? IP_EVENT_STA_GOT_IP : IP_EVENT_STA_LOST_IP; eventData.header.length = sizeof(eventData.header); - PlatformMgrImpl().HandleWFXSystemEvent(IP_EVENT, &eventData); + HandleWFXSystemEvent(IP_EVENT, &eventData); } /************************************************************************************** diff --git a/src/platform/silabs/wifi/wfx_host_events.h b/src/platform/silabs/wifi/WifiInterfaceAbstraction.h similarity index 69% rename from src/platform/silabs/wifi/wfx_host_events.h rename to src/platform/silabs/wifi/WifiInterfaceAbstraction.h index 38808610ee74fe..f6364d040e5189 100644 --- a/src/platform/silabs/wifi/wfx_host_events.h +++ b/src/platform/silabs/wifi/WifiInterfaceAbstraction.h @@ -14,9 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #pragma once +#include +#include +#include +#include +#include + #include "sl_status.h" #include @@ -26,14 +31,18 @@ #include "lwip/netifapi.h" #include "lwip/tcpip.h" -#include "wfx_msgs.h" - #if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) #include "rsi_common_apis.h" #include "sl_si91x_types.h" #include "sl_wifi_constants.h" #include "sl_wifi_device.h" +/* + * Interface to RSI Sapis + */ + +#define WFX_RSI_DHCP_POLL_INTERVAL (250) /* Poll interval in ms for DHCP */ + // MAX SSID LENGTH excluding NULL character #define WFX_MAX_SSID_LENGTH (32) // MAX PASSKEY LENGTH including NULL character @@ -46,6 +55,7 @@ #define WFX_MAX_PASSKEY_LENGTH (64) #endif // (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) +#define MAX_JOIN_RETRIES_COUNT (5) #define BSSID_LEN (6) #define MAC_ADDRESS_FIRST_OCTET (6) #define CONNECTION_STATUS_SUCCESS (1) @@ -61,6 +71,34 @@ // TASK and Interrupt Macros #define SUCCESS_STATUS (1) +enum class WifiState : uint16_t +{ + kStationInit = (1 << 0), + kAPReady = (1 << 1), + kStationProvisioned = (1 << 2), + kStationConnecting = (1 << 3), + kStationConnected = (1 << 4), + kStationDhcpDone = (1 << 6), /* Requested to do DHCP after conn */ + kStationMode = (1 << 7), /* Enable Station Mode */ + kAPMode = (1 << 8), /* Enable AP Mode */ + kStationReady = (kStationConnected | kStationDhcpDone), + kStationStarted = (1 << 9), /* RSI task started */ + kScanStarted = (1 << 10), /* Scan Started */ +}; + +enum class WifiEvent : uint8_t +{ + kStationConnect = 0, + kStationDisconnect = 1, + kAPStart = 2, + kAPStop = 3, + kScan = 4, /* This is used as scan result and start */ + kStationStartJoin = 5, + kStationDoDhcp = 6, + kStationDhcpDone = 7, + kStationDhcpPoll = 8 +}; + typedef enum { WIFI_EVENT, @@ -137,6 +175,29 @@ typedef enum } sl_wfx_interface_t; #endif +typedef struct wfx_rsi_s +{ + chip::BitFlags dev_state; + uint16_t ap_chan; /* The chan our STA is using */ + wfx_wifi_provision_t sec; +#ifdef SL_WFX_CONFIG_SCAN + void (*scan_cb)(wfx_wifi_scan_result_t *); + char * scan_ssid; /* Which one are we scanning for */ + size_t scan_ssid_length; +#endif +#ifdef SL_WFX_CONFIG_SOFTAP + sl_wfx_mac_address_t softap_mac; +#endif + sl_wfx_mac_address_t sta_mac; + sl_wfx_mac_address_t ap_mac; /* To which our STA is connected */ + sl_wfx_mac_address_t ap_bssid; /* To which our STA is connected */ + uint16_t join_retries; + uint8_t ip4_addr[4]; /* Not sure if this is enough */ +} WfxRsi_t; + +// TODO: We shouldn't need to have access to a global variable in the interface here +extern WfxRsi_t wfx_rsi; + sl_status_t wfx_wifi_start(void); void wfx_enable_sta_mode(void); void wfx_get_wifi_mac_addr(sl_wfx_interface_t interface, sl_wfx_mac_address_t * addr); @@ -203,6 +264,32 @@ sl_status_t wfx_power_save(); #endif /* SL_ICD_ENABLED */ #endif /* RS911X_WIFI */ +void sl_matter_wifi_task(void * arg); + +#if CHIP_DEVICE_CONFIG_ENABLE_IPV4 +void wfx_ip_changed_notify(int got_ip); +#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ + +int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap); +int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t * extra_info); +int32_t wfx_rsi_reset_count(); +int32_t sl_wifi_platform_disconnect(); + +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#if SLI_SI917 +int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); +#else +int32_t wfx_rsi_power_save(); +#endif /* SLI_SI917 */ +#endif /* SL_ICD_ENABLED */ + +/** + * @brief Posts an event to the Wi-Fi task + * + * @param[in] event Event to process. + */ +void sl_matter_wifi_post_event(WifiEvent event); + #ifdef __cplusplus extern "C" { #endif diff --git a/src/platform/silabs/wifi_args.gni b/src/platform/silabs/wifi/args.gni similarity index 100% rename from src/platform/silabs/wifi_args.gni rename to src/platform/silabs/wifi/args.gni diff --git a/src/platform/silabs/wifi/dhcp_client.cpp b/src/platform/silabs/wifi/lwip-support/dhcp_client.cpp similarity index 98% rename from src/platform/silabs/wifi/dhcp_client.cpp rename to src/platform/silabs/wifi/lwip-support/dhcp_client.cpp index a219430762cf50..a16064eb1d8b08 100644 --- a/src/platform/silabs/wifi/dhcp_client.cpp +++ b/src/platform/silabs/wifi/lwip-support/dhcp_client.cpp @@ -23,10 +23,7 @@ #include "dhcp_client.h" #include "lwip/dhcp.h" -#include "wfx_host_events.h" - -#include "FreeRTOS.h" -#include "event_groups.h" +#include #include diff --git a/src/platform/silabs/wifi/dhcp_client.h b/src/platform/silabs/wifi/lwip-support/dhcp_client.h similarity index 100% rename from src/platform/silabs/wifi/dhcp_client.h rename to src/platform/silabs/wifi/lwip-support/dhcp_client.h diff --git a/src/platform/silabs/efr32/wifi/ethernetif.cpp b/src/platform/silabs/wifi/lwip-support/ethernetif.cpp similarity index 99% rename from src/platform/silabs/efr32/wifi/ethernetif.cpp rename to src/platform/silabs/wifi/lwip-support/ethernetif.cpp index d6123d2ead0301..7e880f62e9a36b 100644 --- a/src/platform/silabs/efr32/wifi/ethernetif.cpp +++ b/src/platform/silabs/wifi/lwip-support/ethernetif.cpp @@ -21,12 +21,6 @@ #include #include -#include "em_bus.h" -#include "em_cmu.h" -#include "em_gpio.h" -#include "em_ldma.h" -#include "em_usart.h" - #ifndef WF200_WIFI #include "FreeRTOS.h" #include "event_groups.h" @@ -50,7 +44,7 @@ extern "C" { #endif // (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) #endif // WF200_WIFI -#include "wfx_host_events.h" +#include #ifdef WF200_WIFI #include "sl_wfx.h" #endif diff --git a/src/platform/silabs/efr32/wifi/ethernetif.h b/src/platform/silabs/wifi/lwip-support/ethernetif.h similarity index 100% rename from src/platform/silabs/efr32/wifi/ethernetif.h rename to src/platform/silabs/wifi/lwip-support/ethernetif.h diff --git a/src/platform/silabs/efr32/wifi/lwip_netif.cpp b/src/platform/silabs/wifi/lwip-support/lwip_netif.cpp similarity index 94% rename from src/platform/silabs/efr32/wifi/lwip_netif.cpp rename to src/platform/silabs/wifi/lwip-support/lwip_netif.cpp index b6c523c636a2a5..3b8dea41ccab09 100644 --- a/src/platform/silabs/efr32/wifi/lwip_netif.cpp +++ b/src/platform/silabs/wifi/lwip-support/lwip_netif.cpp @@ -19,23 +19,13 @@ #include #include -#include "em_bus.h" -#include "em_cmu.h" -#include "em_gpio.h" -#include "em_ldma.h" -#include "em_usart.h" - -#include "wfx_host_events.h" +#include #include "dhcp_client.h" #include "ethernetif.h" -#include "FreeRTOS.h" -#include "event_groups.h" -#include "task.h" - #include -#include + using namespace ::chip; using namespace ::chip::DeviceLayer; diff --git a/examples/platform/silabs/efr32/rs911x/Rsi91xWifiInterface.cpp b/src/platform/silabs/wifi/rs911x/WifiInterface.cpp similarity index 98% rename from examples/platform/silabs/efr32/rs911x/Rsi91xWifiInterface.cpp rename to src/platform/silabs/wifi/rs911x/WifiInterface.cpp index 5513ee37335319..c918b3af362196 100644 --- a/examples/platform/silabs/efr32/rs911x/Rsi91xWifiInterface.cpp +++ b/src/platform/silabs/wifi/rs911x/WifiInterface.cpp @@ -15,24 +15,20 @@ * 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 "lwip/nd6.h" +#include "silabs_utils.h" #include "sl_status.h" #include -// TODO Fix include order issue #33120 -#include "wfx_host_events.h" +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef __cplusplus extern "C" { -#endif #include "rsi_bootup_config.h" #include "rsi_common_apis.h" #include "rsi_data_types.h" @@ -45,21 +41,7 @@ extern "C" { #include "rsi_wlan_apis.h" #include "rsi_wlan_config.h" #include "rsi_wlan_non_rom.h" -#ifdef __cplusplus } -#endif - -#include "WifiInterfaceAbstraction.h" -#include "WiseconnectInterfaceAbstraction.h" -#include "dhcp_client.h" -#include "ethernetif.h" -#include "lwip/nd6.h" -#include "silabs_utils.h" - -#include -#include -#include -#include using WifiStateFlags = chip::BitFlags; diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c b/src/platform/silabs/wifi/rs911x/platform/efx32_ncp_host.c similarity index 96% rename from examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c rename to src/platform/silabs/wifi/rs911x/platform/efx32_ncp_host.c index 0a2fad7d0deb6c..c7173763d5f96c 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c +++ b/src/platform/silabs/wifi/rs911x/platform/efx32_ncp_host.c @@ -26,9 +26,11 @@ #include "sl_constants.h" #include "sl_rsi_utility.h" #include "sl_si91x_host_interface.h" +#include "sl_si91x_ncp_utility.h" #include "sl_si91x_status.h" #include "sl_status.h" #include "sl_wifi_constants.h" +#include #include #include @@ -40,9 +42,6 @@ #include "sl_board_control.h" #endif // SL_BOARD_NAME -#include "sl_si91x_ncp_utility.h" -#include "spi_multiplex.h" - static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * userParam); uint32_t rx_ldma_channel; diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c b/src/platform/silabs/wifi/rs911x/platform/efx_spi.c similarity index 98% rename from examples/platform/silabs/efr32/rs911x/hal/efx_spi.c rename to src/platform/silabs/wifi/rs911x/platform/efx_spi.c index 75f1edcd55fd9d..a339f711a41f35 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c +++ b/src/platform/silabs/wifi/rs911x/platform/efx_spi.c @@ -18,31 +18,23 @@ /** * Includes */ -#include -#include -#include #include "FreeRTOS.h" -#include "event_groups.h" -#include "semphr.h" -#include "task.h" - -#include "dmadrv.h" -#include "em_chip.h" #include "em_cmu.h" -#include "em_core.h" -#include "em_device.h" -#include "em_gpio.h" -#include "em_ldma.h" +#include "em_eusart.h" #include "gpiointerrupt.h" +#include "rsi_board_configuration.h" +#include "rsi_driver.h" +#include "semphr.h" +#include "silabs_utils.h" #include "sl_device_init_clocks.h" #include "sl_device_init_hfxo.h" +#include "sl_spidrv_eusart_exp_config.h" #include "sl_spidrv_instances.h" #include "sl_status.h" #include "spidrv.h" - -#include "silabs_utils.h" -#include "spi_multiplex.h" +#include "task.h" +#include #ifdef SL_BOARD_NAME #include "sl_board_control.h" @@ -52,9 +44,6 @@ #include "sl_power_manager.h" #endif -#include "rsi_board_configuration.h" -#include "rsi_driver.h" - #if SL_BTLCTRL_MUX #include "btl_interface.h" #endif // SL_BTLCTRL_MUX @@ -66,10 +55,6 @@ #include "sl_mx25_flash_shutdown_usart_config.h" #endif // SL_MX25CTRL_MUX -#include "em_eusart.h" -#include "sl_spidrv_eusart_exp_config.h" -#include "spi_multiplex.h" - #define SL_SPIDRV_HANDLE sl_spidrv_eusart_exp_handle #define SL_SPIDRV_EXP_BITRATE_MULTIPLEXED SL_SPIDRV_EUSART_EXP_BITRATE diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_board_configuration.h b/src/platform/silabs/wifi/rs911x/platform/rsi_board_configuration.h similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_board_configuration.h rename to src/platform/silabs/wifi/rs911x/platform/rsi_board_configuration.h diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal.h b/src/platform/silabs/wifi/rs911x/platform/rsi_hal.h similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_hal.h rename to src/platform/silabs/wifi/rs911x/platform/rsi_hal.h diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c b/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_interrupt.c similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c rename to src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_interrupt.c diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_ioports.c b/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_ioports.c similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_ioports.c rename to src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_ioports.c diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_rtc.c b/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_rtc.c similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_rtc.c rename to src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_rtc.c diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_timer.c b/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_timer.c similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_timer.c rename to src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_timer.c diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h b/src/platform/silabs/wifi/rs911x/platform/sl_board_configuration.h similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h rename to src/platform/silabs/wifi/rs911x/platform/sl_board_configuration.h diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration_SiWx917.h b/src/platform/silabs/wifi/rs911x/platform/sl_board_configuration_SiWx917.h similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration_SiWx917.h rename to src/platform/silabs/wifi/rs911x/platform/sl_board_configuration_SiWx917.h diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c b/src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.c similarity index 100% rename from examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c rename to src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.c diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.h b/src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.h similarity index 84% rename from examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.h rename to src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.h index 0bd8dae7641807..b434e35f82dbbd 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.h +++ b/src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.h @@ -29,7 +29,9 @@ #include "semphr.h" #include "silabs_utils.h" #include "sl_status.h" -#include "spi_multiplex.h" + +// TODO: This is a WF200 specific include. It is not clear why we need this in the 917 NCP files. +#include #if defined(CHIP_9117) #include "em_usart.h" @@ -46,4 +48,4 @@ sl_status_t spi_board_init(void); extern uint32_t rx_ldma_channel; extern uint32_t tx_ldma_channel; -#endif // SL_SI91X_NCP_UTILITY_H \ No newline at end of file +#endif // SL_SI91X_NCP_UTILITY_H diff --git a/examples/platform/silabs/efr32/rs911x/rs9117.gni b/src/platform/silabs/wifi/rs911x/rs9117.gni similarity index 74% rename from examples/platform/silabs/efr32/rs911x/rs9117.gni rename to src/platform/silabs/wifi/rs911x/rs9117.gni index 87e3caeeb74ad5..cbeaf98698c705 100644 --- a/examples/platform/silabs/efr32/rs911x/rs9117.gni +++ b/src/platform/silabs/wifi/rs911x/rs9117.gni @@ -17,22 +17,22 @@ import("//build_overrides/efr32_sdk.gni") import("${silabs_sdk_build_root}/efr32_sdk.gni") rs911x_src_plat = [ - "${chip_root}/examples/platform/silabs/SiWx917/SiWxWifiInterface.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/WifiInterfaceAbstraction.cpp", - "${silabs_common_plat_dir}/wifi/WiseconnectInterfaceAbstraction.cpp", -] + "${chip_root}/src/platform/silabs/wifi/SiWx/WifiInterface.cpp", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_interrupt.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/sl_si91x_ncp_utility.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/sl_board_configuration.h", + "${chip_root}/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp", + "${chip_root}/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h", + + # TODO: We shouldn't need a file form the WF200 for the SiWx917 NCP builds + "${chip_root}/src/platform/silabs/wifi/wf200/platform/spi_multiplex.h", -rs9117_inc_plat = [ - "${examples_plat_dir}/rs911x", - "${examples_plat_dir}/rs911x/hal", - "${wifi_sdk_root}/components/si91x/ble/inc", - "${silabs_common_plat_dir}/wifi", + # TODO : We should be using the file from the Wiseconnect SDK and not our copy of it. + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/efx32_ncp_host.c", ] -rs911x_cflags = [ "-Wno-empty-body" ] +rs9117_inc_plat = [ "${wifi_sdk_root}/components/si91x/ble/inc" ] + rs9117_src_sapi = [ # sl_si91x_wireless component "${wifi_sdk_root}/components/device/silabs/si91x/wireless/src/sl_si91x_driver.c", diff --git a/examples/platform/silabs/efr32/rs911x/rs911x.gni b/src/platform/silabs/wifi/rs911x/rs911x.gni similarity index 80% rename from examples/platform/silabs/efr32/rs911x/rs911x.gni rename to src/platform/silabs/wifi/rs911x/rs911x.gni index 068d5abdb349c7..3daba8b049c802 100644 --- a/examples/platform/silabs/efr32/rs911x/rs911x.gni +++ b/src/platform/silabs/wifi/rs911x/rs911x.gni @@ -17,13 +17,14 @@ import("//build_overrides/efr32_sdk.gni") import("${silabs_sdk_build_root}/efr32_sdk.gni") rs911x_src_plat = [ - "${examples_plat_dir}/rs911x/Rsi91xWifiInterface.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/WifiInterfaceAbstraction.cpp", - "${silabs_common_plat_dir}/wifi/WiseconnectInterfaceAbstraction.cpp", + "${chip_root}/src/platform/silabs/wifi/rs911x/WifiInterface.cpp", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_interrupt.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_ioports.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_hal_mcu_timer.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/efx_spi.c", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_board_configuration.h", + "${chip_root}/src/platform/silabs/wifi/rs911x/platform/rsi_hal.h", + "${chip_root}/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp", ] # @@ -67,11 +68,4 @@ rs911x_src_sapi = [ "${wiseconnect_sdk_root}/sapi/network/socket/rsi_socket_rom.c", ] -rs911x_cflags = [ "-Wno-empty-body" ] - -rs911x_inc_plat = [ - "${examples_plat_dir}/rs911x", - "${examples_plat_dir}/rs911x/hal", - "${wiseconnect_sdk_root}/sapi/include", - "${silabs_common_plat_dir}/wifi", -] +rs911x_inc_plat = [ "${wiseconnect_sdk_root}/sapi/include" ] diff --git a/examples/platform/silabs/efr32/rs911x/rsi_wlan_config.h b/src/platform/silabs/wifi/rs911x/rsi_wlan_config.h similarity index 100% rename from examples/platform/silabs/efr32/rs911x/rsi_wlan_config.h rename to src/platform/silabs/wifi/rs911x/rsi_wlan_config.h diff --git a/examples/platform/silabs/efr32/wf200/Wf200WifiInterface.cpp b/src/platform/silabs/wifi/wf200/WifiInterface.cpp similarity index 98% rename from examples/platform/silabs/efr32/wf200/Wf200WifiInterface.cpp rename to src/platform/silabs/wifi/wf200/WifiInterface.cpp index 0aec9baa4dccae..fef3cb3a63a022 100644 --- a/examples/platform/silabs/efr32/wf200/Wf200WifiInterface.cpp +++ b/src/platform/silabs/wifi/wf200/WifiInterface.cpp @@ -15,28 +15,26 @@ * limitations under the License. */ -#include "AppConfig.h" #include "FreeRTOS.h" -#include "dhcp_client.h" #include "em_bus.h" #include "em_cmu.h" #include "em_gpio.h" #include "em_ldma.h" #include "em_usart.h" -#include "ethernetif.h" #include "event_groups.h" #include "gpiointerrupt.h" -#include "sl_wfx_board.h" #include "sl_wfx_cmd_api.h" #include "sl_wfx_constants.h" -#include "sl_wfx_host.h" -#include "sl_wfx_task.h" #include "task.h" -#include "wfx_host_events.h" #include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -44,6 +42,10 @@ using namespace ::chip; using namespace ::chip::DeviceLayer; +// TODO: This is a workaround because we depend on the platform lib which depends on the platform implementation. +// As such we can't depend on the platform here as well +extern void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData); + /* wfxRsi Task will use as its stack */ StackType_t wfxEventTaskStack[1024] = { 0 }; @@ -333,7 +335,7 @@ sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * event_payload) /******** INDICATION ********/ case SL_WFX_STARTUP_IND_ID: { ChipLogProgress(DeviceLayer, "startup completed."); - PlatformMgrImpl().HandleWFXSystemEvent(WIFI_EVENT, event_payload); + HandleWFXSystemEvent(WIFI_EVENT, event_payload); break; } case SL_WFX_CONNECT_IND_ID: { diff --git a/examples/platform/silabs/efr32/wf200/efr_spi.c b/src/platform/silabs/wifi/wf200/platform/efr_spi.c similarity index 99% rename from examples/platform/silabs/efr32/wf200/efr_spi.c rename to src/platform/silabs/wifi/wf200/platform/efr_spi.c index b5a31cbaafd22c..6f80fc83d90984 100644 --- a/examples/platform/silabs/efr32/wf200/efr_spi.c +++ b/src/platform/silabs/wifi/wf200/platform/efr_spi.c @@ -14,14 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include -#include - -#include "AppConfig.h" #include "FreeRTOS.h" -#include "semphr.h" - #include "dmadrv.h" #include "em_bus.h" #include "em_cmu.h" @@ -29,6 +22,7 @@ #include "em_ldma.h" #include "em_usart.h" #include "gpiointerrupt.h" +#include "semphr.h" #include "sl_spidrv_exp_config.h" #include "sl_spidrv_instances.h" #include "sl_wfx.h" @@ -38,8 +32,10 @@ #include "sl_wfx_host_api.h" #include "sl_wfx_task.h" #include "spidrv.h" - -#include "spi_multiplex.h" +#include +#include +#include +#include #if defined(SL_CATALOG_POWER_MANAGER_PRESENT) #include "sl_power_manager.h" @@ -441,6 +437,8 @@ sl_status_t sl_wfx_host_post_lcd_spi_transfer(void) #endif // SL_SPICTRL_MUX return SL_STATUS_OK; } +#else +#error still not working #endif // SL_LCDCTRL_MUX #if SL_UARTCTRL_MUX diff --git a/examples/platform/silabs/efr32/sl_custom_board.h b/src/platform/silabs/wifi/wf200/platform/sl_custom_board.h similarity index 100% rename from examples/platform/silabs/efr32/sl_custom_board.h rename to src/platform/silabs/wifi/wf200/platform/sl_custom_board.h diff --git a/examples/platform/silabs/efr32/wf200/sl_wfx_board.h b/src/platform/silabs/wifi/wf200/platform/sl_wfx_board.h similarity index 100% rename from examples/platform/silabs/efr32/wf200/sl_wfx_board.h rename to src/platform/silabs/wifi/wf200/platform/sl_wfx_board.h diff --git a/examples/platform/silabs/efr32/wf200/sl_wfx_host.h b/src/platform/silabs/wifi/wf200/platform/sl_wfx_host.h similarity index 100% rename from examples/platform/silabs/efr32/wf200/sl_wfx_host.h rename to src/platform/silabs/wifi/wf200/platform/sl_wfx_host.h diff --git a/examples/platform/silabs/efr32/wf200/sl_wfx_task.c b/src/platform/silabs/wifi/wf200/platform/sl_wfx_task.c similarity index 100% rename from examples/platform/silabs/efr32/wf200/sl_wfx_task.c rename to src/platform/silabs/wifi/wf200/platform/sl_wfx_task.c diff --git a/examples/platform/silabs/efr32/wf200/sl_wfx_task.h b/src/platform/silabs/wifi/wf200/platform/sl_wfx_task.h similarity index 100% rename from examples/platform/silabs/efr32/wf200/sl_wfx_task.h rename to src/platform/silabs/wifi/wf200/platform/sl_wfx_task.h diff --git a/examples/platform/silabs/efr32/spi_multiplex.h b/src/platform/silabs/wifi/wf200/platform/spi_multiplex.h similarity index 100% rename from examples/platform/silabs/efr32/spi_multiplex.h rename to src/platform/silabs/wifi/wf200/platform/spi_multiplex.h diff --git a/examples/platform/silabs/efr32/wf200/wf200_init.c b/src/platform/silabs/wifi/wf200/platform/wf200_init.c similarity index 100% rename from examples/platform/silabs/efr32/wf200/wf200_init.c rename to src/platform/silabs/wifi/wf200/platform/wf200_init.c diff --git a/src/platform/silabs/wifi/wf200/wf200.gni b/src/platform/silabs/wifi/wf200/wf200.gni new file mode 100644 index 00000000000000..437f9def5d47bb --- /dev/null +++ b/src/platform/silabs/wifi/wf200/wf200.gni @@ -0,0 +1,30 @@ +# 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/chip.gni") +import("//build_overrides/efr32_sdk.gni") +import("${silabs_sdk_build_root}/efr32_sdk.gni") + +wf200_plat_src = [ + "${chip_root}/src/platform/silabs/wifi/wf200/WifiInterface.cpp", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_wfx_task.c", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/wf200_init.c", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/efr_spi.c", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_wfx_board.h", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_wfx_host.h", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_wfx_task.h", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_custom_board.h", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/spi_multiplex.h", + "${chip_root}/src/platform/silabs/wifi/wf200/platform/sl_wfx_board.h", +] diff --git a/src/platform/silabs/efr32/wifi/wfx_msgs.h b/src/platform/silabs/wifi/wfx_msgs.h similarity index 100% rename from src/platform/silabs/efr32/wifi/wfx_msgs.h rename to src/platform/silabs/wifi/wfx_msgs.h diff --git a/examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.cpp b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp similarity index 99% rename from examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.cpp rename to src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp index 3c2ec032a8ca3b..2266989b906f79 100644 --- a/examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.cpp +++ b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp @@ -14,10 +14,9 @@ * limitations under the License. */ -#include "WiseconnectInterfaceAbstraction.h" #include #include -#include +#include namespace { diff --git a/examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.h b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h similarity index 95% rename from examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.h rename to src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h index d847e99fb575a5..9073a02ef64b5b 100644 --- a/examples/platform/silabs/wifi/WiseconnectInterfaceAbstraction.h +++ b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h @@ -15,12 +15,11 @@ */ #pragma once -#include "WifiInterfaceAbstraction.h" #include #include #include +#include #include -#include #define WFX_RSI_DHCP_POLL_INTERVAL (250) /* Poll interval in ms for DHCP */ #define GET_IPV6_SUCCESS (1) diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 4bf1aa55217c57..ceeaaa60531b73 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -54,9 +54,7 @@ using namespace Crypto; using namespace Messaging; using namespace Protocols::SecureChannel; -const char kSpake2pContext[] = "CHIP PAKE V1 Commissioning"; -const char kSpake2pI2RSessionInfo[] = "Commissioning I2R Key"; -const char kSpake2pR2ISessionInfo[] = "Commissioning R2I Key"; +const char kSpake2pContext[] = "CHIP PAKE V1 Commissioning"; // Amounts of time to allow for server-side processing of messages. // diff --git a/src/protocols/secure_channel/PASESession.h b/src/protocols/secure_channel/PASESession.h index 92b4ee3d8b991c..a24539eaf508e7 100644 --- a/src/protocols/secure_channel/PASESession.h +++ b/src/protocols/secure_channel/PASESession.h @@ -43,7 +43,9 @@ #include namespace chip { - +namespace Testing { +class TestPASESession; +} extern const char kSpake2pI2RSessionInfo[]; extern const char kSpake2pR2ISessionInfo[]; @@ -174,6 +176,7 @@ class DLL_EXPORT PASESession : public Messaging::UnsolicitedMessageHandler, kInvalidKeyConfirmation = 0x00, kUnexpected = 0xff, }; + friend class Testing::TestPASESession; CHIP_ERROR Init(SessionManager & sessionManager, uint32_t setupCode, SessionEstablishmentDelegate * delegate); diff --git a/src/protocols/secure_channel/tests/FuzzPASE_PW.cpp b/src/protocols/secure_channel/tests/FuzzPASE_PW.cpp index d3dc5998112f2a..0ce3d2d1817857 100644 --- a/src/protocols/secure_channel/tests/FuzzPASE_PW.cpp +++ b/src/protocols/secure_channel/tests/FuzzPASE_PW.cpp @@ -15,16 +15,17 @@ #include #include #include +#include -namespace { +namespace chip { +namespace Testing { -using namespace chip; using namespace std; -using namespace chip::Crypto; +using namespace Crypto; using namespace fuzztest; -using namespace chip::Transport; -using namespace chip::Messaging; +using namespace Transport; +using namespace Messaging; using namespace System::Clock::Literals; // TODO: #35369 Refactor the classes below to Fixtures once Errors related to FuzzTest Fixtures are resolved @@ -113,6 +114,27 @@ class TestPASESession : public FuzzLoopbackMessagingContext TestSecurePairingDelegate & delegateCommissioner, TestSecurePairingDelegate & delegateAccessory, const Spake2pVerifier & verifier, uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t SetUpPINCode); + + void FuzzHandlePBKDFParamRequest(vector fuzzPBKDFLocalRandomData, uint32_t fuzzInitiatorSessionId, + bool fuzzHavePBKDFParameters); + + void FuzzHandlePBKDFParamResponse(vector fuzzPBKDFLocalRandomDataInitiator, + vector fuzzPBKDFLocalRandomDataResponder, uint32_t fuzzResponderSessionId, + const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, bool fuzzHavePBKDFParameters); + + void FuzzHandlePake1(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & pA); + + void FuzzHandlePake2(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & pB, const vector & cB); + + void FuzzHandlePake3(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & cA); + + CHIP_ERROR CallAllocateSecureSession(SessionManager & sessionManager, PASESession & pairing) + { + return pairing.AllocateSecureSession(sessionManager); + } }; class TemporarySessionManager @@ -217,8 +239,11 @@ void PASESession_Bounded(const uint32_t fuzzedSetupPasscode, const vector>().WithMinSize(kSpake2p_Min_PBKDF_Salt_Length).WithMaxSize(kSpake2p_Max_PBKDF_Salt_Length), + // fuzzedPBKDF2Iter InRange(kSpake2p_Min_PBKDF_Iterations, kSpake2p_Max_PBKDF_Iterations)); /* -------------------------------------------------------------------------------------------*/ @@ -245,7 +270,13 @@ void PASESession_Unbounded(const uint32_t fuzzedSetupPasscode, const vector(), Arbitrary>(), Arbitrary()); + .WithDomains( + // fuzzedSetupPasscode + Arbitrary(), + // fuzzedSalt + Arbitrary>(), + // fuzzedPBKDF2Iter + Arbitrary()); /* -------------------------------------------------------------------------------------------*/ // In This FuzzTest, the Spake2pVerifier is fuzzed. @@ -271,9 +302,17 @@ void FuzzSpake2pVerifier(const vector & aW0, const vector & aL fuzzedSpake2pVerifier, fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode); } FUZZ_TEST(FuzzPASE_PW, FuzzSpake2pVerifier) - .WithDomains(Arbitrary>().WithMaxSize(kP256_FE_Length), - Arbitrary>().WithMaxSize(kP256_Point_Length), Arbitrary>(), - Arbitrary(), Arbitrary()); + .WithDomains( + // aW0 + Arbitrary>().WithMaxSize(kP256_FE_Length), + // aL + Arbitrary>().WithMaxSize(kP256_Point_Length), + // aSalt + Arbitrary>(), + // fuzzedPBKDF2Iter + Arbitrary(), + // fuzzedSetupPasscode + Arbitrary()); /* -------------------------------------------------------------------------------------------*/ // In This FuzzTest, Fuzzed Serialized Verifier is deserialized and Serialized Again, comparing the original with RoundTrip result. @@ -301,4 +340,598 @@ void Spake2pVerifier_Serialize_RoundTrip(const vector & FuzzedSerialize FUZZ_TEST(FuzzPASE_PW, Spake2pVerifier_Serialize_RoundTrip) .WithDomains(Arbitrary>().WithSize(kSpake2p_VerifierSerialized_Length)); -} // namespace +/* -------------------------------------------------------------------------------------------*/ +// In This Test a Fuzzed PBKDFParamRequest Message is fuzzed, which is then injected into a PASE Session to test the behaviour of +// PASESession::HandlePBKDFParamRequest(); which will be called by the Accessory/Commissionee. +void TestPASESession::FuzzHandlePBKDFParamRequest(vector fuzzPBKDFLocalRandomData, uint32_t fuzzInitiatorSessionId, + bool fuzzHavePBKDFParameters) +{ + TemporarySessionManager sessionManager(*this); + + // Commissioner: The Sender of PBKDFParamRequest + PASESession pairingCommissioner; + // Accessory: The Receiver of PBKDFParamRequest + PASESession pairingAccessory; + + /*************************** Preparing Commissioner ***************************/ + + CallAllocateSecureSession(sessionManager, pairingCommissioner); + + ReliableMessageProtocolConfig LocalMRPConfig(System::Clock::Milliseconds32(100), System::Clock::Milliseconds32(200), + System::Clock::Milliseconds16(4000)); + + // After the Accessory Handles PBKDFParamRequest, it will send a PBKDFParamResponse back to pairingCommissioner, which should be + // expecting it. + pairingCommissioner.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PBKDFParamResponse); + + /**************************Constructing PBKDFParamRequest Message***************************************** */ + + const size_t max_msg_len = TLV::EstimateStructOverhead(fuzzPBKDFLocalRandomData.size(), // initiatorRandom, + sizeof(fuzzInitiatorSessionId), // initiatorSessionId + sizeof(PasscodeId), // passcodeId, + sizeof(bool), // hasPBKDFParameters + SessionParameters::kEstimatedTLVSize // Session Parameters + ); + + System::PacketBufferHandle req = System::PacketBufferHandle::New(max_msg_len); + EXPECT_FALSE(req.IsNull()); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(req)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, + tlvWriter.PutBytes(TLV::ContextTag(1), fuzzPBKDFLocalRandomData.data(), fuzzPBKDFLocalRandomData.size())); + + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(2), fuzzInitiatorSessionId)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(3), kDefaultCommissioningPasscodeId)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.PutBoolean(TLV::ContextTag(4), fuzzHavePBKDFParameters)); + + EXPECT_EQ(CHIP_NO_ERROR, PASESession::EncodeSessionParameters(TLV::ContextTag(5), LocalMRPConfig, tlvWriter)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Finalize(&req)); + + /*************************** Preparing Accessory for Receiving PBKDFParamRequest Message ***************************/ + + PASETestLoopbackTransportDelegate delegate; + auto & loopback = GetLoopback(); + loopback.SetLoopbackTransportDelegate(&delegate); + loopback.mSentMessageCount = 0; + + TestSecurePairingDelegate delegateAccessory; + + PayloadHeader payloadHeaderAccessory; + + // One Limitation of using this is that contextAccessory will automatically be an Initiator, while in real-life it should be a + // responder. + ExchangeContext * contextAccessory = NewUnauthenticatedExchangeToBob(&pairingAccessory); + + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::PBKDFParamRequest, + &pairingAccessory), + CHIP_NO_ERROR); + + // Adding PASESession::Init in order to AllocateSecureSession and have a localsessionID generated for pairingAccessory + pairingAccessory.Init(sessionManager, 0, &delegateAccessory); + + // This was done to have an exchange context + pairingAccessory.mExchangeCtxt.Emplace(*contextAccessory); + + pairingAccessory.mLocalMRPConfig = MakeOptional(LocalMRPConfig); + + payloadHeaderAccessory.SetMessageType(Protocols::SecureChannel::MsgType::PBKDFParamRequest); + pairingAccessory.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PBKDFParamRequest); + + pairingAccessory.OnMessageReceived(&pairingAccessory.mExchangeCtxt.Value().Get(), payloadHeaderAccessory, std::move(req)); + + DrainAndServiceIO(); +} + +void HandlePBKDFParamRequest(vector fuzzPBKDFLocalRandomData, uint32_t fuzzInitiatorSessionId, + bool fuzzHavePBKDFParameters) +{ + // TODO: #35369 Move this to a Fixture once Errors related to FuzzTest Fixtures are resolved + TestPASESession PASELoopBack; + PASELoopBack.FuzzHandlePBKDFParamRequest(fuzzPBKDFLocalRandomData, fuzzInitiatorSessionId, fuzzHavePBKDFParameters); +} + +FUZZ_TEST(FuzzPASE_PW, HandlePBKDFParamRequest) + .WithDomains( + // PBKDFLocalRandomData + Arbitrary>(), + // InitiatorSessionId + Arbitrary(), + // mHavePBKDFParameters + Arbitrary()); + +/* -------------------------------------------------------------------------------------------*/ +// In This Test a Fuzzed PBKDFParamResponse Message is fuzzed, which is then injected into a PASE Session to test the behaviour of +// PASESession::HandlePBKDFParamResponse(); which will be called by the Commissioner. +void TestPASESession::FuzzHandlePBKDFParamResponse(vector fuzzPBKDFLocalRandomDataInitiator, + vector fuzzPBKDFLocalRandomDataResponder, + uint32_t fuzzResponderSessionId, const vector & fuzzedSalt, + uint32_t fuzzedPBKDF2Iter, bool fuzzHavePBKDFParameters) +{ + TemporarySessionManager sessionManager(*this); + + // Commissioner: The Receiver of PBKDFParamResponse + PASESession pairingCommissioner; + // Accessory: The Sender of PBKDFParamResponse + PASESession pairingAccessory; + + /*************************** Preparing Commissioner ***************************/ + + CallAllocateSecureSession(sessionManager, pairingCommissioner); + + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); + + // This was done to have an exchange context + pairingCommissioner.mExchangeCtxt.Emplace(*contextCommissioner); + + ReliableMessageProtocolConfig LocalMRPConfig(System::Clock::Milliseconds32(100), System::Clock::Milliseconds32(200), + System::Clock::Milliseconds16(4000)); + + pairingCommissioner.mLocalMRPConfig = MakeOptional(LocalMRPConfig); + + // preparing CommissioningHash needed for SetupSpake2p() + pairingCommissioner.mCommissioningHash.Begin(); + pairingCommissioner.mCommissioningHash.AddData(ByteSpan(fuzzedSalt.data(), fuzzedSalt.size())); + + // The Commissioner will check if the PBKDFLocalRandomData it received in TLV is same as the stored mPBKDFLocalRandomData. So we + // inject it here to be able to pass that check + memcpy(&pairingCommissioner.mPBKDFLocalRandomData[0], fuzzPBKDFLocalRandomDataInitiator.data(), + fuzzPBKDFLocalRandomDataInitiator.size()); + + // In order to cover the Code path where the Commissioner has PBKDF Parameters before Starting PASE, as such, the Accessory will + // not send the PBKDF Parameters in the Response message + bool initiatorHasPBKDFParams = fuzzHavePBKDFParameters; + pairingCommissioner.mHavePBKDFParameters = fuzzHavePBKDFParameters; + + /**************************Constructing PBKDFParamResponse Message***************************************** */ + + const size_t max_msg_len = + TLV::EstimateStructOverhead(fuzzPBKDFLocalRandomDataInitiator.size(), // initiatorRandom + fuzzPBKDFLocalRandomDataResponder.size(), // responderRandom + sizeof(fuzzResponderSessionId), // responderSessionId + TLV::EstimateStructOverhead(sizeof(fuzzedPBKDF2Iter), fuzzedSalt.size()), // pbkdf_parameters + SessionParameters::kEstimatedTLVSize // Session Parameters + ); + + System::PacketBufferHandle resp = System::PacketBufferHandle::New(max_msg_len); + EXPECT_FALSE(resp.IsNull()); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(resp)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); + EXPECT_EQ( + CHIP_NO_ERROR, + tlvWriter.PutBytes(TLV::ContextTag(1), fuzzPBKDFLocalRandomDataInitiator.data(), fuzzPBKDFLocalRandomDataInitiator.size())); + EXPECT_EQ( + CHIP_NO_ERROR, + tlvWriter.PutBytes(TLV::ContextTag(2), fuzzPBKDFLocalRandomDataResponder.data(), fuzzPBKDFLocalRandomDataResponder.size())); + + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(3), fuzzResponderSessionId)); + + if (!initiatorHasPBKDFParams) + { + TLV::TLVType pbkdfParamContainer; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::ContextTag(4), TLV::kTLVType_Structure, pbkdfParamContainer)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(1), fuzzedPBKDF2Iter)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.PutBytes(TLV::ContextTag(2), fuzzedSalt.data(), fuzzedSalt.size())); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(pbkdfParamContainer)); + } + + EXPECT_EQ(CHIP_NO_ERROR, PASESession::EncodeSessionParameters(TLV::ContextTag(5), LocalMRPConfig, tlvWriter)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Finalize(&resp)); + + /*************************** Preparing Commissioner for Receiving PBKDFParamResponse Message ***************************/ + + PayloadHeader payloadHeaderCommissioner; + + payloadHeaderCommissioner.SetMessageType(Protocols::SecureChannel::MsgType::PBKDFParamResponse); + pairingCommissioner.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PBKDFParamResponse); + + pairingCommissioner.OnMessageReceived(&pairingCommissioner.mExchangeCtxt.Value().Get(), payloadHeaderCommissioner, + std::move(resp)); + + DrainAndServiceIO(); +} + +void HandlePBKDFParamResponse(vector fuzzPBKDFLocalRandomDataInitiator, vector fuzzPBKDFLocalRandomDataResponder, + uint32_t fuzzResponderSessionId, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + bool fuzzHavePBKDFParameters) +{ + // TODO: #35369 Move this to a Fixture once Errors related to FuzzTest Fixtures are resolved + TestPASESession PASELoopBack; + PASELoopBack.FuzzHandlePBKDFParamResponse(fuzzPBKDFLocalRandomDataInitiator, fuzzPBKDFLocalRandomDataResponder, + fuzzResponderSessionId, fuzzedSalt, fuzzedPBKDF2Iter, fuzzHavePBKDFParameters); +} + +FUZZ_TEST(FuzzPASE_PW, HandlePBKDFParamResponse) + .WithDomains( + // fuzzPBKDFLocalRandomDataInitiator + Arbitrary>().WithMaxSize(32), + // fuzzPBKDFLocalRandomDataResponder + Arbitrary>(), + // fuzzResponderSessionId + Arbitrary(), + // fuzzedSalt + Arbitrary>(), + // fuzzedPBKDF2Iter + Arbitrary(), + // mHavePBKDFParameters + Arbitrary()); + +/*------------------------------------------------------------------------------------------------------------------------------------*/ +// In This Test we start by constructing a Fuzzed Pake1 Message, by fuzzing the payload pA. the Fuzzed Pake1 Message is then +// injected into a PASE Session to test the behaviour of PASESession::HandleMsg1_and_SendMsg2(); which will be called by the +// Accessory/Commissionee. +void TestPASESession::FuzzHandlePake1(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, + uint32_t fuzzedPBKDF2Iter, const vector & fuzzed_pA) +{ + + ByteSpan fuzzedSaltSpan(fuzzedSalt.data(), fuzzedSalt.size()); + + TemporarySessionManager sessionManager(*this); + + // Commissioner: The Sender of PAKE1 + PASESession pairingCommissioner; + // Accessory: The Receiver of PAKE1 + PASESession pairingAccessory; + + /*************************** Preparing Commissioner ***************************/ + + // preparing CommissioningHash needed for SetupSpake2p() + pairingCommissioner.mCommissioningHash.Begin(); + pairingCommissioner.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingCommissioner.SetupSpake2p()); + + uint8_t serializedWS[kSpake2p_WS_Length * 2] = { 0 }; + + // Compute serializedWS, to be used in BeginProver() + + Spake2pVerifier::ComputeWS(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode, serializedWS, sizeof(serializedWS)); + + EXPECT_EQ(CHIP_NO_ERROR, + pairingCommissioner.mSpake2p.BeginProver(nullptr, 0, nullptr, 0, &serializedWS[0], kSpake2p_WS_Length, + &serializedWS[kSpake2p_WS_Length], kSpake2p_WS_Length)); + + /*********************** Constructing Fuzzed Pake1 Message, to later inject it into PASE Session *********************/ + + constexpr uint8_t kPake1_pA = 1; + + const size_t max_msg_len = TLV::EstimateStructOverhead(fuzzed_pA.size()); + System::PacketBufferHandle msg = System::PacketBufferHandle::New(max_msg_len); + EXPECT_FALSE(msg.IsNull()); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(kPake1_pA), ByteSpan(fuzzed_pA.data(), fuzzed_pA.size()))); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Finalize(&msg)); + + /*************************** Preparing Accessory for Receiving Pake1 Message ***************************/ + + // One Limitation of using this is that contextAccessory will automatically be an Initiator, while in real-life it should be a + // responder. + ExchangeContext * contextAccessory = NewUnauthenticatedExchangeToBob(&pairingAccessory); + + pairingAccessory.mExchangeCtxt.Emplace(*contextAccessory); + + pairingAccessory.mLocalMRPConfig = MakeOptional(ReliableMessageProtocolConfig( + System::Clock::Milliseconds32(100), System::Clock::Milliseconds32(200), System::Clock::Milliseconds16(4000))); + + // preparing CommissioningHash needed for SetupSpake2p() + pairingAccessory.mCommissioningHash.Begin(); + pairingAccessory.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingAccessory.SetupSpake2p()); + + // Compute mPASEVerifier (in order for mSpake2p.BeginVerifier() to use it, once it is called by the pairingAccessory through + // HandleMsg1_and_SendMsg2) + pairingAccessory.mPASEVerifier.Generate(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode); + + /************************Injecting Fuzzed Pake1 Message into PaseSession::OnMessageReceived*************************/ + + PayloadHeader payloadHeaderAccessory; + + // Below two lines are needed to trigger PASESession::OnMessageReceived to call HandleMsg1_and_SendMsg2 + payloadHeaderAccessory.SetMessageType(Protocols::SecureChannel::MsgType::PASE_Pake1); + pairingAccessory.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PASE_Pake1); + + pairingAccessory.OnMessageReceived(&pairingAccessory.mExchangeCtxt.Value().Get(), payloadHeaderAccessory, std::move(msg)); + + DrainAndServiceIO(); +} + +void HandlePake1(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & fuzzed_pA) +{ + // TODO: #35369 Move this to a Fixture once Errors related to FuzzTest Fixtures are resolved + TestPASESession PASELoopBack; + + // pA is an uncompressed public key format, it should start with 0x04. + // Appending 0x04 to the fuzzed input to increase the likelihood of having a valid point format during fuzzing. + vector pA_appended = { 0x04 }; + pA_appended.insert(pA_appended.end(), fuzzed_pA.begin(), fuzzed_pA.end()); + PASELoopBack.FuzzHandlePake1(fuzzedSetupPasscode, fuzzedSalt, fuzzedPBKDF2Iter, pA_appended); +} + +// In This FuzzTest, we will construct a PAKE1 Message with a fuzzed TLV length, and send it through a PASESession +FUZZ_TEST(FuzzPASE_PW, HandlePake1) + .WithDomains( + // Setup Code Range (covers the full 27-bit range, plus 16 additional values) + InRange(00000000, 0x800000F), + // Salt length range (extending min and max by 4 bytes) + Arbitrary>() + .WithMinSize(kSpake2p_Min_PBKDF_Salt_Length - 4) + .WithMaxSize(kSpake2p_Max_PBKDF_Salt_Length + 4), + // PBKDF2Iterations count range (extending min and max by 10 iterations) + InRange(kSpake2p_Min_PBKDF_Iterations - 10, kSpake2p_Max_PBKDF_Iterations + 10), + // Fuzzed pA (Original size = kMAX_Point_Length) + Arbitrary>()); + +/*------------------------------------------------------------------------------------------------------------------------------------*/ +// In this FuzzTest we start by constructing a Fuzzed PAKE2 Message, by fuzzing the payloads pB and cB. the fuzzed message is then +// injected into a PASE Session to test the behavior of PASESession::HandleMsg2_and_SendMsg3(), which will be called by Commissioner +void TestPASESession::FuzzHandlePake2(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, + uint32_t fuzzedPBKDF2Iter, const vector & fuzzed_pB, + const vector & fuzzed_cB) +{ + + ByteSpan fuzzedSaltSpan(fuzzedSalt.data(), fuzzedSalt.size()); + + TemporarySessionManager sessionManager(*this); + + // Commissioner: The Receiver of PAKE2 + PASESession pairingCommissioner; + // Accessory: The Sender of PAKE2 + PASESession pairingAccessory; + + /*************************** Preparing Commissioner ***************************/ + + CallAllocateSecureSession(sessionManager, pairingCommissioner); + + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); + + // This was done to have an exchange context + pairingCommissioner.mExchangeCtxt.Emplace(*contextCommissioner); + + pairingCommissioner.mLocalMRPConfig = MakeOptional(ReliableMessageProtocolConfig( + System::Clock::Milliseconds32(100), System::Clock::Milliseconds32(200), System::Clock::Milliseconds16(4000))); + + // preparing CommissioningHash needed for SetupSpake2p() + pairingCommissioner.mCommissioningHash.Begin(); + pairingCommissioner.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingCommissioner.SetupSpake2p()); + + uint8_t serializedWS[kSpake2p_WS_Length * 2] = { 0 }; + + // Compute serializedWS, to be used in BeginProver() + Spake2pVerifier::ComputeWS(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode, serializedWS, sizeof(serializedWS)); + + EXPECT_EQ(CHIP_NO_ERROR, + pairingCommissioner.mSpake2p.BeginProver(nullptr, 0, nullptr, 0, &serializedWS[0], kSpake2p_WS_Length, + &serializedWS[kSpake2p_WS_Length], kSpake2p_WS_Length)); + + // The Commissioner should have alread called ComputeRoundOne As part of the PASE Session Exchange (and consequently have + // mSpake2p.state = CHIP_SPAKE2P_STATE::R1), the computed values are not used in the test. + uint8_t X[kMAX_Point_Length]; + size_t X_len = sizeof(X); + pairingCommissioner.mSpake2p.ComputeRoundOne(nullptr, 0, X, &X_len); + + /*************************** Preparing Accessory ***************************/ + + // Init mCommissioningHash; needed for SetupSpake2p() + pairingAccessory.mCommissioningHash.Begin(); + pairingAccessory.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingAccessory.SetupSpake2p()); + + // Below Steps take place in HandleMsg1 + // Compute mPASEVerifier to be able to pass it to BeginVerifier() + pairingAccessory.mPASEVerifier.Generate(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode); + + pairingAccessory.mSpake2p.BeginVerifier(nullptr, 0, nullptr, 0, pairingAccessory.mPASEVerifier.mW0, kP256_FE_Length, + pairingAccessory.mPASEVerifier.mL, kP256_Point_Length); + + /*********************** Constructing Fuzzed PAKE2 Message, to later inject it into PASE Session *********************/ + + constexpr uint8_t kPake2_pB = 1; + constexpr uint8_t kPake2_cB = 2; + + const size_t max_msg_len = TLV::EstimateStructOverhead(fuzzed_pB.size(), fuzzed_cB.size()); + System::PacketBufferHandle msg2 = System::PacketBufferHandle::New(max_msg_len); + EXPECT_FALSE(msg2.IsNull()); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg2)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(kPake2_pB), ByteSpan(fuzzed_pB.data(), fuzzed_pB.size()))); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(kPake2_cB), ByteSpan(fuzzed_cB.data(), fuzzed_cB.size()))); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Finalize(&msg2)); + + // After PAKE2 is sent, the pairingAccessory will expect a a Pake3 Message + pairingAccessory.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PASE_Pake3); + + /************************Injecting Fuzzed PAKE2 Message into PaseSession::OnMessageReceived*************************/ + + PayloadHeader payloadHeaderCommissioner; + + // Below two lines are needed to trigger PASESession::OnMessageReceived to call HandleMsg2_and_SendMsg3 + payloadHeaderCommissioner.SetMessageType(Protocols::SecureChannel::MsgType::PASE_Pake2); + pairingCommissioner.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PASE_Pake2); + + pairingCommissioner.OnMessageReceived(&pairingCommissioner.mExchangeCtxt.Value().Get(), payloadHeaderCommissioner, + std::move(msg2)); + + DrainAndServiceIO(); +} + +void HandlePake2(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & pB, const vector & cB) +{ + TestPASESession PASELoopBack; + // pB is an uncompressed public key format, it should start with 0x04. + // Appending 0x04 to the fuzzed input to increase the likelihood of having a valid point format during fuzzing. + vector pB_appended = { 0x04 }; + pB_appended.insert(pB_appended.end(), pB.begin(), pB.end()); + + PASELoopBack.FuzzHandlePake2(fuzzedSetupPasscode, fuzzedSalt, fuzzedPBKDF2Iter, pB_appended, cB); +} + +FUZZ_TEST(FuzzPASE_PW, HandlePake2) + .WithDomains( + // Setup Code Range (covers the full 27-bit range, plus 16 additional values) + InRange(00000000, 0x800000F), + // Salt length range (extending min and max by 4 bytes) + Arbitrary>() + .WithMinSize(kSpake2p_Min_PBKDF_Salt_Length - 4) + .WithMaxSize(kSpake2p_Max_PBKDF_Salt_Length + 4), + // PBKDF2Iterations count range (extending min and max by 10 iterations) + InRange(kSpake2p_Min_PBKDF_Iterations - 10, kSpake2p_Max_PBKDF_Iterations + 10), + // Fuzzed pB (Original size = kMAX_Point_Length), + Arbitrary>(), + // Fuzzed cB (Original size = kMAX_Hash_Length) + Arbitrary>()); + +/*------------------------------------------------------------------------------------------------------------------------------------*/ +// In This Test we start by constructing a Fuzzed Pake3 Message, by fuzzing the payload cA. The Fuzzed message is then injected into +// a PASE Session to test the behavior of PASESession::HandleMsg3(); which will be called by the Accessory/Commissionee. +void TestPASESession::FuzzHandlePake3(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, + uint32_t fuzzedPBKDF2Iter, const vector & fuzzed_cA) +{ + + ByteSpan fuzzedSaltSpan(fuzzedSalt.data(), fuzzedSalt.size()); + + TemporarySessionManager sessionManager(*this); + + // Commissioner: The Sender of PAKE3 + PASESession pairingCommissioner; + // Accessory: The Receiver of PAKE3 + PASESession pairingAccessory; + + /*************************** Preparing Commissioner ***************************/ + + // preparing CommissioningHash needed for SetupSpake2p() + pairingCommissioner.mCommissioningHash.Begin(); + pairingCommissioner.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingCommissioner.SetupSpake2p()); + + uint8_t serializedWS[kSpake2p_WS_Length * 2] = { 0 }; + + // Compute serializedWS, to be used in BeginProver() + + Spake2pVerifier::ComputeWS(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode, serializedWS, sizeof(serializedWS)); + + EXPECT_EQ(CHIP_NO_ERROR, + pairingCommissioner.mSpake2p.BeginProver(nullptr, 0, nullptr, 0, &serializedWS[0], kSpake2p_WS_Length, + &serializedWS[kSpake2p_WS_Length], kSpake2p_WS_Length)); + + // The Commissioner should have already called ComputeRoundOne As part of the Exchange (and consequently have state = + // CHIP_SPAKE2P_STATE::R1), the computed values are not used. + uint8_t X[kMAX_Point_Length]; + size_t X_len = sizeof(X); + pairingCommissioner.mSpake2p.ComputeRoundOne(nullptr, 0, X, &X_len); + + /*************************** Preparing Accessory ***************************/ + + CallAllocateSecureSession(sessionManager, pairingAccessory); + + // One Limitation of using this is that contextAccessory will automatically be an Initiator, while in real-life it should be a + // responder. + ExchangeContext * contextAccessory = NewUnauthenticatedExchangeToBob(&pairingAccessory); + + // This was done to have an exchange context + pairingAccessory.mExchangeCtxt.Emplace(*contextAccessory); + + pairingAccessory.mLocalMRPConfig = MakeOptional(ReliableMessageProtocolConfig( + System::Clock::Milliseconds32(100), System::Clock::Milliseconds32(200), System::Clock::Milliseconds16(4000))); + + // preparing CommissioningHash needed for SetupSpake2p() + pairingAccessory.mCommissioningHash.Begin(); + pairingAccessory.mCommissioningHash.AddData(fuzzedSaltSpan); + EXPECT_EQ(CHIP_NO_ERROR, pairingAccessory.SetupSpake2p()); + + // Below Steps take place in HandleMsg1 + // compute mPASEVerifier to be able to pass it to BeginVerifier() + pairingAccessory.mPASEVerifier.Generate(fuzzedPBKDF2Iter, fuzzedSaltSpan, fuzzedSetupPasscode); + + pairingAccessory.mSpake2p.BeginVerifier(nullptr, 0, nullptr, 0, pairingAccessory.mPASEVerifier.mW0, kP256_FE_Length, + pairingAccessory.mPASEVerifier.mL, kP256_Point_Length); + + /*************************** Preparing Accessory for Receiving PAKE3 Message ***************************/ + + uint8_t Y[kMAX_Point_Length]; + size_t Y_len = sizeof(Y); + + uint8_t verifier[kMAX_Hash_Length]; + size_t verifier_len = kMAX_Hash_Length; + + // These calls are usually done on the Accessory before sending Pake2. They are needed to make sure that the Accessory is at the + // correct Spake2p state (CHIP_SPAKE2P_STATE::R2) to handle Pake3 Messages. + pairingAccessory.mSpake2p.ComputeRoundOne(X, X_len, Y, &Y_len); + pairingAccessory.mSpake2p.ComputeRoundTwo(X, X_len, verifier, &verifier_len); + + /*********************** Constructing Fuzzed PAKE3 Message, to later inject it into PASE Session *********************/ + + constexpr uint8_t kPake3_cA = 1; + + const size_t max_msg_len = TLV::EstimateStructOverhead(fuzzed_cA.size()); + System::PacketBufferHandle msg3 = System::PacketBufferHandle::New(max_msg_len); + EXPECT_FALSE(msg3.IsNull()); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg3)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Put(TLV::ContextTag(kPake3_cA), ByteSpan(fuzzed_cA.data(), fuzzed_cA.size()))); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.EndContainer(outerContainerType)); + EXPECT_EQ(CHIP_NO_ERROR, tlvWriter.Finalize(&msg3)); + + // After PAKE3 is sent, the pairingCommissioner will expect a StatusReport + pairingCommissioner.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::StatusReport); + + /************************Injecting Fuzzed PAKE3 Message into PaseSession::OnMessageReceived*************************/ + + PayloadHeader payloadHeaderAccessory; + + // Below two lines are needed to trigger PASESession::OnMessageReceived to call HandleMsg3 + payloadHeaderAccessory.SetMessageType(Protocols::SecureChannel::MsgType::PASE_Pake3); + pairingAccessory.mNextExpectedMsg.SetValue(Protocols::SecureChannel::MsgType::PASE_Pake3); + + pairingAccessory.OnMessageReceived(&pairingAccessory.mExchangeCtxt.Value().Get(), payloadHeaderAccessory, std::move(msg3)); + + DrainAndServiceIO(); +} + +void HandlePake3(const uint32_t fuzzedSetupPasscode, const vector & fuzzedSalt, uint32_t fuzzedPBKDF2Iter, + const vector & fuzzedcA) +{ + TestPASESession PASELoopBack; + PASELoopBack.FuzzHandlePake3(fuzzedSetupPasscode, fuzzedSalt, fuzzedPBKDF2Iter, fuzzedcA); +} + +FUZZ_TEST(FuzzPASE_PW, HandlePake3) + .WithDomains( + // Setup Code Range (covers the full 27-bit range, plus 16 additional values) + InRange(00000000, 0x800000F), + // Salt length range (extending min and max by 4 bytes) + Arbitrary>() + .WithMinSize(kSpake2p_Min_PBKDF_Salt_Length - 4) + .WithMaxSize(kSpake2p_Max_PBKDF_Salt_Length + 4), + // PBKDF2Iterations count range (extending min and max by 10 iterations) + InRange(kSpake2p_Min_PBKDF_Iterations - 10, kSpake2p_Max_PBKDF_Iterations + 10), + // Fuzzed cA (Original size = kMAX_Hash_Length) + Arbitrary>()); + +} // namespace Testing +} // namespace chip diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 94763d8311dce6..0bc8c7c69318c4 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -19,7 +19,7 @@ import("//build_overrides/mbedtls.gni") import("${chip_root}/src/app/icd/icd.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/lib.gni") -import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/src/platform/silabs/wifi/args.gni") import("${silabs_sdk_build_root}/efr32_sdk.gni") import("silabs_board.gni") diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 146077372f4cc6..9ca85baa47bf5b 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -96,6 +96,7 @@ declare_args() { examples_plat_dir = "${chip_root}/examples/platform/silabs/efr32" silabs_plat_efr32_wifi_dir = "${chip_root}/src/platform/silabs/efr32/wifi" silabs_common_plat_dir = "${chip_root}/examples/platform/silabs" +silabs_platform_dir = "${chip_root}/src/platform/silabs" is_series_2 = silabs_family == "mgm24" || silabs_family == "efr32mg24" || silabs_family == "efr32mg26" @@ -333,6 +334,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/radio/wifi/wfx_fmac_driver/firmware", "${efr32_sdk_root}/platform/radio/wifi/wfx_fmac_driver/pds/brd8022a", "${efr32_sdk_root}/platform/radio/wifi/wfx_fmac_driver/secure_link", + "${efr32_sdk_root}/platform/radio/wifi/wfx_fmac_driver/config", ] } @@ -365,12 +367,23 @@ template("efr32_sdk") { "${wifi_sdk_root}/components/protocol/wifi/si91x", ] } + + if (use_rs9116) { + # TODO: we should create a seperate directory for headers that are necessary for the underlying sdks + _include_dirs += [ + "${chip_root}/src/platform/silabs/wifi/rs911x/platform", + "${chip_root}/src/platform/silabs/wifi/rs911x", + ] + } + if (use_rs9116 || use_SiWx917) { _include_dirs += [ "${chip_root}/src/platform/silabs/rs911x" ] } + if (use_wf200 || use_rs9116 || use_SiWx917) { _include_dirs += [ "${chip_root}/src/platform/silabs/wifi" ] } + if (silabs_family != "mgm24") { _include_dirs += [ "${efr32_sdk_root}/platform/radio/rail_lib/hal", @@ -583,7 +596,7 @@ template("efr32_sdk") { } if (use_wf200 || use_rs9116 || use_SiWx917) { - import("${chip_root}/src/platform/silabs/wifi_args.gni") + import("${chip_root}/src/platform/silabs/wifi/args.gni") defines += [ "LWIP_NETIF_API=1" ] if (chip_enable_wifi_ipv4) { 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 f2c2ea2ef58377..4879ae5213c65d 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 @@ -29749,7 +29749,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; encoder.Encode(to_underlying(Fields::kImageCodec), imageCodec); - encoder.Encode(to_underlying(Fields::kFrameRate), frameRate); + encoder.Encode(to_underlying(Fields::kMaxFrameRate), maxFrameRate); encoder.Encode(to_underlying(Fields::kBitRate), bitRate); encoder.Encode(to_underlying(Fields::kMinResolution), minResolution); encoder.Encode(to_underlying(Fields::kMaxResolution), maxResolution); @@ -29775,9 +29775,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, imageCodec); } - else if (__context_tag == to_underlying(Fields::kFrameRate)) + else if (__context_tag == to_underlying(Fields::kMaxFrameRate)) { - err = DataModel::Decode(reader, frameRate); + err = DataModel::Decode(reader, maxFrameRate); } else if (__context_tag == to_underlying(Fields::kBitRate)) { @@ -30023,10 +30023,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, currentFrameRate); case Attributes::HDRModeEnabled::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, HDRModeEnabled); - case Attributes::CurrentVideoCodecs::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, currentVideoCodecs); - case Attributes::CurrentSnapshotConfig::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, currentSnapshotConfig); case Attributes::FabricsUsingCamera::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, fabricsUsingCamera); case Attributes::AllocatedVideoStreams::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 35e26825283dad..2357a87dd9d9fa 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 @@ -41542,7 +41542,7 @@ namespace SnapshotStreamAllocate { enum class Fields : uint8_t { kImageCodec = 0, - kFrameRate = 1, + kMaxFrameRate = 1, kBitRate = 2, kMinResolution = 3, kMaxResolution = 4, @@ -41557,7 +41557,7 @@ struct Type static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } ImageCodecEnum imageCodec = static_cast(0); - uint16_t frameRate = static_cast(0); + uint16_t maxFrameRate = static_cast(0); uint32_t bitRate = static_cast(0); Structs::VideoResolutionStruct::Type minResolution; Structs::VideoResolutionStruct::Type maxResolution; @@ -41577,7 +41577,7 @@ struct DecodableType static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } ImageCodecEnum imageCodec = static_cast(0); - uint16_t frameRate = static_cast(0); + uint16_t maxFrameRate = static_cast(0); uint32_t bitRate = static_cast(0); Structs::VideoResolutionStruct::DecodableType minResolution; Structs::VideoResolutionStruct::DecodableType maxResolution; @@ -41932,31 +41932,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace HDRModeEnabled -namespace CurrentVideoCodecs { -struct TypeInfo -{ - using Type = chip::app::DataModel::List; - using DecodableType = chip::app::DataModel::DecodableList; - using DecodableArgType = - const chip::app::DataModel::DecodableList &; - - static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::CurrentVideoCodecs::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace CurrentVideoCodecs -namespace CurrentSnapshotConfig { -struct TypeInfo -{ - using Type = chip::app::Clusters::CameraAvStreamManagement::Structs::SnapshotParamsStruct::Type; - using DecodableType = chip::app::Clusters::CameraAvStreamManagement::Structs::SnapshotParamsStruct::DecodableType; - using DecodableArgType = const chip::app::Clusters::CameraAvStreamManagement::Structs::SnapshotParamsStruct::DecodableType &; - - static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::CurrentSnapshotConfig::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace CurrentSnapshotConfig namespace FabricsUsingCamera { struct TypeInfo { @@ -42343,8 +42318,6 @@ struct TypeInfo Attributes::MaxNetworkBandwidth::TypeInfo::DecodableType maxNetworkBandwidth = static_cast(0); Attributes::CurrentFrameRate::TypeInfo::DecodableType currentFrameRate = static_cast(0); Attributes::HDRModeEnabled::TypeInfo::DecodableType HDRModeEnabled = static_cast(0); - Attributes::CurrentVideoCodecs::TypeInfo::DecodableType currentVideoCodecs; - Attributes::CurrentSnapshotConfig::TypeInfo::DecodableType currentSnapshotConfig; Attributes::FabricsUsingCamera::TypeInfo::DecodableType fabricsUsingCamera; Attributes::AllocatedVideoStreams::TypeInfo::DecodableType allocatedVideoStreams; Attributes::AllocatedAudioStreams::TypeInfo::DecodableType allocatedAudioStreams; 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 e0fa3a25fdaf2a..5d12daa8564976 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 @@ -6922,120 +6922,112 @@ namespace HDRModeEnabled { static constexpr AttributeId Id = 0x0000000D; } // namespace HDRModeEnabled -namespace CurrentVideoCodecs { -static constexpr AttributeId Id = 0x0000000E; -} // namespace CurrentVideoCodecs - -namespace CurrentSnapshotConfig { -static constexpr AttributeId Id = 0x0000000F; -} // namespace CurrentSnapshotConfig - namespace FabricsUsingCamera { -static constexpr AttributeId Id = 0x00000010; +static constexpr AttributeId Id = 0x0000000E; } // namespace FabricsUsingCamera namespace AllocatedVideoStreams { -static constexpr AttributeId Id = 0x00000011; +static constexpr AttributeId Id = 0x0000000F; } // namespace AllocatedVideoStreams namespace AllocatedAudioStreams { -static constexpr AttributeId Id = 0x00000012; +static constexpr AttributeId Id = 0x00000010; } // namespace AllocatedAudioStreams namespace AllocatedSnapshotStreams { -static constexpr AttributeId Id = 0x00000013; +static constexpr AttributeId Id = 0x00000011; } // namespace AllocatedSnapshotStreams namespace RankedVideoStreamPrioritiesList { -static constexpr AttributeId Id = 0x00000014; +static constexpr AttributeId Id = 0x00000012; } // namespace RankedVideoStreamPrioritiesList namespace SoftRecordingPrivacyModeEnabled { -static constexpr AttributeId Id = 0x00000015; +static constexpr AttributeId Id = 0x00000013; } // namespace SoftRecordingPrivacyModeEnabled namespace SoftLivestreamPrivacyModeEnabled { -static constexpr AttributeId Id = 0x00000016; +static constexpr AttributeId Id = 0x00000014; } // namespace SoftLivestreamPrivacyModeEnabled namespace HardPrivacyModeOn { -static constexpr AttributeId Id = 0x00000017; +static constexpr AttributeId Id = 0x00000015; } // namespace HardPrivacyModeOn namespace NightVision { -static constexpr AttributeId Id = 0x00000018; +static constexpr AttributeId Id = 0x00000016; } // namespace NightVision namespace NightVisionIllum { -static constexpr AttributeId Id = 0x00000019; +static constexpr AttributeId Id = 0x00000017; } // namespace NightVisionIllum namespace Viewport { -static constexpr AttributeId Id = 0x0000001A; +static constexpr AttributeId Id = 0x00000018; } // namespace Viewport namespace SpeakerMuted { -static constexpr AttributeId Id = 0x0000001B; +static constexpr AttributeId Id = 0x00000019; } // namespace SpeakerMuted namespace SpeakerVolumeLevel { -static constexpr AttributeId Id = 0x0000001C; +static constexpr AttributeId Id = 0x0000001A; } // namespace SpeakerVolumeLevel namespace SpeakerMaxLevel { -static constexpr AttributeId Id = 0x0000001D; +static constexpr AttributeId Id = 0x0000001B; } // namespace SpeakerMaxLevel namespace SpeakerMinLevel { -static constexpr AttributeId Id = 0x0000001E; +static constexpr AttributeId Id = 0x0000001C; } // namespace SpeakerMinLevel namespace MicrophoneMuted { -static constexpr AttributeId Id = 0x0000001F; +static constexpr AttributeId Id = 0x0000001D; } // namespace MicrophoneMuted namespace MicrophoneVolumeLevel { -static constexpr AttributeId Id = 0x00000020; +static constexpr AttributeId Id = 0x0000001E; } // namespace MicrophoneVolumeLevel namespace MicrophoneMaxLevel { -static constexpr AttributeId Id = 0x00000021; +static constexpr AttributeId Id = 0x0000001F; } // namespace MicrophoneMaxLevel namespace MicrophoneMinLevel { -static constexpr AttributeId Id = 0x00000022; +static constexpr AttributeId Id = 0x00000020; } // namespace MicrophoneMinLevel namespace MicrophoneAGCEnabled { -static constexpr AttributeId Id = 0x00000023; +static constexpr AttributeId Id = 0x00000021; } // namespace MicrophoneAGCEnabled namespace ImageRotation { -static constexpr AttributeId Id = 0x00000024; +static constexpr AttributeId Id = 0x00000022; } // namespace ImageRotation namespace ImageFlipHorizontal { -static constexpr AttributeId Id = 0x00000025; +static constexpr AttributeId Id = 0x00000023; } // namespace ImageFlipHorizontal namespace ImageFlipVertical { -static constexpr AttributeId Id = 0x00000026; +static constexpr AttributeId Id = 0x00000024; } // namespace ImageFlipVertical namespace LocalVideoRecordingEnabled { -static constexpr AttributeId Id = 0x00000027; +static constexpr AttributeId Id = 0x00000025; } // namespace LocalVideoRecordingEnabled namespace LocalSnapshotRecordingEnabled { -static constexpr AttributeId Id = 0x00000028; +static constexpr AttributeId Id = 0x00000026; } // namespace LocalSnapshotRecordingEnabled namespace StatusLightEnabled { -static constexpr AttributeId Id = 0x00000029; +static constexpr AttributeId Id = 0x00000027; } // namespace StatusLightEnabled namespace StatusLightBrightness { -static constexpr AttributeId Id = 0x0000002A; +static constexpr AttributeId Id = 0x00000028; } // namespace StatusLightBrightness namespace GeneratedCommandList { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 3fca8853155172..b0c00980d3e42d 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -13736,35 +13736,33 @@ class ZoneManagementRemoveZone : public ClusterCommand | * MaxNetworkBandwidth | 0x000B | | * CurrentFrameRate | 0x000C | | * HDRModeEnabled | 0x000D | -| * CurrentVideoCodecs | 0x000E | -| * CurrentSnapshotConfig | 0x000F | -| * FabricsUsingCamera | 0x0010 | -| * AllocatedVideoStreams | 0x0011 | -| * AllocatedAudioStreams | 0x0012 | -| * AllocatedSnapshotStreams | 0x0013 | -| * RankedVideoStreamPrioritiesList | 0x0014 | -| * SoftRecordingPrivacyModeEnabled | 0x0015 | -| * SoftLivestreamPrivacyModeEnabled | 0x0016 | -| * HardPrivacyModeOn | 0x0017 | -| * NightVision | 0x0018 | -| * NightVisionIllum | 0x0019 | -| * Viewport | 0x001A | -| * SpeakerMuted | 0x001B | -| * SpeakerVolumeLevel | 0x001C | -| * SpeakerMaxLevel | 0x001D | -| * SpeakerMinLevel | 0x001E | -| * MicrophoneMuted | 0x001F | -| * MicrophoneVolumeLevel | 0x0020 | -| * MicrophoneMaxLevel | 0x0021 | -| * MicrophoneMinLevel | 0x0022 | -| * MicrophoneAGCEnabled | 0x0023 | -| * ImageRotation | 0x0024 | -| * ImageFlipHorizontal | 0x0025 | -| * ImageFlipVertical | 0x0026 | -| * LocalVideoRecordingEnabled | 0x0027 | -| * LocalSnapshotRecordingEnabled | 0x0028 | -| * StatusLightEnabled | 0x0029 | -| * StatusLightBrightness | 0x002A | +| * FabricsUsingCamera | 0x000E | +| * AllocatedVideoStreams | 0x000F | +| * AllocatedAudioStreams | 0x0010 | +| * AllocatedSnapshotStreams | 0x0011 | +| * RankedVideoStreamPrioritiesList | 0x0012 | +| * SoftRecordingPrivacyModeEnabled | 0x0013 | +| * SoftLivestreamPrivacyModeEnabled | 0x0014 | +| * HardPrivacyModeOn | 0x0015 | +| * NightVision | 0x0016 | +| * NightVisionIllum | 0x0017 | +| * Viewport | 0x0018 | +| * SpeakerMuted | 0x0019 | +| * SpeakerVolumeLevel | 0x001A | +| * SpeakerMaxLevel | 0x001B | +| * SpeakerMinLevel | 0x001C | +| * MicrophoneMuted | 0x001D | +| * MicrophoneVolumeLevel | 0x001E | +| * MicrophoneMaxLevel | 0x001F | +| * MicrophoneMinLevel | 0x0020 | +| * MicrophoneAGCEnabled | 0x0021 | +| * ImageRotation | 0x0022 | +| * ImageFlipHorizontal | 0x0023 | +| * ImageFlipVertical | 0x0024 | +| * LocalVideoRecordingEnabled | 0x0025 | +| * LocalSnapshotRecordingEnabled | 0x0026 | +| * StatusLightEnabled | 0x0027 | +| * StatusLightBrightness | 0x0028 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * AttributeList | 0xFFFB | @@ -14004,7 +14002,7 @@ class CameraAvStreamManagementSnapshotStreamAllocate : public ClusterCommand mComplex_MaxResolution(&mRequest.maxResolution) { AddArgument("ImageCodec", 0, UINT8_MAX, &mRequest.imageCodec); - AddArgument("FrameRate", 0, UINT16_MAX, &mRequest.frameRate); + AddArgument("MaxFrameRate", 0, UINT16_MAX, &mRequest.maxFrameRate); AddArgument("BitRate", 0, UINT32_MAX, &mRequest.bitRate); AddArgument("MinResolution", &mComplex_MinResolution); AddArgument("MaxResolution", &mComplex_MaxResolution); @@ -26768,8 +26766,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "max-network-bandwidth", Attributes::MaxNetworkBandwidth::Id, credsIssuerConfig), // make_unique(Id, "current-frame-rate", Attributes::CurrentFrameRate::Id, credsIssuerConfig), // make_unique(Id, "hdrmode-enabled", Attributes::HDRModeEnabled::Id, credsIssuerConfig), // - make_unique(Id, "current-video-codecs", Attributes::CurrentVideoCodecs::Id, credsIssuerConfig), // - make_unique(Id, "current-snapshot-config", Attributes::CurrentSnapshotConfig::Id, credsIssuerConfig), // make_unique(Id, "fabrics-using-camera", Attributes::FabricsUsingCamera::Id, credsIssuerConfig), // make_unique(Id, "allocated-video-streams", Attributes::AllocatedVideoStreams::Id, credsIssuerConfig), // make_unique(Id, "allocated-audio-streams", Attributes::AllocatedAudioStreams::Id, credsIssuerConfig), // @@ -26844,12 +26840,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "hdrmode-enabled", 0, 1, Attributes::HDRModeEnabled::Id, WriteCommandType::kWrite, credsIssuerConfig), // - make_unique>>( - Id, "current-video-codecs", Attributes::CurrentVideoCodecs::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>( - Id, "current-snapshot-config", Attributes::CurrentSnapshotConfig::Id, WriteCommandType::kForceWrite, - credsIssuerConfig), // make_unique>>( Id, "fabrics-using-camera", Attributes::FabricsUsingCamera::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( - Id, "ranked-video-stream-priorities-list", Attributes::RankedVideoStreamPrioritiesList::Id, WriteCommandType::kWrite, - credsIssuerConfig), // + Id, "ranked-video-stream-priorities-list", Attributes::RankedVideoStreamPrioritiesList::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "soft-recording-privacy-mode-enabled", 0, 1, Attributes::SoftRecordingPrivacyModeEnabled::Id, WriteCommandType::kWrite, credsIssuerConfig), // @@ -26947,8 +26937,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "max-network-bandwidth", Attributes::MaxNetworkBandwidth::Id, credsIssuerConfig), // make_unique(Id, "current-frame-rate", Attributes::CurrentFrameRate::Id, credsIssuerConfig), // make_unique(Id, "hdrmode-enabled", Attributes::HDRModeEnabled::Id, credsIssuerConfig), // - make_unique(Id, "current-video-codecs", Attributes::CurrentVideoCodecs::Id, credsIssuerConfig), // - make_unique(Id, "current-snapshot-config", Attributes::CurrentSnapshotConfig::Id, credsIssuerConfig), // make_unique(Id, "fabrics-using-camera", Attributes::FabricsUsingCamera::Id, credsIssuerConfig), // make_unique(Id, "allocated-video-streams", Attributes::AllocatedVideoStreams::Id, credsIssuerConfig), // make_unique(Id, "allocated-audio-streams", Attributes::AllocatedAudioStreams::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 6fb87819ce70df..1ea513ea1d3f95 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -18563,16 +18563,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("HDRModeEnabled", 1, value); } - case CameraAvStreamManagement::Attributes::CurrentVideoCodecs::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("CurrentVideoCodecs", 1, value); - } - case CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::Id: { - chip::app::Clusters::CameraAvStreamManagement::Structs::SnapshotParamsStruct::DecodableType value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("CurrentSnapshotConfig", 1, value); - } case CameraAvStreamManagement::Attributes::FabricsUsingCamera::Id: { chip::app::DataModel::DecodableList 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 753378db6fa9e7..3977ee180be1e2 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -4197,10 +4197,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "CurrentFrameRate"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::HDRModeEnabled::Id: return "HDRModeEnabled"; - case chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentVideoCodecs::Id: - return "CurrentVideoCodecs"; - case chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::Id: - return "CurrentSnapshotConfig"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::FabricsUsingCamera::Id: return "FabricsUsingCamera"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::AllocatedVideoStreams::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 6e8b57d2d8baab..2d9b737038535e 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -150659,35 +150659,33 @@ class SubscribeAttributeZoneManagementClusterRevision : public SubscribeAttribut | * MaxNetworkBandwidth | 0x000B | | * CurrentFrameRate | 0x000C | | * HDRModeEnabled | 0x000D | -| * CurrentVideoCodecs | 0x000E | -| * CurrentSnapshotConfig | 0x000F | -| * FabricsUsingCamera | 0x0010 | -| * AllocatedVideoStreams | 0x0011 | -| * AllocatedAudioStreams | 0x0012 | -| * AllocatedSnapshotStreams | 0x0013 | -| * RankedVideoStreamPrioritiesList | 0x0014 | -| * SoftRecordingPrivacyModeEnabled | 0x0015 | -| * SoftLivestreamPrivacyModeEnabled | 0x0016 | -| * HardPrivacyModeOn | 0x0017 | -| * NightVision | 0x0018 | -| * NightVisionIllum | 0x0019 | -| * Viewport | 0x001A | -| * SpeakerMuted | 0x001B | -| * SpeakerVolumeLevel | 0x001C | -| * SpeakerMaxLevel | 0x001D | -| * SpeakerMinLevel | 0x001E | -| * MicrophoneMuted | 0x001F | -| * MicrophoneVolumeLevel | 0x0020 | -| * MicrophoneMaxLevel | 0x0021 | -| * MicrophoneMinLevel | 0x0022 | -| * MicrophoneAGCEnabled | 0x0023 | -| * ImageRotation | 0x0024 | -| * ImageFlipHorizontal | 0x0025 | -| * ImageFlipVertical | 0x0026 | -| * LocalVideoRecordingEnabled | 0x0027 | -| * LocalSnapshotRecordingEnabled | 0x0028 | -| * StatusLightEnabled | 0x0029 | -| * StatusLightBrightness | 0x002A | +| * FabricsUsingCamera | 0x000E | +| * AllocatedVideoStreams | 0x000F | +| * AllocatedAudioStreams | 0x0010 | +| * AllocatedSnapshotStreams | 0x0011 | +| * RankedVideoStreamPrioritiesList | 0x0012 | +| * SoftRecordingPrivacyModeEnabled | 0x0013 | +| * SoftLivestreamPrivacyModeEnabled | 0x0014 | +| * HardPrivacyModeOn | 0x0015 | +| * NightVision | 0x0016 | +| * NightVisionIllum | 0x0017 | +| * Viewport | 0x0018 | +| * SpeakerMuted | 0x0019 | +| * SpeakerVolumeLevel | 0x001A | +| * SpeakerMaxLevel | 0x001B | +| * SpeakerMinLevel | 0x001C | +| * MicrophoneMuted | 0x001D | +| * MicrophoneVolumeLevel | 0x001E | +| * MicrophoneMaxLevel | 0x001F | +| * MicrophoneMinLevel | 0x0020 | +| * MicrophoneAGCEnabled | 0x0021 | +| * ImageRotation | 0x0022 | +| * ImageFlipHorizontal | 0x0023 | +| * ImageFlipVertical | 0x0024 | +| * LocalVideoRecordingEnabled | 0x0025 | +| * LocalSnapshotRecordingEnabled | 0x0026 | +| * StatusLightEnabled | 0x0027 | +| * StatusLightBrightness | 0x0028 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * AttributeList | 0xFFFB | @@ -151138,7 +151136,7 @@ class CameraAvStreamManagementSnapshotStreamAllocate : public ClusterCommand { AddArgument("ImageCodec", 0, UINT8_MAX, &mRequest.imageCodec); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - AddArgument("FrameRate", 0, UINT16_MAX, &mRequest.frameRate); + AddArgument("MaxFrameRate", 0, UINT16_MAX, &mRequest.maxFrameRate); #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL AddArgument("BitRate", 0, UINT32_MAX, &mRequest.bitRate); @@ -151170,7 +151168,7 @@ class CameraAvStreamManagementSnapshotStreamAllocate : public ClusterCommand { params.imageCodec = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.imageCodec)]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - params.frameRate = [NSNumber numberWithUnsignedShort:mRequest.frameRate]; + params.maxFrameRate = [NSNumber numberWithUnsignedShort:mRequest.maxFrameRate]; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL params.bitRate = [NSNumber numberWithUnsignedInt:mRequest.bitRate]; @@ -152633,176 +152631,6 @@ class SubscribeAttributeCameraAvStreamManagementHDRModeEnabled : public Subscrib #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute CurrentVideoCodecs - */ -class ReadCameraAvStreamManagementCurrentVideoCodecs : public ReadAttribute { -public: - ReadCameraAvStreamManagementCurrentVideoCodecs() - : ReadAttribute("current-video-codecs") - { - } - - ~ReadCameraAvStreamManagementCurrentVideoCodecs() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentVideoCodecs::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_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeCurrentVideoCodecsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.CurrentVideoCodecs response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CameraAVStreamManagement CurrentVideoCodecs read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCameraAvStreamManagementCurrentVideoCodecs : public SubscribeAttribute { -public: - SubscribeAttributeCameraAvStreamManagementCurrentVideoCodecs() - : SubscribeAttribute("current-video-codecs") - { - } - - ~SubscribeAttributeCameraAvStreamManagementCurrentVideoCodecs() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentVideoCodecs::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_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement 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 subscribeAttributeCurrentVideoCodecsWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.CurrentVideoCodecs 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 CurrentSnapshotConfig - */ -class ReadCameraAvStreamManagementCurrentSnapshotConfig : public ReadAttribute { -public: - ReadCameraAvStreamManagementCurrentSnapshotConfig() - : ReadAttribute("current-snapshot-config") - { - } - - ~ReadCameraAvStreamManagementCurrentSnapshotConfig() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::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_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeCurrentSnapshotConfigWithCompletion:^(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.CurrentSnapshotConfig response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CameraAVStreamManagement CurrentSnapshotConfig read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCameraAvStreamManagementCurrentSnapshotConfig : public SubscribeAttribute { -public: - SubscribeAttributeCameraAvStreamManagementCurrentSnapshotConfig() - : SubscribeAttribute("current-snapshot-config") - { - } - - ~SubscribeAttributeCameraAvStreamManagementCurrentSnapshotConfig() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::CurrentSnapshotConfig::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_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement 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 subscribeAttributeCurrentSnapshotConfigWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(MTRCameraAVStreamManagementClusterSnapshotParamsStruct * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.CurrentSnapshotConfig 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 FabricsUsingCamera */ @@ -153180,58 +153008,6 @@ class ReadCameraAvStreamManagementRankedVideoStreamPrioritiesList : public ReadA } }; -class WriteCameraAvStreamManagementRankedVideoStreamPrioritiesList : public WriteAttribute { -public: - WriteCameraAvStreamManagementRankedVideoStreamPrioritiesList() - : WriteAttribute("ranked-video-stream-priorities-list") - , mComplex(&mValue) - { - AddArgument("attr-name", "ranked-video-stream-priorities-list"); - AddArgument("attr-value", &mComplex); - WriteAttribute::AddArguments(); - } - - ~WriteCameraAvStreamManagementRankedVideoStreamPrioritiesList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::RankedVideoStreamPrioritiesList::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_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement 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; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - for (auto & entry_0 : mValue) { - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0)]; - [array_0 addObject:newElement_0]; - } - value = array_0; - } - - [cluster writeAttributeRankedVideoStreamPrioritiesListWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("CameraAVStreamManagement RankedVideoStreamPrioritiesList write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::List mValue; - TypedComplexArgument> mComplex; -}; - class SubscribeAttributeCameraAvStreamManagementRankedVideoStreamPrioritiesList : public SubscribeAttribute { public: SubscribeAttributeCameraAvStreamManagementRankedVideoStreamPrioritiesList() @@ -181286,14 +181062,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -181312,7 +181080,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands) #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // - make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL