diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index 46215baa5..978ecd671 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -1522,14 +1522,15 @@ otThreadGetExtendedPanId( } OTAPI -void +ThreadError OTCALL otThreadSetExtendedPanId( _In_ otInstance *aInstance, const uint8_t *aExtendedPanId ) { - if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_PANID, (const otExtendedPanId*)aExtendedPanId); + if (aInstance == nullptr) return kThreadError_InvalidArgs; + return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_PANID, (const otExtendedPanId*)aExtendedPanId)); } OTAPI diff --git a/examples/drivers/windows/otLwf/iocontrol.c b/examples/drivers/windows/otLwf/iocontrol.c index 105007ead..82725c68c 100644 --- a/examples/drivers/windows/otLwf/iocontrol.c +++ b/examples/drivers/windows/otLwf/iocontrol.c @@ -1244,8 +1244,7 @@ otLwfIoCtl_otExtendedPanId( if (InBufferLength >= sizeof(otExtendedPanId)) { - otThreadSetExtendedPanId(pFilter->otCtx, (uint8_t*)InBuffer); - status = STATUS_SUCCESS; + status = ThreadErrorToNtstatus(otThreadSetExtendedPanId(pFilter->otCtx, (uint8_t*)InBuffer)); *OutBufferLength = 0; } else if (*OutBufferLength >= sizeof(otExtendedPanId)) diff --git a/include/openthread/link.h b/include/openthread/link.h index b49d8a1ae..7eff0e497 100644 --- a/include/openthread/link.h +++ b/include/openthread/link.h @@ -164,11 +164,16 @@ OTAPI uint8_t OTCALL otLinkGetChannel(otInstance *aInstance); /** * Set the IEEE 802.15.4 channel * + * This function will only succeed when Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aChannel The IEEE 802.15.4 channel. * - * @retval kThreadErrorNone Successfully set the channel. - * @retval kThreadErrorInvalidArgs If @p aChnanel is not in the range [11, 26]. + * @retval kThreadErrorNone Successfully set the channel. + * @retval kThreadErrorInvalidArgs If @p aChnanel is not in the range [11, 26]. + * @retrval kThreadError_InvalidState Thread protocols are enabled. * * @sa otLinkGetChannel */ @@ -186,11 +191,14 @@ OTAPI const uint8_t *OTCALL otLinkGetExtendedAddress(otInstance *aInstance); /** * This function sets the IEEE 802.15.4 Extended Address. * + * This function will only succeed when Thread protocols are disabled. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aExtendedAddress A pointer to the IEEE 802.15.4 Extended Address. * - * @retval kThreadError_None Successfully set the IEEE 802.15.4 Extended Address. - * @retval kThreadError_InvalidArgs @p aExtendedAddress was NULL. + * @retval kThreadError_None Successfully set the IEEE 802.15.4 Extended Address. + * @retval kThreadError_InvalidArgs @p aExtendedAddress was NULL. + * @retval kThraedError_InvalidState Thread protocols are enabled. * */ OTAPI ThreadError OTCALL otLinkSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtendedAddress); @@ -249,11 +257,16 @@ OTAPI otPanId OTCALL otLinkGetPanId(otInstance *aInstance); /** * Set the IEEE 802.15.4 PAN ID. * + * This function will only succeed when Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aPanId The IEEE 802.15.4 PAN ID. * - * @retval kThreadErrorNone Successfully set the PAN ID. - * @retval kThreadErrorInvalidArgs If aPanId is not in the range [0, 65534]. + * @retval kThreadError_None Successfully set the PAN ID. + * @retval kThreadError_InvalidArgs If aPanId is not in the range [0, 65534]. + * @retval kThreadError_InvalidState Thread protocols are enabled. * * @sa otLinkGetPanId */ diff --git a/include/openthread/thread.h b/include/openthread/thread.h index 961167ce0..0f0e61da8 100644 --- a/include/openthread/thread.h +++ b/include/openthread/thread.h @@ -205,12 +205,19 @@ OTAPI const uint8_t *OTCALL otThreadGetExtendedPanId(otInstance *aInstance); /** * Set the IEEE 802.15.4 Extended PAN ID. * + * This function may only be called while Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aExtendedPanId A pointer to the IEEE 802.15.4 Extended PAN ID. * + * @retval kThreadError_None Successfully set the Extended PAN ID. + * @retval kThreadError_InvalidState Thread protocols are enabled. + * * @sa otThreadGetExtendedPanId */ -OTAPI void OTCALL otThreadSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPanId); +OTAPI ThreadError OTCALL otThreadSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPanId); /** * This function returns a pointer to the Leader's RLOC. @@ -264,12 +271,17 @@ OTAPI const uint8_t *OTCALL otThreadGetMasterKey(otInstance *aInstance, uint8_t /** * Set the thrMasterKey. * + * This function will only succeed when Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aKey A pointer to a buffer containing the thrMasterKey. * @param[in] aKeyLength Number of bytes representing the thrMasterKey stored at aKey. Valid range is [0, 16]. * - * @retval kThreadErrorNone Successfully set the thrMasterKey. - * @retval kThreadErrorInvalidArgs If aKeyLength is larger than 16. + * @retval kThreadErrorNone Successfully set the thrMasterKey. + * @retval kThreadErrorInvalidArgs If aKeyLength is larger than 16. + * @retval kThreadError_InvalidState Thread protocols are enabled. * * @sa otThreadGetMasterKey */ @@ -298,10 +310,15 @@ OTAPI const uint8_t *OTCALL otThreadGetMeshLocalPrefix(otInstance *aInstance); /** * This function sets the Mesh Local Prefix. * + * This function will only succeed when Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aMeshLocalPrefix A pointer to the Mesh Local Prefix. * - * @retval kThreadError_None Successfully set the Mesh Local Prefix. + * @retval kThreadError_None Successfully set the Mesh Local Prefix. + * @retval kThreadError_InvalidState Thread protocols are enabled. * */ OTAPI ThreadError OTCALL otThreadSetMeshLocalPrefix(otInstance *aInstance, const uint8_t *aMeshLocalPrefix); @@ -320,10 +337,15 @@ OTAPI const char *OTCALL otThreadGetNetworkName(otInstance *aInstance); /** * Set the Thread Network Name. * + * This function will only succeed when Thread protocols are disabled. A successful + * call to this function will also invalidate the Active and Pending Operational Datasets in + * non-volatile memory. + * * @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aNetworkName A pointer to the Thread Network Name. * - * @retval kThreadErrorNone Successfully set the Thread Network Name. + * @retval kThreadErrorNone Successfully set the Thread Network Name. + * @retval kThreadError_InvalidState Thread protocols are enabled. * * @sa otThreadGetNetworkName */ diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp index b09aae335..d7f0101f3 100644 --- a/src/core/api/link_api.cpp +++ b/src/core/api/link_api.cpp @@ -51,7 +51,17 @@ uint8_t otLinkGetChannel(otInstance *aInstance) ThreadError otLinkSetChannel(otInstance *aInstance, uint8_t aChannel) { - return aInstance->mThreadNetif.GetMac().SetChannel(aChannel); + ThreadError error; + + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); + + error = aInstance->mThreadNetif.GetMac().SetChannel(aChannel); + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); + +exit: + return error; } const uint8_t *otLinkGetExtendedAddress(otInstance *aInstance) @@ -64,6 +74,8 @@ ThreadError otLinkSetExtendedAddress(otInstance *aInstance, const otExtAddress * ThreadError error = kThreadError_None; VerifyOrExit(aExtAddress != NULL, error = kThreadError_InvalidArgs); + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); aInstance->mThreadNetif.GetMac().SetExtAddress(*static_cast(aExtAddress)); @@ -103,12 +115,12 @@ ThreadError otLinkSetPanId(otInstance *aInstance, otPanId aPanId) { ThreadError error = kThreadError_None; - // do not allow setting PAN ID to broadcast if Thread is running - VerifyOrExit(aPanId != Mac::kPanIdBroadcast || - aInstance->mThreadNetif.GetMle().GetDeviceState() != Mle::kDeviceStateDisabled, + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, error = kThreadError_InvalidState); error = aInstance->mThreadNetif.GetMac().SetPanId(aPanId); + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); exit: return error; diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index 5eec0299e..8416631f1 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -75,10 +75,14 @@ const uint8_t *otThreadGetExtendedPanId(otInstance *aInstance) return aInstance->mThreadNetif.GetMac().GetExtendedPanId(); } -void otThreadSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPanId) +ThreadError otThreadSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPanId) { + ThreadError error = kThreadError_None; uint8_t mlPrefix[8]; + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); + aInstance->mThreadNetif.GetMac().SetExtendedPanId(aExtendedPanId); mlPrefix[0] = 0xfd; @@ -86,6 +90,12 @@ void otThreadSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPan mlPrefix[6] = 0x00; mlPrefix[7] = 0x00; aInstance->mThreadNetif.GetMle().SetMeshLocalPrefix(mlPrefix); + + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); + +exit: + return error; } ThreadError otThreadGetLeaderRloc(otInstance *aInstance, otIp6Address *aAddress) @@ -164,7 +174,17 @@ const uint8_t *otThreadGetMasterKey(otInstance *aInstance, uint8_t *aKeyLength) ThreadError otThreadSetMasterKey(otInstance *aInstance, const uint8_t *aKey, uint8_t aKeyLength) { - return aInstance->mThreadNetif.GetKeyManager().SetMasterKey(aKey, aKeyLength); + ThreadError error = kThreadError_None; + + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); + + error = aInstance->mThreadNetif.GetKeyManager().SetMasterKey(aKey, aKeyLength); + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); + +exit: + return error; } const otIp6Address *otThreadGetMeshLocalEid(otInstance *aInstance) @@ -179,7 +199,17 @@ const uint8_t *otThreadGetMeshLocalPrefix(otInstance *aInstance) ThreadError otThreadSetMeshLocalPrefix(otInstance *aInstance, const uint8_t *aMeshLocalPrefix) { - return aInstance->mThreadNetif.GetMle().SetMeshLocalPrefix(aMeshLocalPrefix); + ThreadError error = kThreadError_None; + + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); + + error = aInstance->mThreadNetif.GetMle().SetMeshLocalPrefix(aMeshLocalPrefix); + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); + +exit: + return error; } const char *otThreadGetNetworkName(otInstance *aInstance) @@ -189,7 +219,17 @@ const char *otThreadGetNetworkName(otInstance *aInstance) ThreadError otThreadSetNetworkName(otInstance *aInstance, const char *aNetworkName) { - return aInstance->mThreadNetif.GetMac().SetNetworkName(aNetworkName); + ThreadError error = kThreadError_None; + + VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled, + error = kThreadError_InvalidState); + + error = aInstance->mThreadNetif.GetMac().SetNetworkName(aNetworkName); + aInstance->mThreadNetif.GetActiveDataset().Clear(false); + aInstance->mThreadNetif.GetPendingDataset().Clear(false); + +exit: + return error; } bool otThreadIsRouterRoleEnabled(otInstance *aInstance)