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