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