Skip to content

Commit b3fc1d0

Browse files
authoredMay 31, 2024
[Fabric-Bridge] Refactor device management from main (#33618)
* [Fabric-Bridge] Refactor device management from main * Address review comments
1 parent 55012bf commit b3fc1d0

File tree

5 files changed

+260
-211
lines changed

5 files changed

+260
-211
lines changed
 

‎examples/fabric-bridge-app/linux/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ executable("fabric-bridge-app") {
2222
sources = [
2323
"${chip_root}/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h",
2424
"Device.cpp",
25+
"DeviceManager.cpp",
2526
"include/Device.h",
27+
"include/DeviceManager.h",
2628
"main.cpp",
2729
]
2830

‎examples/fabric-bridge-app/linux/Device.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ void Device::SetReachable(bool aReachable)
4646

4747
if (aReachable)
4848
{
49-
ChipLogProgress(DeviceLayer, "Device[%s]: ONLINE", mName);
49+
ChipLogProgress(NotSpecified, "Device[%s]: ONLINE", mName);
5050
}
5151
else
5252
{
53-
ChipLogProgress(DeviceLayer, "Device[%s]: OFFLINE", mName);
53+
ChipLogProgress(NotSpecified, "Device[%s]: OFFLINE", mName);
5454
}
5555

5656
if (changed)
@@ -63,7 +63,7 @@ void Device::SetName(const char * szName)
6363
{
6464
bool changed = (strncmp(mName, szName, sizeof(mName)) != 0);
6565

66-
ChipLogProgress(DeviceLayer, "Device[%s]: New Name=\"%s\"", mName, szName);
66+
ChipLogProgress(NotSpecified, "Device[%s]: New Name=\"%s\"", mName, szName);
6767

6868
chip::Platform::CopyString(mName, szName);
6969

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include "DeviceManager.h"
20+
21+
#include <app-common/zap-generated/ids/Attributes.h>
22+
#include <app-common/zap-generated/ids/Clusters.h>
23+
#include <app/AttributeAccessInterfaceRegistry.h>
24+
#include <app/ConcreteAttributePath.h>
25+
#include <app/EventLogging.h>
26+
#include <app/reporting/reporting.h>
27+
#include <app/server/Server.h>
28+
#include <app/util/af-types.h>
29+
#include <app/util/attribute-storage.h>
30+
#include <app/util/endpoint-config-api.h>
31+
#include <app/util/util.h>
32+
#include <lib/support/CHIPMem.h>
33+
#include <lib/support/ZclString.h>
34+
35+
#include <cstdio>
36+
#include <string>
37+
38+
using namespace chip;
39+
using namespace chip::app;
40+
using namespace chip::Credentials;
41+
using namespace chip::Inet;
42+
using namespace chip::Transport;
43+
using namespace chip::DeviceLayer;
44+
using namespace chip::app::Clusters;
45+
46+
namespace {
47+
constexpr uint8_t kMaxRetries = 10;
48+
} // namespace
49+
50+
DeviceManager::DeviceManager()
51+
{
52+
memset(mDevices, 0, sizeof(mDevices));
53+
mFirstDynamicEndpointId = static_cast<chip::EndpointId>(
54+
static_cast<int>(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1))) + 1);
55+
mCurrentEndpointId = mFirstDynamicEndpointId;
56+
}
57+
58+
int DeviceManager::AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep,
59+
const chip::Span<const EmberAfDeviceType> & deviceTypeList,
60+
const chip::Span<chip::DataVersion> & dataVersionStorage, chip::EndpointId parentEndpointId)
61+
{
62+
uint8_t index = 0;
63+
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
64+
{
65+
if (nullptr == mDevices[index])
66+
{
67+
mDevices[index] = dev;
68+
CHIP_ERROR err;
69+
int retryCount = 0;
70+
while (retryCount < kMaxRetries)
71+
{
72+
DeviceLayer::StackLock lock;
73+
dev->SetEndpointId(mCurrentEndpointId);
74+
dev->SetParentEndpointId(parentEndpointId);
75+
err =
76+
emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId);
77+
if (err == CHIP_NO_ERROR)
78+
{
79+
ChipLogProgress(NotSpecified, "Added device %s to dynamic endpoint %d (index=%d)", dev->GetName(),
80+
mCurrentEndpointId, index);
81+
return index;
82+
}
83+
if (err != CHIP_ERROR_ENDPOINT_EXISTS)
84+
{
85+
return -1; // Return error as endpoint addition failed due to an error other than endpoint already exists
86+
}
87+
// Increment the endpoint ID and handle wrap condition
88+
if (++mCurrentEndpointId < mFirstDynamicEndpointId)
89+
{
90+
mCurrentEndpointId = mFirstDynamicEndpointId;
91+
}
92+
retryCount++;
93+
}
94+
ChipLogError(NotSpecified, "Failed to add dynamic endpoint after %d retries", kMaxRetries);
95+
return -1; // Return error as all retries are exhausted
96+
}
97+
index++;
98+
}
99+
ChipLogProgress(NotSpecified, "Failed to add dynamic endpoint: No endpoints available!");
100+
return -1;
101+
}
102+
103+
int DeviceManager::RemoveDeviceEndpoint(Device * dev)
104+
{
105+
uint8_t index = 0;
106+
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
107+
{
108+
if (mDevices[index] == dev)
109+
{
110+
DeviceLayer::StackLock lock;
111+
// Silence complaints about unused ep when progress logging
112+
// disabled.
113+
[[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index);
114+
mDevices[index] = nullptr;
115+
ChipLogProgress(NotSpecified, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index);
116+
return index;
117+
}
118+
index++;
119+
}
120+
return -1;
121+
}
122+
123+
Device * DeviceManager::GetDevice(uint16_t index) const
124+
{
125+
if (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
126+
{
127+
return mDevices[index];
128+
}
129+
return nullptr;
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include <platform/CHIPDeviceLayer.h>
22+
23+
#include "Device.h"
24+
25+
class DeviceManager
26+
{
27+
public:
28+
DeviceManager();
29+
30+
/**
31+
* @brief Adds a device to a dynamic endpoint.
32+
*
33+
* This function attempts to add a device to a dynamic endpoint. It tries to find an available
34+
* endpoint slot and retries the addition process up to a specified maximum number of times if
35+
* the endpoint already exists. If the addition is successful, it returns the index of the
36+
* dynamic endpoint; otherwise, it returns -1.
37+
*
38+
* @param dev A pointer to the device to be added.
39+
* @param ep A pointer to the endpoint type.
40+
* @param deviceTypeList A span containing the list of device types.
41+
* @param dataVersionStorage A span containing the data version storage.
42+
* @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID.
43+
* @return int The index of the dynamic endpoint if successful, -1 otherwise.
44+
*/
45+
int AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep, const chip::Span<const EmberAfDeviceType> & deviceTypeList,
46+
const chip::Span<chip::DataVersion> & dataVersionStorage,
47+
chip::EndpointId parentEndpointId = chip::kInvalidEndpointId);
48+
49+
/**
50+
* @brief Removes a device from a dynamic endpoint.
51+
*
52+
* This function attempts to remove a device from a dynamic endpoint by iterating through the
53+
* available endpoints and checking if the device matches. If the device is found, it clears the
54+
* dynamic endpoint, logs the removal, and returns the index of the removed endpoint.
55+
* If the device is not found, it returns -1.
56+
*
57+
* @param dev A pointer to the device to be removed.
58+
* @return int The index of the removed dynamic endpoint if successful, -1 otherwise.
59+
*/
60+
int RemoveDeviceEndpoint(Device * dev);
61+
62+
Device * GetDevice(uint16_t index) const;
63+
64+
private:
65+
chip::EndpointId mCurrentEndpointId;
66+
chip::EndpointId mFirstDynamicEndpointId;
67+
Device * mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1];
68+
};

0 commit comments

Comments
 (0)