• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *    Copyright (c) 2020, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *    POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for Thread helper.
32  */
33 
34 #ifndef OTBR_THREAD_HELPER_HPP_
35 #define OTBR_THREAD_HELPER_HPP_
36 
37 #include "openthread-br/config.h"
38 
39 #include <chrono>
40 #include <functional>
41 #include <map>
42 #include <random>
43 #include <string>
44 #include <vector>
45 
46 #include <openthread/instance.h>
47 #include <openthread/ip6.h>
48 #include <openthread/jam_detection.h>
49 #include <openthread/joiner.h>
50 #include <openthread/netdata.h>
51 #include <openthread/thread.h>
52 #include "mdns/mdns.hpp"
53 #if OTBR_ENABLE_TELEMETRY_DATA_API
54 #include "proto/thread_telemetry.pb.h"
55 #endif
56 
57 namespace otbr {
58 namespace Ncp {
59 class ControllerOpenThread;
60 }
61 } // namespace otbr
62 
63 namespace otbr {
64 namespace agent {
65 
66 /**
67  * This class implements Thread helper.
68  */
69 class ThreadHelper
70 {
71 public:
72     using DeviceRoleHandler       = std::function<void(otDeviceRole)>;
73     using ScanHandler             = std::function<void(otError, const std::vector<otActiveScanResult> &)>;
74     using EnergyScanHandler       = std::function<void(otError, const std::vector<otEnergyScanResult> &)>;
75     using ResultHandler           = std::function<void(otError)>;
76     using AttachHandler           = std::function<void(otError, int64_t)>;
77     using UpdateMeshCopTxtHandler = std::function<void(std::map<std::string, std::vector<uint8_t>>)>;
78     using DatasetChangeHandler    = std::function<void(const otOperationalDatasetTlvs &)>;
79 
80     /**
81      * The constructor of a Thread helper.
82      *
83      * @param[in] aInstance  The Thread instance.
84      * @param[in] aNcp       The ncp controller.
85      *
86      */
87     ThreadHelper(otInstance *aInstance, otbr::Ncp::ControllerOpenThread *aNcp);
88 
89     /**
90      * This method adds a callback for device role change.
91      *
92      * @param[in] aHandler  The device role handler.
93      *
94      */
95     void AddDeviceRoleHandler(DeviceRoleHandler aHandler);
96 
97     /**
98      * This method adds a callback for active dataset change.
99      *
100      * @param[in]  aHandler   The active dataset change handler.
101      */
102     void AddActiveDatasetChangeHandler(DatasetChangeHandler aHandler);
103 
104     /**
105      * This method permits unsecure join on port.
106      *
107      * @param[in] aPort     The port number.
108      * @param[in] aSeconds  The timeout to close the port, 0 for never close.
109      *
110      * @returns The error value of underlying OpenThread api calls.
111      *
112      */
113     otError PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds);
114 
115     /**
116      * This method performs a Thread network scan.
117      *
118      * @param[in] aHandler  The scan result handler.
119      *
120      */
121     void Scan(ScanHandler aHandler);
122 
123     /**
124      * This method performs an IEEE 802.15.4 Energy Scan.
125      *
126      * @param[in] aScanDuration  The duration for the scan, in milliseconds.
127      * @param[in] aHandler       The scan result handler.
128      *
129      */
130     void EnergyScan(uint32_t aScanDuration, EnergyScanHandler aHandler);
131 
132     /**
133      * This method attaches the device to the Thread network.
134      *
135      * @note The joiner start and the attach proccesses are exclusive
136      *
137      * @param[in] aNetworkName  The network name.
138      * @param[in] aPanId        The pan id, UINT16_MAX for random.
139      * @param[in] aExtPanId     The extended pan id, UINT64_MAX for random.
140      * @param[in] aNetworkKey   The network key, empty for random.
141      * @param[in] aPSKc         The pre-shared commissioner key, empty for random.
142      * @param[in] aChannelMask  A bitmask for valid channels, will random select one.
143      * @param[in] aHandler      The attach result handler.
144      *
145      */
146     void Attach(const std::string          &aNetworkName,
147                 uint16_t                    aPanId,
148                 uint64_t                    aExtPanId,
149                 const std::vector<uint8_t> &aNetworkKey,
150                 const std::vector<uint8_t> &aPSKc,
151                 uint32_t                    aChannelMask,
152                 AttachHandler               aHandler);
153 
154     /**
155      * This method detaches the device from the Thread network.
156      *
157      * @returns The error value of underlying OpenThread API calls.
158      *
159      */
160     otError Detach(void);
161 
162     /**
163      * This method attaches the device to the Thread network.
164      *
165      * @note The joiner start and the attach proccesses are exclusive, and the
166      *       network parameter will be set through the active dataset.
167      *
168      * @param[in] aHandler  The attach result handler.
169      *
170      */
171     void Attach(AttachHandler aHandler);
172 
173     /**
174      * This method makes all nodes in the current network attach to the network specified by the dataset TLVs.
175      *
176      * @param[in] aDatasetTlvs  The dataset TLVs.
177      * @param[in] aHandler      The result handler.
178      *
179      */
180     void AttachAllNodesTo(const std::vector<uint8_t> &aDatasetTlvs, AttachHandler aHandler);
181 
182     /**
183      * This method resets the OpenThread stack.
184      *
185      * @returns The error value of underlying OpenThread api calls.
186      *
187      */
188     otError Reset(void);
189 
190     /**
191      * This method triggers a thread join process.
192      *
193      * @note The joiner start and the attach proccesses are exclusive
194      *
195      * @param[in] aPskd             The pre-shared key for device.
196      * @param[in] aProvisioningUrl  The provision url.
197      * @param[in] aVendorName       The vendor name.
198      * @param[in] aVendorModel      The vendor model.
199      * @param[in] aVendorSwVersion  The vendor software version.
200      * @param[in] aVendorData       The vendor custom data.
201      * @param[in] aHandler          The join result handler.
202      *
203      */
204     void JoinerStart(const std::string &aPskd,
205                      const std::string &aProvisioningUrl,
206                      const std::string &aVendorName,
207                      const std::string &aVendorModel,
208                      const std::string &aVendorSwVersion,
209                      const std::string &aVendorData,
210                      ResultHandler      aHandler);
211 
212     /**
213      * This method tries to restore the network after reboot
214      *
215      * @returns The error value of underlying OpenThread api calls.
216      *
217      */
218     otError TryResumeNetwork(void);
219 
220     /**
221      * This method returns the underlying OpenThread instance.
222      *
223      * @returns The underlying instance.
224      *
225      */
GetInstance(void)226     otInstance *GetInstance(void) { return mInstance; }
227 
228     /**
229      * This method handles OpenThread state changed notification.
230      *
231      * @param[in] aFlags    A bit-field indicating specific state that has changed.  See `OT_CHANGED_*` definitions.
232      *
233      */
234     void StateChangedCallback(otChangedFlags aFlags);
235 
236 #if OTBR_ENABLE_DBUS_SERVER
237     /**
238      * This method sets a callback for calls of UpdateVendorMeshCopTxtEntries D-Bus API.
239      *
240      * @param[in] aHandler  The handler on MeshCoP TXT changes.
241      *
242      */
SetUpdateMeshCopTxtHandler(UpdateMeshCopTxtHandler aHandler)243     void SetUpdateMeshCopTxtHandler(UpdateMeshCopTxtHandler aHandler)
244     {
245         mUpdateMeshCopTxtHandler = std::move(aHandler);
246     }
247 
248     /**
249      * This method handles MeshCoP TXT updates done by UpdateVendorMeshCopTxtEntries D-Bus API.
250      *
251      * @param[in] aUpdate  The key-value pairs to be updated in the TXT record.
252      *
253      */
254     void OnUpdateMeshCopTxt(std::map<std::string, std::vector<uint8_t>> aUpdate);
255 #endif
256 
257     void DetachGracefully(ResultHandler aHandler);
258 
259 #if OTBR_ENABLE_TELEMETRY_DATA_API
260     /**
261      * This method populates the telemetry data with best effort. The best effort means, for a given
262      * telemetry, if its retrieval has error, it is left unpopulated and the process continues to
263      * retrieve the remaining telemetries instead of the immediately return. The error code
264      * OT_ERRROR_FAILED will be returned if there is one or more error(s) happened in the process.
265      *
266      * @param[in] aPublisher     The Mdns::Publisher to provide MDNS telemetry if it is not `nullptr`.
267      * @param[in] telemetryData  The telemetry data to be populated.
268      *
269      * @retval OTBR_ERROR_NONE  There is no error happened in the process.
270      * @retval OT_ERRROR_FAILED There is one or more error(s) happened in the process.
271      */
272     otError RetrieveTelemetryData(Mdns::Publisher *aPublisher, threadnetwork::TelemetryData &telemetryData);
273 #endif // OTBR_ENABLE_TELEMETRY_DATA_API
274 
275     /**
276      * This method logs OpenThread action result.
277      *
278      * @param[in] aAction  The action OpenThread performs.
279      * @param[in] aError   The action result.
280      *
281      */
282     static void LogOpenThreadResult(const char *aAction, otError aError);
283 
284 private:
285     static void ActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper);
286     void        ActiveScanHandler(otActiveScanResult *aResult);
287 
288     static void EnergyScanCallback(otEnergyScanResult *aResult, void *aThreadHelper);
289     void        EnergyScanCallback(otEnergyScanResult *aResult);
290 
291     static void JoinerCallback(otError aError, void *aThreadHelper);
292     void        JoinerCallback(otError aResult);
293 
294     static void MgmtSetResponseHandler(otError aResult, void *aContext);
295     void        MgmtSetResponseHandler(otError aResult);
296 
297     static void DetachGracefullyCallback(void *aContext);
298     void        DetachGracefullyCallback(void);
299 
300     void    RandomFill(void *aBuf, size_t size);
301     uint8_t RandomChannelFromChannelMask(uint32_t aChannelMask);
302 
303     void ActiveDatasetChangedCallback(void);
304 
305     otInstance *mInstance;
306 
307     otbr::Ncp::ControllerOpenThread *mNcp;
308 
309     ScanHandler                     mScanHandler;
310     std::vector<otActiveScanResult> mScanResults;
311     EnergyScanHandler               mEnergyScanHandler;
312     std::vector<otEnergyScanResult> mEnergyScanResults;
313 
314     std::vector<DeviceRoleHandler>    mDeviceRoleHandlers;
315     std::vector<DatasetChangeHandler> mActiveDatasetChangeHandlers;
316 
317     std::map<uint16_t, size_t> mUnsecurePortRefCounter;
318 
319     bool mWaitingMgmtSetResponse =
320         false; // During waiting for mgmt set response, calls to AttachHandler by StateChangedCallback will be ignored
321     int64_t       mAttachDelayMs = 0;
322     AttachHandler mAttachHandler;
323     ResultHandler mJoinerHandler;
324 
325     ResultHandler mDetachGracefullyHandler = nullptr;
326 
327     otOperationalDatasetTlvs mAttachPendingDatasetTlvs = {};
328 
329     std::random_device mRandomDevice;
330 
331 #if OTBR_ENABLE_DBUS_SERVER
332     UpdateMeshCopTxtHandler mUpdateMeshCopTxtHandler;
333 #endif
334 
335 #if OTBR_ENABLE_TELEMETRY_DATA_API && (OTBR_ENABLE_NAT64 || OTBR_ENABLE_DHCP6_PD)
336     static constexpr uint8_t kNat64PdCommonHashSaltLength = 16;
337     uint8_t                  mNat64PdCommonSalt[kNat64PdCommonHashSaltLength];
338 #endif
339 };
340 
341 } // namespace agent
342 } // namespace otbr
343 
344 #endif // OTBR_THREAD_HELPER_HPP_
345