• 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 <chrono>
38 #include <functional>
39 #include <map>
40 #include <random>
41 #include <string>
42 #include <vector>
43 
44 #include <openthread/instance.h>
45 #include <openthread/ip6.h>
46 #include <openthread/jam_detection.h>
47 #include <openthread/joiner.h>
48 #include <openthread/netdata.h>
49 #include <openthread/thread.h>
50 
51 namespace otbr {
52 namespace Ncp {
53 class ControllerOpenThread;
54 }
55 } // namespace otbr
56 
57 namespace otbr {
58 namespace agent {
59 
60 /**
61  * This class implements Thread helper.
62  */
63 class ThreadHelper
64 {
65 public:
66     using DeviceRoleHandler       = std::function<void(otDeviceRole)>;
67     using ScanHandler             = std::function<void(otError, const std::vector<otActiveScanResult> &)>;
68     using EnergyScanHandler       = std::function<void(otError, const std::vector<otEnergyScanResult> &)>;
69     using ResultHandler           = std::function<void(otError)>;
70     using AttachHandler           = std::function<void(otError, int64_t)>;
71     using UpdateMeshCopTxtHandler = std::function<void(std::map<std::string, std::vector<uint8_t>>)>;
72     using DatasetChangeHandler    = std::function<void(const otOperationalDatasetTlvs &)>;
73 
74     /**
75      * The constructor of a Thread helper.
76      *
77      * @param[in] aInstance  The Thread instance.
78      * @param[in] aNcp       The ncp controller.
79      *
80      */
81     ThreadHelper(otInstance *aInstance, otbr::Ncp::ControllerOpenThread *aNcp);
82 
83     /**
84      * This method adds a callback for device role change.
85      *
86      * @param[in] aHandler  The device role handler.
87      *
88      */
89     void AddDeviceRoleHandler(DeviceRoleHandler aHandler);
90 
91     /**
92      * This method adds a callback for active dataset change.
93      *
94      * @param[in]  aHandler   The active dataset change handler.
95      */
96     void AddActiveDatasetChangeHandler(DatasetChangeHandler aHandler);
97 
98     /**
99      * This method permits unsecure join on port.
100      *
101      * @param[in] aPort     The port number.
102      * @param[in] aSeconds  The timeout to close the port, 0 for never close.
103      *
104      * @returns The error value of underlying OpenThread api calls.
105      *
106      */
107     otError PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds);
108 
109     /**
110      * This method performs a Thread network scan.
111      *
112      * @param[in] aHandler  The scan result handler.
113      *
114      */
115     void Scan(ScanHandler aHandler);
116 
117     /**
118      * This method performs an IEEE 802.15.4 Energy Scan.
119      *
120      * @param[in] aScanDuration  The duration for the scan, in milliseconds.
121      * @param[in] aHandler       The scan result handler.
122      *
123      */
124     void EnergyScan(uint32_t aScanDuration, EnergyScanHandler aHandler);
125 
126     /**
127      * This method attaches the device to the Thread network.
128      *
129      * @note The joiner start and the attach proccesses are exclusive
130      *
131      * @param[in] aNetworkName  The network name.
132      * @param[in] aPanId        The pan id, UINT16_MAX for random.
133      * @param[in] aExtPanId     The extended pan id, UINT64_MAX for random.
134      * @param[in] aNetworkKey   The network key, empty for random.
135      * @param[in] aPSKc         The pre-shared commissioner key, empty for random.
136      * @param[in] aChannelMask  A bitmask for valid channels, will random select one.
137      * @param[in] aHandler      The attach result handler.
138      *
139      */
140     void Attach(const std::string &         aNetworkName,
141                 uint16_t                    aPanId,
142                 uint64_t                    aExtPanId,
143                 const std::vector<uint8_t> &aNetworkKey,
144                 const std::vector<uint8_t> &aPSKc,
145                 uint32_t                    aChannelMask,
146                 AttachHandler               aHandler);
147 
148     /**
149      * This method detaches the device from the Thread network.
150      *
151      * @returns The error value of underlying OpenThread API calls.
152      *
153      */
154     otError Detach(void);
155 
156     /**
157      * This method attaches the device to the Thread network.
158      *
159      * @note The joiner start and the attach proccesses are exclusive, and the
160      *       network parameter will be set through the active dataset.
161      *
162      * @param[in] aHandler  The attach result handler.
163      *
164      */
165     void Attach(AttachHandler aHandler);
166 
167     /**
168      * This method makes all nodes in the current network attach to the network specified by the dataset TLVs.
169      *
170      * @param[in] aDatasetTlvs  The dataset TLVs.
171      * @param[in] aHandler      The result handler.
172      *
173      */
174     void AttachAllNodesTo(const std::vector<uint8_t> &aDatasetTlvs, AttachHandler aHandler);
175 
176     /**
177      * This method resets the OpenThread stack.
178      *
179      * @returns The error value of underlying OpenThread api calls.
180      *
181      */
182     otError Reset(void);
183 
184     /**
185      * This method triggers a thread join process.
186      *
187      * @note The joiner start and the attach proccesses are exclusive
188      *
189      * @param[in] aPskd             The pre-shared key for device.
190      * @param[in] aProvisioningUrl  The provision url.
191      * @param[in] aVendorName       The vendor name.
192      * @param[in] aVendorModel      The vendor model.
193      * @param[in] aVendorSwVersion  The vendor software version.
194      * @param[in] aVendorData       The vendor custom data.
195      * @param[in] aHandler          The join result handler.
196      *
197      */
198     void JoinerStart(const std::string &aPskd,
199                      const std::string &aProvisioningUrl,
200                      const std::string &aVendorName,
201                      const std::string &aVendorModel,
202                      const std::string &aVendorSwVersion,
203                      const std::string &aVendorData,
204                      ResultHandler      aHandler);
205 
206     /**
207      * This method tries to restore the network after reboot
208      *
209      * @returns The error value of underlying OpenThread api calls.
210      *
211      */
212     otError TryResumeNetwork(void);
213 
214     /**
215      * This method returns the underlying OpenThread instance.
216      *
217      * @returns The underlying instance.
218      *
219      */
GetInstance(void)220     otInstance *GetInstance(void) { return mInstance; }
221 
222     /**
223      * This method handles OpenThread state changed notification.
224      *
225      * @param[in] aFlags    A bit-field indicating specific state that has changed.  See `OT_CHANGED_*` definitions.
226      *
227      */
228     void StateChangedCallback(otChangedFlags aFlags);
229 
230 #if OTBR_ENABLE_DBUS_SERVER
231     /**
232      * This method sets a callback for calls of UpdateVendorMeshCopTxtEntries D-Bus API.
233      *
234      * @param[in] aHandler  The handler on MeshCoP TXT changes.
235      *
236      */
SetUpdateMeshCopTxtHandler(UpdateMeshCopTxtHandler aHandler)237     void SetUpdateMeshCopTxtHandler(UpdateMeshCopTxtHandler aHandler)
238     {
239         mUpdateMeshCopTxtHandler = std::move(aHandler);
240     }
241 
242     /**
243      * This method handles MeshCoP TXT updates done by UpdateVendorMeshCopTxtEntries D-Bus API.
244      *
245      * @param[in] aUpdate  The key-value pairs to be updated in the TXT record.
246      *
247      */
248     void OnUpdateMeshCopTxt(std::map<std::string, std::vector<uint8_t>> aUpdate);
249 #endif
250 
251     /**
252      * This method logs OpenThread action result.
253      *
254      * @param[in] aAction  The action OpenThread performs.
255      * @param[in] aError   The action result.
256      *
257      */
258     static void LogOpenThreadResult(const char *aAction, otError aError);
259 
260 private:
261     static void ActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper);
262     void        ActiveScanHandler(otActiveScanResult *aResult);
263 
264     static void EnergyScanCallback(otEnergyScanResult *aResult, void *aThreadHelper);
265     void        EnergyScanCallback(otEnergyScanResult *aResult);
266 
267     static void JoinerCallback(otError aError, void *aThreadHelper);
268     void        JoinerCallback(otError aResult);
269 
270     static void MgmtSetResponseHandler(otError aResult, void *aContext);
271     void        MgmtSetResponseHandler(otError aResult);
272 
273     void    RandomFill(void *aBuf, size_t size);
274     uint8_t RandomChannelFromChannelMask(uint32_t aChannelMask);
275 
276     void ActiveDatasetChangedCallback();
277 
278     otInstance *mInstance;
279 
280     otbr::Ncp::ControllerOpenThread *mNcp;
281 
282     ScanHandler                     mScanHandler;
283     std::vector<otActiveScanResult> mScanResults;
284     EnergyScanHandler               mEnergyScanHandler;
285     std::vector<otEnergyScanResult> mEnergyScanResults;
286 
287     std::vector<DeviceRoleHandler>    mDeviceRoleHandlers;
288     std::vector<DatasetChangeHandler> mActiveDatasetChangeHandlers;
289 
290     std::map<uint16_t, size_t> mUnsecurePortRefCounter;
291 
292     int64_t       mAttachDelayMs = 0;
293     AttachHandler mAttachHandler;
294     ResultHandler mJoinerHandler;
295 
296     otOperationalDatasetTlvs mAttachPendingDatasetTlvs = {};
297 
298     std::random_device mRandomDevice;
299 
300 #if OTBR_ENABLE_DBUS_SERVER
301     UpdateMeshCopTxtHandler mUpdateMeshCopTxtHandler;
302 #endif
303 };
304 
305 } // namespace agent
306 } // namespace otbr
307 
308 #endif // OTBR_THREAD_HELPER_HPP_
309