1 /* 2 * Copyright (c) 2016, 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 * @brief 32 * This file includes functions for the Thread Commissioner role. 33 */ 34 35 #ifndef OPENTHREAD_COMMISSIONER_H_ 36 #define OPENTHREAD_COMMISSIONER_H_ 37 38 #include <openthread/dataset.h> 39 #include <openthread/ip6.h> 40 #include <openthread/joiner.h> 41 #include <openthread/platform/radio.h> 42 #include <openthread/platform/toolchain.h> 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /** 49 * @addtogroup api-commissioner 50 * 51 * @brief 52 * This module includes functions for the Thread Commissioner role. 53 * 54 * @{ 55 */ 56 57 /** 58 * Defines the Commissioner State. 59 */ 60 typedef enum otCommissionerState 61 { 62 OT_COMMISSIONER_STATE_DISABLED = 0, ///< Commissioner role is disabled. 63 OT_COMMISSIONER_STATE_PETITION = 1, ///< Currently petitioning to become a Commissioner. 64 OT_COMMISSIONER_STATE_ACTIVE = 2, ///< Commissioner role is active. 65 } otCommissionerState; 66 67 /** 68 * Defines a Joiner Event on the Commissioner. 69 */ 70 typedef enum otCommissionerJoinerEvent 71 { 72 OT_COMMISSIONER_JOINER_START = 0, 73 OT_COMMISSIONER_JOINER_CONNECTED = 1, 74 OT_COMMISSIONER_JOINER_FINALIZE = 2, 75 OT_COMMISSIONER_JOINER_END = 3, 76 OT_COMMISSIONER_JOINER_REMOVED = 4, 77 } otCommissionerJoinerEvent; 78 79 #define OT_COMMISSIONING_PASSPHRASE_MIN_SIZE 6 ///< Minimum size of the Commissioning Passphrase 80 #define OT_COMMISSIONING_PASSPHRASE_MAX_SIZE 255 ///< Maximum size of the Commissioning Passphrase 81 82 #define OT_PROVISIONING_URL_MAX_SIZE 64 ///< Max size (number of chars) in Provisioning URL string (excludes null char). 83 84 #define OT_STEERING_DATA_MAX_LENGTH 16 ///< Max steering data length (bytes) 85 86 /** 87 * Represents the steering data. 88 */ 89 typedef struct otSteeringData 90 { 91 uint8_t mLength; ///< Length of steering data (bytes) 92 uint8_t m8[OT_STEERING_DATA_MAX_LENGTH]; ///< Byte values 93 } otSteeringData; 94 95 /** 96 * Represents a Commissioning Dataset. 97 */ 98 typedef struct otCommissioningDataset 99 { 100 uint16_t mLocator; ///< Border Router RLOC16 101 uint16_t mSessionId; ///< Commissioner Session Id 102 otSteeringData mSteeringData; ///< Steering Data 103 uint16_t mJoinerUdpPort; ///< Joiner UDP Port 104 105 bool mIsLocatorSet : 1; ///< TRUE if Border Router RLOC16 is set, FALSE otherwise. 106 bool mIsSessionIdSet : 1; ///< TRUE if Commissioner Session Id is set, FALSE otherwise. 107 bool mIsSteeringDataSet : 1; ///< TRUE if Steering Data is set, FALSE otherwise. 108 bool mIsJoinerUdpPortSet : 1; ///< TRUE if Joiner UDP Port is set, FALSE otherwise. 109 bool mHasExtraTlv : 1; ///< TRUE if the Dataset contains any extra unknown sub-TLV, FALSE otherwise. 110 } otCommissioningDataset; 111 112 #define OT_JOINER_MAX_PSKD_LENGTH 32 ///< Maximum string length of a Joiner PSKd (does not include null char). 113 114 /** 115 * Represents a Joiner PSKd. 116 */ 117 typedef struct otJoinerPskd 118 { 119 char m8[OT_JOINER_MAX_PSKD_LENGTH + 1]; ///< Char string array (must be null terminated - +1 is for null char). 120 } otJoinerPskd; 121 122 /** 123 * Defines a Joiner Info Type. 124 */ 125 typedef enum otJoinerInfoType 126 { 127 OT_JOINER_INFO_TYPE_ANY = 0, ///< Accept any Joiner (no EUI64 or Discerner is specified). 128 OT_JOINER_INFO_TYPE_EUI64 = 1, ///< Joiner EUI-64 is specified (`mSharedId.mEui64` in `otJoinerInfo`). 129 OT_JOINER_INFO_TYPE_DISCERNER = 2, ///< Joiner Discerner is specified (`mSharedId.mDiscerner` in `otJoinerInfo`). 130 } otJoinerInfoType; 131 132 /** 133 * Represents a Joiner Info. 134 */ 135 typedef struct otJoinerInfo 136 { 137 otJoinerInfoType mType; ///< Joiner type. 138 union 139 { 140 otExtAddress mEui64; ///< Joiner EUI64 (when `mType` is `OT_JOINER_INFO_TYPE_EUI64`) 141 otJoinerDiscerner mDiscerner; ///< Joiner Discerner (when `mType` is `OT_JOINER_INFO_TYPE_DISCERNER`) 142 } mSharedId; ///< Shared fields 143 otJoinerPskd mPskd; ///< Joiner PSKd 144 uint32_t mExpirationTime; ///< Joiner expiration time in msec 145 } otJoinerInfo; 146 147 /** 148 * Pointer is called whenever the commissioner state changes. 149 * 150 * @param[in] aState The Commissioner state. 151 * @param[in] aContext A pointer to application-specific context. 152 */ 153 typedef void (*otCommissionerStateCallback)(otCommissionerState aState, void *aContext); 154 155 /** 156 * Pointer is called whenever the joiner state changes. 157 * 158 * @param[in] aEvent The joiner event type. 159 * @param[in] aJoinerInfo A pointer to the Joiner Info. 160 * @param[in] aJoinerId A pointer to the Joiner ID (if not known, it will be NULL). 161 * @param[in] aContext A pointer to application-specific context. 162 */ 163 typedef void (*otCommissionerJoinerCallback)(otCommissionerJoinerEvent aEvent, 164 const otJoinerInfo *aJoinerInfo, 165 const otExtAddress *aJoinerId, 166 void *aContext); 167 168 /** 169 * Enables the Thread Commissioner role. 170 * 171 * @param[in] aInstance A pointer to an OpenThread instance. 172 * @param[in] aStateCallback A pointer to a function that is called when the commissioner state changes. 173 * @param[in] aJoinerCallback A pointer to a function that is called with a joiner event occurs. 174 * @param[in] aCallbackContext A pointer to application-specific context. 175 * 176 * @retval OT_ERROR_NONE Successfully started the Commissioner service. 177 * @retval OT_ERROR_ALREADY Commissioner is already started. 178 * @retval OT_ERROR_INVALID_STATE Device is not currently attached to a network. 179 */ 180 otError otCommissionerStart(otInstance *aInstance, 181 otCommissionerStateCallback aStateCallback, 182 otCommissionerJoinerCallback aJoinerCallback, 183 void *aCallbackContext); 184 185 /** 186 * Disables the Thread Commissioner role. 187 * 188 * @param[in] aInstance A pointer to an OpenThread instance. 189 * 190 * @retval OT_ERROR_NONE Successfully stopped the Commissioner service. 191 * @retval OT_ERROR_ALREADY Commissioner is already stopped. 192 */ 193 otError otCommissionerStop(otInstance *aInstance); 194 195 /** 196 * Returns the Commissioner Id. 197 * 198 * @param[in] aInstance A pointer to an OpenThread instance. 199 * 200 * @returns The Commissioner Id. 201 */ 202 const char *otCommissionerGetId(otInstance *aInstance); 203 204 /** 205 * Sets the Commissioner Id. 206 * 207 * @param[in] aInstance A pointer to an OpenThread instance. 208 * @param[in] aId A pointer to a string character array. Must be null terminated. 209 * 210 * @retval OT_ERROR_NONE Successfully set the Commissioner Id. 211 * @retval OT_ERROR_INVALID_ARGS Given name is too long. 212 * @retval OT_ERROR_INVALID_STATE The commissioner is active and id cannot be changed. 213 */ 214 otError otCommissionerSetId(otInstance *aInstance, const char *aId); 215 216 /** 217 * Adds a Joiner entry. 218 * 219 * @param[in] aInstance A pointer to an OpenThread instance. 220 * @param[in] aEui64 A pointer to the Joiner's IEEE EUI-64 or NULL for any Joiner. 221 * @param[in] aPskd A pointer to the PSKd. 222 * @param[in] aTimeout A time after which a Joiner is automatically removed, in seconds. 223 * 224 * @retval OT_ERROR_NONE Successfully added the Joiner. 225 * @retval OT_ERROR_NO_BUFS No buffers available to add the Joiner. 226 * @retval OT_ERROR_INVALID_ARGS @p aEui64 or @p aPskd is invalid. 227 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 228 * 229 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 230 */ 231 otError otCommissionerAddJoiner(otInstance *aInstance, 232 const otExtAddress *aEui64, 233 const char *aPskd, 234 uint32_t aTimeout); 235 236 /** 237 * Adds a Joiner entry with a given Joiner Discerner value. 238 * 239 * @param[in] aInstance A pointer to an OpenThread instance. 240 * @param[in] aDiscerner A pointer to the Joiner Discerner. 241 * @param[in] aPskd A pointer to the PSKd. 242 * @param[in] aTimeout A time after which a Joiner is automatically removed, in seconds. 243 * 244 * @retval OT_ERROR_NONE Successfully added the Joiner. 245 * @retval OT_ERROR_NO_BUFS No buffers available to add the Joiner. 246 * @retval OT_ERROR_INVALID_ARGS @p aDiscerner or @p aPskd is invalid. 247 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 248 * 249 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 250 */ 251 otError otCommissionerAddJoinerWithDiscerner(otInstance *aInstance, 252 const otJoinerDiscerner *aDiscerner, 253 const char *aPskd, 254 uint32_t aTimeout); 255 256 /** 257 * Get joiner info at aIterator position. 258 * 259 * @param[in] aInstance A pointer to instance. 260 * @param[in,out] aIterator A pointer to the Joiner Info iterator context. 261 * @param[out] aJoiner A reference to Joiner info. 262 * 263 * @retval OT_ERROR_NONE Successfully get the Joiner info. 264 * @retval OT_ERROR_NOT_FOUND Not found next Joiner. 265 */ 266 otError otCommissionerGetNextJoinerInfo(otInstance *aInstance, uint16_t *aIterator, otJoinerInfo *aJoiner); 267 268 /** 269 * Removes a Joiner entry. 270 * 271 * @param[in] aInstance A pointer to an OpenThread instance. 272 * @param[in] aEui64 A pointer to the Joiner's IEEE EUI-64 or NULL for any Joiner. 273 * 274 * @retval OT_ERROR_NONE Successfully removed the Joiner. 275 * @retval OT_ERROR_NOT_FOUND The Joiner specified by @p aEui64 was not found. 276 * @retval OT_ERROR_INVALID_ARGS @p aEui64 is invalid. 277 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 278 * 279 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 280 */ 281 otError otCommissionerRemoveJoiner(otInstance *aInstance, const otExtAddress *aEui64); 282 283 /** 284 * Removes a Joiner entry. 285 * 286 * @param[in] aInstance A pointer to an OpenThread instance. 287 * @param[in] aDiscerner A pointer to the Joiner Discerner. 288 * 289 * @retval OT_ERROR_NONE Successfully removed the Joiner. 290 * @retval OT_ERROR_NOT_FOUND The Joiner specified by @p aEui64 was not found. 291 * @retval OT_ERROR_INVALID_ARGS @p aDiscerner is invalid. 292 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 293 * 294 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 295 */ 296 otError otCommissionerRemoveJoinerWithDiscerner(otInstance *aInstance, const otJoinerDiscerner *aDiscerner); 297 298 /** 299 * Gets the Provisioning URL. 300 * 301 * @param[in] aInstance A pointer to an OpenThread instance. 302 * 303 * @returns A pointer to the URL string. 304 */ 305 const char *otCommissionerGetProvisioningUrl(otInstance *aInstance); 306 307 /** 308 * Sets the Provisioning URL. 309 * 310 * @param[in] aInstance A pointer to an OpenThread instance. 311 * @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL to set as empty string). 312 * 313 * @retval OT_ERROR_NONE Successfully set the Provisioning URL. 314 * @retval OT_ERROR_INVALID_ARGS @p aProvisioningUrl is invalid (too long). 315 */ 316 otError otCommissionerSetProvisioningUrl(otInstance *aInstance, const char *aProvisioningUrl); 317 318 /** 319 * Sends an Announce Begin message. 320 * 321 * @param[in] aInstance A pointer to an OpenThread instance. 322 * @param[in] aChannelMask The channel mask value. 323 * @param[in] aCount The number of Announcement messages per channel. 324 * @param[in] aPeriod The time between two successive MLE Announce transmissions (in milliseconds). 325 * @param[in] aAddress A pointer to the IPv6 destination. 326 * 327 * @retval OT_ERROR_NONE Successfully enqueued the Announce Begin message. 328 * @retval OT_ERROR_NO_BUFS Insufficient buffers to generate an Announce Begin message. 329 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 330 * 331 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 332 */ 333 otError otCommissionerAnnounceBegin(otInstance *aInstance, 334 uint32_t aChannelMask, 335 uint8_t aCount, 336 uint16_t aPeriod, 337 const otIp6Address *aAddress); 338 339 /** 340 * Pointer is called when the Commissioner receives an Energy Report. 341 * 342 * @param[in] aChannelMask The channel mask value. 343 * @param[in] aEnergyList A pointer to the energy measurement list. 344 * @param[in] aEnergyListLength Number of entries in @p aEnergyListLength. 345 * @param[in] aContext A pointer to application-specific context. 346 */ 347 typedef void (*otCommissionerEnergyReportCallback)(uint32_t aChannelMask, 348 const uint8_t *aEnergyList, 349 uint8_t aEnergyListLength, 350 void *aContext); 351 352 /** 353 * Sends an Energy Scan Query message. 354 * 355 * @param[in] aInstance A pointer to an OpenThread instance. 356 * @param[in] aChannelMask The channel mask value. 357 * @param[in] aCount The number of energy measurements per channel. 358 * @param[in] aPeriod The time between energy measurements (milliseconds). 359 * @param[in] aScanDuration The scan duration for each energy measurement (milliseconds). 360 * @param[in] aAddress A pointer to the IPv6 destination. 361 * @param[in] aCallback A pointer to a function called on receiving an Energy Report message. 362 * @param[in] aContext A pointer to application-specific context. 363 * 364 * @retval OT_ERROR_NONE Successfully enqueued the Energy Scan Query message. 365 * @retval OT_ERROR_NO_BUFS Insufficient buffers to generate an Energy Scan Query message. 366 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 367 * 368 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 369 */ 370 otError otCommissionerEnergyScan(otInstance *aInstance, 371 uint32_t aChannelMask, 372 uint8_t aCount, 373 uint16_t aPeriod, 374 uint16_t aScanDuration, 375 const otIp6Address *aAddress, 376 otCommissionerEnergyReportCallback aCallback, 377 void *aContext); 378 379 /** 380 * Pointer is called when the Commissioner receives a PAN ID Conflict message. 381 * 382 * @param[in] aPanId The PAN ID value. 383 * @param[in] aChannelMask The channel mask value. 384 * @param[in] aContext A pointer to application-specific context. 385 */ 386 typedef void (*otCommissionerPanIdConflictCallback)(uint16_t aPanId, uint32_t aChannelMask, void *aContext); 387 388 /** 389 * Sends a PAN ID Query message. 390 * 391 * @param[in] aInstance A pointer to an OpenThread instance. 392 * @param[in] aPanId The PAN ID to query. 393 * @param[in] aChannelMask The channel mask value. 394 * @param[in] aAddress A pointer to the IPv6 destination. 395 * @param[in] aCallback A pointer to a function called on receiving a PAN ID Conflict message. 396 * @param[in] aContext A pointer to application-specific context. 397 * 398 * @retval OT_ERROR_NONE Successfully enqueued the PAN ID Query message. 399 * @retval OT_ERROR_NO_BUFS Insufficient buffers to generate a PAN ID Query message. 400 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 401 * 402 * @note Only use this after successfully starting the Commissioner role with otCommissionerStart(). 403 */ 404 otError otCommissionerPanIdQuery(otInstance *aInstance, 405 uint16_t aPanId, 406 uint32_t aChannelMask, 407 const otIp6Address *aAddress, 408 otCommissionerPanIdConflictCallback aCallback, 409 void *aContext); 410 411 /** 412 * Sends MGMT_COMMISSIONER_GET. 413 * 414 * @param[in] aInstance A pointer to an OpenThread instance. 415 * @param[in] aTlvs A pointer to TLVs. 416 * @param[in] aLength The length of TLVs. 417 * 418 * @retval OT_ERROR_NONE Successfully send the meshcop dataset command. 419 * @retval OT_ERROR_NO_BUFS Insufficient buffer space to send. 420 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 421 */ 422 otError otCommissionerSendMgmtGet(otInstance *aInstance, const uint8_t *aTlvs, uint8_t aLength); 423 424 /** 425 * Sends MGMT_COMMISSIONER_SET. 426 * 427 * @param[in] aInstance A pointer to an OpenThread instance. 428 * @param[in] aDataset A pointer to commissioning dataset. 429 * @param[in] aTlvs A pointer to TLVs. 430 * @param[in] aLength The length of TLVs. 431 * 432 * @retval OT_ERROR_NONE Successfully send the meshcop dataset command. 433 * @retval OT_ERROR_NO_BUFS Insufficient buffer space to send. 434 * @retval OT_ERROR_INVALID_STATE The commissioner is not active. 435 */ 436 otError otCommissionerSendMgmtSet(otInstance *aInstance, 437 const otCommissioningDataset *aDataset, 438 const uint8_t *aTlvs, 439 uint8_t aLength); 440 441 /** 442 * Returns the Commissioner Session ID. 443 * 444 * @param[in] aInstance A pointer to an OpenThread instance. 445 * 446 * @returns The current commissioner session id. 447 */ 448 uint16_t otCommissionerGetSessionId(otInstance *aInstance); 449 450 /** 451 * Returns the Commissioner State. 452 * 453 * @param[in] aInstance A pointer to an OpenThread instance. 454 * 455 * @retval OT_COMMISSIONER_STATE_DISABLED Commissioner disabled. 456 * @retval OT_COMMISSIONER_STATE_PETITION Becoming the commissioner. 457 * @retval OT_COMMISSIONER_STATE_ACTIVE Commissioner enabled. 458 */ 459 otCommissionerState otCommissionerGetState(otInstance *aInstance); 460 461 /** 462 * @} 463 */ 464 465 #ifdef __cplusplus 466 } // end of extern "C" 467 #endif 468 469 #endif // OPENTHREAD_COMMISSIONER_H_ 470