-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fabric-Sync] Integrate fabric bridge functionalities into fabric-sync (
- Loading branch information
1 parent
5512614
commit cefb8bf
Showing
9 changed files
with
980 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
examples/fabric-sync/bridge/include/BridgedAdministratorCommissioning.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <app-common/zap-generated/cluster-objects.h> | ||
#include <app/AttributeAccessInterfaceRegistry.h> | ||
|
||
/** | ||
* @brief CADMIN cluster implementation for handling attribute interactions of bridged device endpoints. | ||
* | ||
* The current Administrator Commissioning Cluster server's zap generated code will automatically | ||
* register an Attribute Access Interface for the root node endpoint implementation. In order to | ||
* properly respond to a read attribute for bridged devices we are representing, we override the | ||
* currently registered Attribute Interface such that we are first to receive any read attribute | ||
* request on Administrator Commissioning Cluster, and if it is not an endpoint for a device we | ||
* are a bridge for we redirect to the default cluster server implementation of Administrator | ||
* Commissioning Cluster. | ||
*/ | ||
class BridgedAdministratorCommissioning : public chip::app::AttributeAccessInterface | ||
{ | ||
public: | ||
// Register for the AdministratorCommissioning cluster on all endpoints. | ||
BridgedAdministratorCommissioning() : | ||
AttributeAccessInterface(chip::NullOptional, chip::app::Clusters::AdministratorCommissioning::Id) | ||
{} | ||
|
||
CHIP_ERROR Init(); | ||
|
||
CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & aPath, chip::app::AttributeValueEncoder & aEncoder) override; | ||
|
||
// We do not allow writing to CADMIN attributes of a bridged device endpoint. We simply redirect | ||
// write requests to the original attribute interface. | ||
CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & aPath, chip::app::AttributeValueDecoder & aDecoder) override | ||
{ | ||
VerifyOrDie(mOriginalAttributeInterface); | ||
return mOriginalAttributeInterface->Write(aPath, aDecoder); | ||
} | ||
|
||
private: | ||
// If mOriginalAttributeInterface is removed from here, the class description needs to be updated | ||
// to reflect this change. | ||
chip::app::AttributeAccessInterface * mOriginalAttributeInterface = nullptr; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* | ||
* 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 <app-common/zap-generated/cluster-objects.h> | ||
#include <app/util/attribute-storage.h> | ||
|
||
#include <string> | ||
|
||
class BridgedDevice | ||
{ | ||
public: | ||
/// Defines all attributes that we keep track of for a bridged device | ||
struct BridgedAttributes | ||
{ | ||
std::string uniqueId; | ||
std::string vendorName; | ||
uint16_t vendorId = 0; | ||
std::string productName; | ||
uint16_t productId = 0; | ||
std::string nodeLabel; | ||
uint16_t hardwareVersion = 0; | ||
std::string hardwareVersionString; | ||
uint32_t softwareVersion = 0; | ||
std::string softwareVersionString; | ||
}; | ||
|
||
struct AdminCommissioningAttributes | ||
{ | ||
chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum commissioningWindowStatus = | ||
chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen; | ||
std::optional<chip::FabricIndex> openerFabricIndex = std::nullopt; | ||
std::optional<chip::VendorId> openerVendorId = std::nullopt; | ||
}; | ||
|
||
BridgedDevice(chip::ScopedNodeId scopedNodeId); | ||
virtual ~BridgedDevice() = default; | ||
|
||
[[nodiscard]] bool IsReachable() const { return mReachable; } | ||
void SetReachable(bool reachable); | ||
// Reachability attribute changed and requires marking attribute as dirty and sending | ||
// event. | ||
void ReachableChanged(bool reachable); | ||
|
||
void LogActiveChangeEvent(uint32_t promisedActiveDurationMs); | ||
|
||
[[nodiscard]] bool IsIcd() const { return mIsIcd; } | ||
void SetIcd(bool icd) { mIsIcd = icd; } | ||
|
||
inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; | ||
inline chip::EndpointId GetEndpointId() { return mEndpointId; }; | ||
inline chip::ScopedNodeId GetScopedNodeId() { return mScopedNodeId; }; | ||
inline void SetParentEndpointId(chip::EndpointId id) { mParentEndpointId = id; }; | ||
inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; | ||
|
||
[[nodiscard]] const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } | ||
void SetBridgedAttributes(const BridgedAttributes & value) { mAttributes = value; } | ||
|
||
void SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes); | ||
const AdminCommissioningAttributes & GetAdminCommissioningAttributes() const { return mAdminCommissioningAttributes; } | ||
|
||
/// Convenience method to set just the unique id of a bridged device as it | ||
/// is one of the few attributes that is not always bulk-set | ||
void SetUniqueId(const std::string & value) { mAttributes.uniqueId = value; } | ||
|
||
protected: | ||
bool mReachable = false; | ||
bool mIsIcd = false; | ||
|
||
chip::ScopedNodeId mScopedNodeId; | ||
chip::EndpointId mEndpointId = 0; | ||
chip::EndpointId mParentEndpointId = 0; | ||
|
||
BridgedAttributes mAttributes; | ||
AdminCommissioningAttributes mAdminCommissioningAttributes; | ||
}; |
32 changes: 32 additions & 0 deletions
32
examples/fabric-sync/bridge/include/BridgedDeviceBasicInformationImpl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* 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. | ||
*/ | ||
#pragma once | ||
|
||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/AttributeAccessInterface.h> | ||
|
||
class BridgedDeviceBasicInformationImpl : public chip::app::AttributeAccessInterface | ||
{ | ||
public: | ||
BridgedDeviceBasicInformationImpl() : | ||
chip::app::AttributeAccessInterface(chip::NullOptional /* endpointId */, | ||
chip::app::Clusters::BridgedDeviceBasicInformation::Id) | ||
{} | ||
|
||
// AttributeAccessInterface implementation | ||
CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & path, chip::app::AttributeValueEncoder & encoder) override; | ||
CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & path, chip::app::AttributeValueDecoder & decoder) override; | ||
}; |
136 changes: 136 additions & 0 deletions
136
examples/fabric-sync/bridge/include/BridgedDeviceManager.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* | ||
* 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 <platform/CHIPDeviceLayer.h> | ||
|
||
#include "BridgedDevice.h" | ||
|
||
#include <memory> | ||
|
||
class BridgedDeviceManager | ||
{ | ||
public: | ||
BridgedDeviceManager() = default; | ||
|
||
/** | ||
* @brief Initializes the BridgedDeviceManager. | ||
* | ||
* This function sets up the initial state of the BridgedDeviceManager, clearing | ||
* any existing devices and setting the starting dynamic endpoint ID. | ||
*/ | ||
void Init(); | ||
|
||
/** | ||
* @brief Adds a device to a dynamic endpoint. | ||
* | ||
* This function attempts to add a device to a dynamic endpoint. It tries to find an available | ||
* endpoint slot and retries the addition process up to a specified maximum number of times if | ||
* the endpoint already exists. If the addition is successful, it returns the index of the | ||
* dynamic endpoint; | ||
* | ||
* Ensures that the device has a unique id: | ||
* - device MUST set its unique id if any BEFORE calling this method | ||
* - if no unique id (i.e. empty string), a new unique id will be generated | ||
* - Add will fail if the unique id is not unique | ||
* | ||
* @param dev A pointer to the device to be added. | ||
* @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID. | ||
* @return int The index of the dynamic endpoint if successful, nullopt otherwise | ||
*/ | ||
std::optional<unsigned> AddDeviceEndpoint(std::unique_ptr<BridgedDevice> dev, | ||
chip::EndpointId parentEndpointId = chip::kInvalidEndpointId); | ||
|
||
/** | ||
* @brief Removes a device from a dynamic endpoint. | ||
* | ||
* This function attempts to remove a device from a dynamic endpoint by iterating through the | ||
* available endpoints and checking if the device matches. If the device is found, it clears the | ||
* dynamic endpoint, logs the removal, and returns the index of the removed endpoint. | ||
* If the device is not found, it returns -1. | ||
* | ||
* @param dev A pointer to the device to be removed. | ||
* @return int The index of the removed dynamic endpoint if successful, -1 otherwise. | ||
*/ | ||
int RemoveDeviceEndpoint(BridgedDevice * dev); | ||
|
||
/** | ||
* @brief Gets a device from its endpoint ID. | ||
* | ||
* This function iterates through the available devices and returns the device that matches the | ||
* specified endpoint ID. If no device matches the endpoint ID, it returns nullptr. | ||
* | ||
* @param endpointId The endpoint ID of the device to be retrieved. | ||
* @return BridgedDevice* A pointer to the device if found, nullptr otherwise. | ||
*/ | ||
BridgedDevice * GetDevice(chip::EndpointId endpointId) const; | ||
|
||
/** | ||
* @brief Gets a device from its ScopedNodeId. | ||
* | ||
* This function iterates through the available devices and returns the device that matches the | ||
* specified ScopedNodeId. If no device matches the ScopedNodeId, it returns nullptr. | ||
* | ||
* @param scopedNodeId The ScopedNodeId of the device to be retrieved. | ||
* @return BridgedDevice* A pointer to the device if found, nullptr otherwise. | ||
*/ | ||
BridgedDevice * GetDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) const; | ||
|
||
/** | ||
* @brief Removes a device from a dynamic endpoint by its ScopedNodeId. | ||
* | ||
* This function attempts to remove a device and the associated dynamic endpoint by iterating through | ||
* the available device and checking if the device matches the specified ScopedNodeId. If the device is | ||
* found, it removes the dynamic endpoint. | ||
* | ||
* @param scopedNodeId The ScopedNodeId of the device to be removed. | ||
* @return unsigned of the index of the removed dynamic endpoint if successful, nullopt otherwise. | ||
*/ | ||
std::optional<unsigned> RemoveDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId); | ||
|
||
/** | ||
* Finds the device with the given unique id (if any) | ||
*/ | ||
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<BridgedDevice> 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; | ||
} |
Oops, something went wrong.