-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathDeviceManager.h
227 lines (174 loc) · 9.2 KB
/
DeviceManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*
*
* 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 <commands/pairing/PairingCommand.h>
#include <platform/CHIPDeviceLayer.h>
#include <set>
constexpr uint32_t kDefaultSetupPinCode = 20202021;
constexpr uint16_t kDefaultLocalBridgePort = 5540;
constexpr uint16_t kResponseTimeoutSeconds = 30;
class Device
{
public:
Device(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 Device & other) const
{
return mNodeId < other.mNodeId || (mNodeId == other.mNodeId && mEndpointId < other.mEndpointId);
}
private:
chip::NodeId mNodeId;
chip::EndpointId mEndpointId;
};
class DeviceManager : public PairingDelegate
{
public:
DeviceManager() = default;
void Init();
chip::NodeId GetNextAvailableNodeId();
chip::NodeId GetRemoteBridgeNodeId() const { return mRemoteBridgeNodeId; }
chip::NodeId GetLocalBridgeNodeId() const { return mLocalBridgeNodeId; }
void UpdateLastUsedNodeId(chip::NodeId nodeId);
void SetRemoteBridgeNodeId(chip::NodeId nodeId) { mRemoteBridgeNodeId = nodeId; }
void SetLocalBridgePort(uint16_t port) { mLocalBridgePort = port; }
void SetLocalBridgeSetupPinCode(uint32_t pinCode) { mLocalBridgeSetupPinCode = pinCode; }
void SetLocalBridgeNodeId(chip::NodeId nodeId) { mLocalBridgeNodeId = nodeId; }
bool IsAutoSyncEnabled() const { return mAutoSyncEnabled; }
bool IsFabricSyncReady() const { return mRemoteBridgeNodeId != chip::kUndefinedNodeId; }
bool IsLocalBridgeReady() const { return mLocalBridgeNodeId != chip::kUndefinedNodeId; }
void EnableAutoSync(bool state) { mAutoSyncEnabled = state; }
void AddSyncedDevice(const Device & device);
void RemoveSyncedDevice(chip::NodeId nodeId);
/**
* @brief Determines whether a given nodeId corresponds to the "current bridge device," either local or remote.
*
* @param nodeId The ID of the node being checked.
*
* @return true if the nodeId matches either the local or remote bridge device; otherwise, false.
*/
bool IsCurrentBridgeDevice(chip::NodeId nodeId) const { return nodeId == mLocalBridgeNodeId || nodeId == mRemoteBridgeNodeId; }
/**
* @brief Open the commissioning window for a specific device within its own fabric.
*
* This function initiates the process to open the commissioning window for a device identified by the given node ID.
*
* @param nodeId The ID of the node that should open the commissioning window.
* @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 iterations The number of PBKDF (Password-Based Key Derivation Function) iterations to use
* for deriving the PAKE (Password Authenticated Key Exchange) verifier.
* @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 OpenDeviceCommissioningWindow(chip::NodeId nodeId, uint32_t commissioningTimeoutSec, uint32_t iterations,
uint16_t discriminator, const chip::ByteSpan & salt, const chip::ByteSpan & verifier);
/**
* @brief Open the commissioning window of a device from another fabric via its fabric bridge.
*
* This function initiates the process to open the commissioning window for a device that belongs to another
* fabric, accessed through a fabric bridge.
*
* @param remoteEndpointId The endpoint ID of the remote device that should open the commissioning window.
* This endpoint is associated with the device in the other fabric, accessed via the
* fabric bridge.
*
* @note This function is used when the device to be commissioned is part of a different fabric and must be
* accessed through an intermediary fabric bridge.
*/
void OpenRemoteDeviceCommissioningWindow(chip::EndpointId remoteEndpointId);
/**
* @brief Pair a remote fabric bridge with a given node ID.
*
* This function initiates the pairing process for a remote fabric bridge using the specified parameters.
* @param nodeId The user-defined ID for the node being commissioned. It doesn’t need to be the same ID,
* as for the first fabric.
* @param setupPINCode The setup PIN code used to authenticate the pairing process.
* @param deviceRemoteIp The IP address of the remote device that is being paired as part of the fabric bridge.
* @param deviceRemotePort The secured device port of the remote device that is being paired as part of the fabric bridge.
*/
void PairRemoteFabricBridge(chip::NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp, uint16_t deviceRemotePort);
/**
* @brief Pair a remote Matter device to the current fabric.
*
* This function initiates the pairing process for a remote device using the specified parameters.
* @param nodeId The user-defined ID for the node being commissioned. It doesn’t need to be the same ID,
* as for the first fabric.
* @param payload The the QR code payload or a manual pairing code generated by the first commissioner
* instance when opened commissioning window.
*/
void PairRemoteDevice(chip::NodeId nodeId, const char * payload);
/**
* @brief Pair a local fabric bridge with a given node ID.
*
* This function initiates the pairing process for the local fabric bridge using the specified parameters.
* @param nodeId The user-defined ID for the node being commissioned. It doesn’t need to be the same ID,
* as for the first fabric.
*/
void PairLocalFabricBridge(chip::NodeId nodeId);
void UnpairRemoteFabricBridge();
void UnpairLocalFabricBridge();
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);
Device * FindDeviceByEndpoint(chip::EndpointId endpointId);
Device * FindDeviceByNode(chip::NodeId nodeId);
private:
friend DeviceManager & DeviceMgr();
void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) override;
void RequestCommissioningApproval();
void HandleReadSupportedDeviceCategories(chip::TLV::TLVReader & data);
void HandleCommissioningRequestResult(chip::TLV::TLVReader & data);
void HandleAttributePartsListUpdate(chip::TLV::TLVReader & data);
void SendCommissionNodeRequest(uint64_t requestId, uint16_t responseTimeoutSeconds);
void HandleReverseOpenCommissioningWindow(chip::TLV::TLVReader & data);
static DeviceManager sInstance;
chip::NodeId mLastUsedNodeId = 0;
// The Node ID of the remote bridge used for Fabric-Sync
// This represents the bridge on the other ecosystem.
chip::NodeId mRemoteBridgeNodeId = chip::kUndefinedNodeId;
uint16_t mLocalBridgePort = kDefaultLocalBridgePort;
uint32_t mLocalBridgeSetupPinCode = kDefaultSetupPinCode;
// The Node ID of the local bridge used for Fabric-Sync
// This represents the bridge within its own ecosystem.
chip::NodeId mLocalBridgeNodeId = chip::kUndefinedNodeId;
std::set<Device> mSyncedDevices;
bool mAutoSyncEnabled = false;
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;
}