Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / controller / CHIPDeviceController.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *    All rights reserved.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *    @file
22  *      Declaration of CHIP Device Controller, a common class
23  *      that implements connecting and messaging and will later
24  *      be expanded to support discovery, pairing and
25  *      provisioning of CHIP  devices.
26  *
27  */
28
29 #pragma once
30
31 #include <controller/CHIPDevice.h>
32 #include <core/CHIPCore.h>
33 #include <core/CHIPPersistentStorageDelegate.h>
34 #include <core/CHIPTLV.h>
35 #include <messaging/ExchangeMgr.h>
36 #include <support/DLLUtil.h>
37 #include <support/SerializableIntegerSet.h>
38 #include <transport/AdminPairingTable.h>
39 #include <transport/RendezvousSession.h>
40 #include <transport/RendezvousSessionDelegate.h>
41 #include <transport/SecureSessionMgr.h>
42 #include <transport/TransportMgr.h>
43 #include <transport/raw/UDP.h>
44
45 namespace chip {
46
47 namespace Controller {
48
49 constexpr uint16_t kNumMaxActiveDevices = 64;
50 constexpr uint16_t kNumMaxPairedDevices = 128;
51
52 struct ControllerInitParams
53 {
54     PersistentStorageDelegate * storageDelegate = nullptr;
55     System::Layer * systemLayer                 = nullptr;
56     Inet::InetLayer * inetLayer                 = nullptr;
57 };
58
59 class DLL_EXPORT DevicePairingDelegate
60 {
61 public:
62     virtual ~DevicePairingDelegate() {}
63
64     /**
65      * @brief
66      *   Called when the pairing reaches a certain stage.
67      *
68      * @param status Current status of pairing
69      */
70     virtual void OnStatusUpdate(RendezvousSessionDelegate::Status status) {}
71
72     /**
73      * @brief
74      *   Called when the network credentials are needed for the remote device
75      *
76      * @param callback Callback delegate that provisions the network credentials
77      */
78     virtual void OnNetworkCredentialsRequested(RendezvousDeviceCredentialsDelegate * callback) = 0;
79
80     /**
81      * @brief
82      *   Called when the operational credentials are needed for the remote device
83      *
84      * @param csr Certificate signing request from the device
85      * @param csr_length The length of CSR
86      * @param callback Callback delegate that provisions the operational credentials
87      */
88     virtual void OnOperationalCredentialsRequested(const char * csr, size_t csr_length,
89                                                    RendezvousDeviceCredentialsDelegate * callback) = 0;
90
91     /**
92      * @brief
93      *   Called when the pairing is complete (with success or error)
94      *
95      * @param error Error cause, if any
96      */
97     virtual void OnPairingComplete(CHIP_ERROR error) {}
98
99     /**
100      * @brief
101      *   Called when the pairing is deleted (with success or error)
102      *
103      * @param error Error cause, if any
104      */
105     virtual void OnPairingDeleted(CHIP_ERROR error) {}
106 };
107
108 /**
109  * @brief
110  *   Controller applications can use this class to communicate with already paired CHIP devices. The
111  *   application is required to provide access to the persistent storage, where the paired device information
112  *   is stored. This object of this class can be initialized with the data from the storage (List of devices,
113  *   and device pairing information for individual devices). Alternatively, this class can retrieve the
114  *   relevant information when the application tries to communicate with the device
115  */
116 class DLL_EXPORT DeviceController : public SecureSessionMgrDelegate, public PersistentStorageResultDelegate
117 {
118 public:
119     DeviceController();
120     virtual ~DeviceController() {}
121
122     /**
123      * Init function to be used when there exists a device layer that takes care of initializing
124      * System::Layer and InetLayer.
125      */
126     CHIP_ERROR Init(NodeId localDeviceId, ControllerInitParams params);
127
128     // Note: Future modifications should be made to ControllerInitParams
129     CHIP_ERROR Init(NodeId localDeviceId, PersistentStorageDelegate * storageDelegate = nullptr,
130                     System::Layer * systemLayer = nullptr, Inet::InetLayer * inetLayer = nullptr);
131
132     virtual CHIP_ERROR Shutdown();
133
134     /**
135      * @brief
136      *   This function deserializes the provided deviceInfo object, and initializes and outputs the
137      *   corresponding Device object. The lifetime of the output object is tied to that of the DeviceController
138      *   object. The caller must not use the Device object If they free the DeviceController object, or
139      *   after they call ReleaseDevice() on the returned device object.
140      *
141      * @param[in] deviceId   Node ID for the CHIP device
142      * @param[in] deviceInfo Serialized device info for the device
143      * @param[out] device    The output device object
144      *
145      * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
146      */
147     CHIP_ERROR GetDevice(NodeId deviceId, const SerializedDevice & deviceInfo, Device ** device);
148
149     /**
150      * @brief
151      *   This function is similar to the other GetDevice object, except it reads the serialized object from
152      *   the persistent storage.
153      *
154      * @param[in] deviceId   Node ID for the CHIP device
155      * @param[out] device    The output device object
156      *
157      * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
158      */
159     CHIP_ERROR GetDevice(NodeId deviceId, Device ** device);
160
161     CHIP_ERROR SetUdpListenPort(uint16_t listenPort);
162
163     virtual void ReleaseDevice(Device * device);
164
165     // ----- IO -----
166     /**
167      * @brief
168      * Start the event loop task within the CHIP stack
169      * @return CHIP_ERROR   The return status
170      */
171     CHIP_ERROR ServiceEvents();
172
173     /**
174      * @brief
175      *   Allow the CHIP Stack to process any pending events
176      *   This can be called in an event handler loop to tigger callbacks within the CHIP stack
177      * @return CHIP_ERROR   The return status
178      */
179     CHIP_ERROR ServiceEventSignal();
180
181 protected:
182     enum class State
183     {
184         NotInitialized,
185         Initialized
186     };
187
188     State mState;
189
190     /* A list of device objects that can be used for communicating with corresponding
191        CHIP devices. The list does not contain all the paired devices, but only the ones
192        which the controller application is currently accessing.
193     */
194     Device mActiveDevices[kNumMaxActiveDevices];
195
196     SerializableU64Set<kNumMaxPairedDevices> mPairedDevices;
197     bool mPairedDevicesInitialized;
198
199     NodeId mLocalDeviceId;
200     DeviceTransportMgr * mTransportMgr;
201     SecureSessionMgr * mSessionManager;
202     Messaging::ExchangeManager * mExchangeManager;
203     PersistentStorageDelegate * mStorageDelegate;
204     Inet::InetLayer * mInetLayer;
205
206     uint16_t mListenPort;
207     uint16_t GetInactiveDeviceIndex();
208     uint16_t FindDeviceIndex(SecureSessionHandle session);
209     uint16_t FindDeviceIndex(NodeId id);
210     void ReleaseDevice(uint16_t index);
211     void ReleaseDeviceById(NodeId remoteDeviceId);
212     CHIP_ERROR InitializePairedDeviceList();
213     CHIP_ERROR SetPairedDeviceList(const char * pairedDeviceSerializedSet);
214     ControllerDeviceInitParams GetControllerDeviceInitParams();
215
216     Transport::AdminId mAdminId = 0;
217     Transport::AdminPairingTable mAdmins;
218
219 private:
220     //////////// SecureSessionMgrDelegate Implementation ///////////////
221     void OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session,
222                            System::PacketBufferHandle msgBuf, SecureSessionMgr * mgr) override;
223
224     void OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) override;
225     void OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr) override;
226
227     //////////// PersistentStorageResultDelegate Implementation ///////////////
228     void OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR err) override;
229
230     void ReleaseAllDevices();
231
232     System::Layer * mSystemLayer;
233 };
234
235 /**
236  * @brief
237  *   The commissioner applications doesn't advertise itself as an available device for rendezvous
238  *   process. This delegate class provides no-op functions for the advertisement delegate.
239  */
240 class DeviceCommissionerRendezvousAdvertisementDelegate : public RendezvousAdvertisementDelegate
241 {
242 public:
243     /**
244      * @brief
245      *   Starts advertisement of the device for rendezvous availability.
246      */
247     CHIP_ERROR StartAdvertisement() const override { return CHIP_NO_ERROR; }
248
249     /**
250      * @brief
251      *   Stops advertisement of the device for rendezvous availability.
252      */
253     CHIP_ERROR StopAdvertisement() const override { return CHIP_NO_ERROR; }
254 };
255
256 /**
257  * @brief
258  *   The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is
259  *   required to provide write access to the persistent storage, where the paired device information
260  *   will be stored.
261  */
262 class DLL_EXPORT DeviceCommissioner : public DeviceController, public RendezvousSessionDelegate
263 {
264 public:
265     DeviceCommissioner();
266     ~DeviceCommissioner() {}
267
268     /**
269      * Init function to be used when there exists a device layer that takes care of initializing
270      * System::Layer and InetLayer.
271      */
272     CHIP_ERROR Init(NodeId localDeviceId, ControllerInitParams params, DevicePairingDelegate * pairingDelegate = nullptr);
273
274     // Note: Future modifications should be made to ControllerInitParams
275     CHIP_ERROR Init(NodeId localDeviceId, PersistentStorageDelegate * storageDelegate = nullptr,
276                     DevicePairingDelegate * pairingDelegate = nullptr, System::Layer * systemLayer = nullptr,
277                     Inet::InetLayer * inetLayer = nullptr);
278
279     void SetDevicePairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
280
281     CHIP_ERROR Shutdown() override;
282
283     // ----- Connection Management -----
284     /**
285      * @brief
286      *   Pair a CHIP device with the provided Rendezvous connection parameters.
287      *   Use registered DevicePairingDelegate object to receive notifications on
288      *   pairing status updates.
289      *
290      *   Note: Pairing process requires that the caller has registered PersistentStorageDelegate
291      *         in the Init() call.
292      *
293      * @param[in] remoteDeviceId        The remote device Id.
294      * @param[in] params                The Rendezvous connection parameters
295      */
296     CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & params);
297
298     [[deprecated("Available until Rendezvous is implemented")]] CHIP_ERROR
299     PairTestDeviceWithoutSecurity(NodeId remoteDeviceId, const Transport::PeerAddress & peerAddress, SerializedDevice & serialized);
300
301     /**
302      * @brief
303      *   This function stops a pairing process that's in progress. It does not delete the pairing of a previously
304      *   paired device.
305      *
306      * @param[in] remoteDeviceId        The remote device Id.
307      *
308      * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
309      */
310     CHIP_ERROR StopPairing(NodeId remoteDeviceId);
311
312     /**
313      * @brief
314      *   Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
315      *
316      * @param[in] remoteDeviceId        The remote device Id.
317      *
318      * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
319      */
320     CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);
321
322     //////////// RendezvousSessionDelegate Implementation ///////////////
323     void OnRendezvousError(CHIP_ERROR err) override;
324     void OnRendezvousComplete() override;
325     void OnRendezvousStatusUpdate(RendezvousSessionDelegate::Status status, CHIP_ERROR err) override;
326
327     void RendezvousCleanup(CHIP_ERROR status);
328
329     void ReleaseDevice(Device * device) override;
330
331 private:
332     DevicePairingDelegate * mPairingDelegate;
333     RendezvousSession * mRendezvousSession;
334
335     /* This field is an index in mActiveDevices list. The object at this index in the list
336        contains the device object that's tracking the state of the device that's being paired.
337        If no device is currently being paired, this value will be kNumMaxPairedDevices.  */
338     uint16_t mDeviceBeingPaired;
339
340     /* TODO: BLE rendezvous and IP rendezvous should share the same procedure, so this is just a
341        workaround-like flag and should be removed in the future.
342        When using IP rendezvous, we need to disable network provisioning. In the future, network
343        provisioning will no longer be a part of rendezvous procedure. */
344     bool mIsIPRendezvous;
345
346     /* This field is true when device pairing information changes, e.g. a new device is paired, or
347        the pairing for a device is removed. The DeviceCommissioner uses this to decide when to
348        persist the device list */
349     bool mPairedDevicesUpdated;
350
351     DeviceCommissionerRendezvousAdvertisementDelegate mRendezvousAdvDelegate;
352
353     void PersistDeviceList();
354
355     void FreeRendezvousSession();
356
357     CHIP_ERROR LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out);
358
359     uint16_t mNextKeyId = 0;
360 };
361
362 } // namespace Controller
363 } // namespace chip