Automatic Joiners removal in Commissioner (#1421)

* Implement automatic Joiner removal feature.

* Save some RAM in JoinerRouter class.

* Specify timeout for each Joiner separately.

* Update Windows API files.
This commit is contained in:
Robert Lubos
2017-03-08 05:19:12 -08:00
committed by Jonathan Hui
parent 6eaacdd4a4
commit 746a40a340
12 changed files with 121 additions and 23 deletions
@@ -602,6 +602,7 @@ typedef struct otCommissionConfig
// uint8_t - aExtAddressValid
// otExtAddress - aExtAddress (optional)
// char[OPENTHREAD_PSK_MAX_LENGTH + 1] - aPSKd
// uint32_t - aTimeout
#define IOCTL_OTLWF_OT_COMMISIONER_REMOVE_JOINER \
OTLWF_CTL_CODE(181, METHOD_BUFFERED, FILE_WRITE_DATA)
+5 -3
View File
@@ -3513,7 +3513,8 @@ OTCALL
otCommissionerAddJoiner(
_In_ otInstance *aInstance,
const otExtAddress *aExtAddress,
const char *aPSKd
const char *aPSKd,
uint32_t aTimeout
)
{
if (aInstance == nullptr || aPSKd == nullptr) return kThreadError_InvalidArgs;
@@ -3526,13 +3527,14 @@ otCommissionerAddJoiner(
uint8_t aExtAddressValid = aExtAddress ? 1 : 0;
const ULONG BufferLength = sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + (ULONG)aPSKdLength + 1;
BYTE Buffer[sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + OPENTHREAD_PSK_MAX_LENGTH + 1] = {0};
const ULONG BufferLength = sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + (ULONG)aPSKdLength + 1 + sizeof(aTimeout);
BYTE Buffer[sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + OPENTHREAD_PSK_MAX_LENGTH + 1 + sizeof(aTimeout)] = {0};
memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), &aExtAddressValid, sizeof(aExtAddressValid));
if (aExtAddressValid)
memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t), aExtAddress, sizeof(otExtAddress));
memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress), sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t) - sizeof(otExtAddress), aPSKd, aPSKdLength);
memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + aPSKdLength + 1, sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t) - sizeof(otExtAddress) - aPSKdLength - 1, &aTimeout, sizeof(aTimeout));
return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISIONER_ADD_JOINER, Buffer, BufferLength, nullptr, 0));
}
+3 -2
View File
@@ -5596,19 +5596,20 @@ otLwfIoCtl_otCommissionerAddJoiner(
if (InBufferLength >= sizeof(uint8_t) + sizeof(otExtAddress))
{
const ULONG aPSKdBufferLength = InBufferLength - sizeof(uint8_t) - sizeof(otExtAddress);
const ULONG aPSKdBufferLength = InBufferLength - sizeof(uint8_t) - sizeof(otExtAddress) - sizeof(uint32_t);
if (aPSKdBufferLength <= OPENTHREAD_PSK_MAX_LENGTH + 1)
{
uint8_t aExtAddressValid = *(uint8_t*)InBuffer;
const otExtAddress *aExtAddress = aExtAddressValid == 0 ? NULL : (otExtAddress*)(InBuffer + sizeof(uint8_t));
char *aPSKd = (char*)(InBuffer + sizeof(uint8_t) + sizeof(otExtAddress));
uint32_t aTimeout = *(uint32_t*)(InBuffer + sizeof(uint8_t) + sizeof(otExtAddress) + aPSKdBufferLength);
// Ensure aPSKd is NULL terminated in the buffer
if (strnlen(aPSKd, aPSKdBufferLength) < aPSKdBufferLength)
{
status = ThreadErrorToNtstatus(otCommissionerAddJoiner(
pFilter->otCtx, aExtAddress, aPSKd));
pFilter->otCtx, aExtAddress, aPSKd, aTimeout));
}
}
}
@@ -1010,11 +1010,13 @@ OTNODEAPI int32_t OTCALL otNodeCommissionerJoinerAdd(otNode* aNode, const char *
otLogFuncEntryMsg("[%d] %s %s", aNode->mId, aExtAddr, aPSKd);
printf("%d: commissioner joiner add %s %s\r\n", aNode->mId, aExtAddr, aPSKd);
const uint32_t kDefaultJoinerTimeout = 120;
ThreadError error;
if (strcmp(aExtAddr, "*") == 0)
{
error = otCommissionerAddJoiner(aNode->mInstance, nullptr, aPSKd);
error = otCommissionerAddJoiner(aNode->mInstance, nullptr, aPSKd, kDefaultJoinerTimeout);
}
else
{
@@ -1022,7 +1024,7 @@ OTNODEAPI int32_t OTCALL otNodeCommissionerJoinerAdd(otNode* aNode, const char *
if (Hex2Bin(aExtAddr, extAddr.m8, sizeof(extAddr)) != sizeof(extAddr))
return kThreadError_Parse;
error = otCommissionerAddJoiner(aNode->mInstance, &extAddr, aPSKd);
error = otCommissionerAddJoiner(aNode->mInstance, &extAddr, aPSKd, kDefaultJoinerTimeout);
}
otLogFuncExit();
+2 -1
View File
@@ -75,6 +75,7 @@ OTAPI ThreadError OTCALL otCommissionerStop(otInstance *aInstance);
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aExtAddress A pointer to the Joiner's extended address or NULL for any Joiner.
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aTimeout A time after which a Joiner is automatically removed, in seconds.
*
* @retval kThreadError_None Successfully added the Joiner.
* @retval kThreadError_NoBufs No buffers available to add the Joiner.
@@ -82,7 +83,7 @@ OTAPI ThreadError OTCALL otCommissionerStop(otInstance *aInstance);
*
*/
OTAPI ThreadError OTCALL otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aExtAddress,
const char *aPSKd);
const char *aPSKd, uint32_t aTimeout);
/**
* This function removes a Joiner entry.
+9 -1
View File
@@ -2327,7 +2327,15 @@ void Interpreter::ProcessCommissioner(int argc, char *argv[])
if (strcmp(argv[1], "add") == 0)
{
VerifyOrExit(argc > 3, error = kThreadError_Parse);
SuccessOrExit(error = otCommissionerAddJoiner(mInstance, addrPtr, argv[3]));
// Timeout parameter is optional - if not specified, use default value.
unsigned long timeout = kDefaultJoinerTimeout;
if (argc > 4)
{
SuccessOrExit(error = ParseUnsignedLong(argv[4], timeout));
}
SuccessOrExit(error = otCommissionerAddJoiner(mInstance, addrPtr, argv[3], static_cast<uint32_t>(timeout)));
}
else if (strcmp(argv[1], "remove") == 0)
{
+1
View File
@@ -147,6 +147,7 @@ private:
{
kMaxArgs = 32,
kMaxAutoAddresses = 8,
kDefaultJoinerTimeout = 120, ///< Default timeout for Joiners, in seconds.
};
void AppendResult(ThreadError error);
+4 -2
View File
@@ -53,9 +53,11 @@ ThreadError otCommissionerStop(otInstance *aInstance)
return aInstance->mThreadNetif.GetCommissioner().Stop();
}
ThreadError otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aExtAddress, const char *aPSKd)
ThreadError otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aExtAddress, const char *aPSKd,
uint32_t aTimeout)
{
return aInstance->mThreadNetif.GetCommissioner().AddJoiner(static_cast<const Mac::ExtAddress *>(aExtAddress), aPSKd);
return aInstance->mThreadNetif.GetCommissioner().AddJoiner(static_cast<const Mac::ExtAddress *>(aExtAddress), aPSKd,
aTimeout);
}
ThreadError otCommissionerRemoveJoiner(otInstance *aInstance, const otExtAddress *aExtAddress)
+72 -1
View File
@@ -68,6 +68,7 @@ Commissioner::Commissioner(ThreadNetif &aThreadNetif):
mState(kStateDisabled),
mJoinerPort(0),
mJoinerRloc(0),
mJoinerExpirationTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleJoinerExpirationTimer, this),
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this),
mSessionId(0),
mTransmitAttempts(0),
@@ -199,7 +200,7 @@ void Commissioner::ClearJoiners(void)
otLogFuncExit();
}
ThreadError Commissioner::AddJoiner(const Mac::ExtAddress *aExtAddress, const char *aPSKd)
ThreadError Commissioner::AddJoiner(const Mac::ExtAddress *aExtAddress, const char *aPSKd, uint32_t aTimeout)
{
ThreadError error = kThreadError_NoBufs;
@@ -226,6 +227,9 @@ ThreadError Commissioner::AddJoiner(const Mac::ExtAddress *aExtAddress, const ch
strncpy(mJoiners[i].mPsk, aPSKd, sizeof(mJoiners[i].mPsk) - 1);
mJoiners[i].mValid = true;
mJoiners[i].mExpirationTime = Timer::GetNow() + Timer::SecToMsec(aTimeout);
UpdateJoinerExpirationTimer();
SendCommissionerSet();
@@ -264,6 +268,8 @@ ThreadError Commissioner::RemoveJoiner(const Mac::ExtAddress *aExtAddress)
mJoiners[i].mValid = false;
UpdateJoinerExpirationTimer();
SendCommissionerSet();
ExitNow(error = kThreadError_None);
@@ -311,6 +317,66 @@ void Commissioner::HandleTimer(void)
}
}
void Commissioner::HandleJoinerExpirationTimer(void *aContext)
{
static_cast<Commissioner *>(aContext)->HandleJoinerExpirationTimer();
}
void Commissioner::HandleJoinerExpirationTimer(void)
{
uint32_t now = Timer::GetNow();
// Remove expired Joiners.
for (size_t i = 0; i < sizeof(mJoiners) / sizeof(mJoiners[0]); i++)
{
if (!mJoiners[i].mValid)
{
continue;
}
if (static_cast<int32_t>(now - mJoiners[i].mExpirationTime) >= 0)
{
otLogDebgMeshCoP("removing joiner due to timeout");
RemoveJoiner(&mJoiners[i].mExtAddress);
}
}
UpdateJoinerExpirationTimer();
}
void Commissioner::UpdateJoinerExpirationTimer(void)
{
uint32_t now = Timer::GetNow();
uint32_t nextTimeout = 0xffffffff;
// Check if timer should be set for next Joiner.
for (size_t i = 0; i < sizeof(mJoiners) / sizeof(mJoiners[0]); i++)
{
{
if (!mJoiners[i].mValid)
{
continue;
}
if (mJoiners[i].mExpirationTime - now < nextTimeout)
{
nextTimeout = mJoiners[i].mExpirationTime - now;
}
}
}
if (nextTimeout != 0xffffffff)
{
// Update the timer to the timeout of the next Joiner.
mJoinerExpirationTimer.Start(nextTimeout);
}
else
{
// No Joiners, stop the timer.
mJoinerExpirationTimer.Stop();
}
}
ThreadError Commissioner::SendMgmtCommissionerGetRequest(const uint8_t *aTlvs,
uint8_t aLength)
{
@@ -822,6 +888,7 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader,
Ip6::MessageInfo joinerMessageInfo;
MeshCoP::StateTlv stateTlv;
Message *message;
Mac::ExtAddress extAddr;
otLogFuncEntry();
@@ -842,6 +909,10 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader,
mSendKek = true;
SuccessOrExit(error = mNetif.GetSecureCoapServer().SendMessage(*message, joinerMessageInfo));
memcpy(extAddr.m8, mJoinerIid, sizeof(extAddr.m8));
extAddr.SetLocal(!extAddr.IsLocal());
RemoveJoiner(&extAddr);
otLogInfoMeshCoP("sent joiner finalize response");
otLogCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.rsp");
exit:
+14 -6
View File
@@ -92,13 +92,14 @@ public:
* This method adds a Joiner entry.
*
* @param[in] aExtAddress A pointer to the Joiner's extended address or NULL for any Joiner.
* @param[in] aPSKd A pointer to the PSKd
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aTimeout A time after which a Joiner is automatically removed, in seconds.
*
* @retval kThreadError_None Successfully added the Joiner.
* @retval kThreadError_NoBufs No buffers available to add the Joiner.
*
*/
ThreadError AddJoiner(const Mac::ExtAddress *aExtAddress, const char *aPSKd);
ThreadError AddJoiner(const Mac::ExtAddress *aExtAddress, const char *aPSKd, uint32_t aTimeout);
/**
* This method removes a Joiner entry.
@@ -199,15 +200,20 @@ public:
private:
enum
{
kPetitionAttemptDelay = 5, ///< COMM_PET_ATTEMPT_DELAY (seconds)
kPetitionRetryCount = 2, ///< COMM_PET_RETRY_COUNT
kPetitionRetryDelay = 1, ///< COMM_PET_RETRY_DELAY (seconds)
kKeepAliveTimeout = 50, ///< TIMEOUT_COMM_PET (seconds)
kPetitionAttemptDelay = 5, ///< COMM_PET_ATTEMPT_DELAY (seconds)
kPetitionRetryCount = 2, ///< COMM_PET_RETRY_COUNT
kPetitionRetryDelay = 1, ///< COMM_PET_RETRY_DELAY (seconds)
kKeepAliveTimeout = 50, ///< TIMEOUT_COMM_PET (seconds)
};
static void HandleTimer(void *aContext);
void HandleTimer(void);
static void HandleJoinerExpirationTimer(void *aContext);
void HandleJoinerExpirationTimer(void);
void UpdateJoinerExpirationTimer(void);
static void HandleMgmtCommissionerSetResponse(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
const otMessageInfo *aMessageInfo, ThreadError aResult);
void HandleMgmtCommissisonerSetResponse(Coap::Header *aHeader, Message *aMessage,
@@ -251,6 +257,7 @@ private:
struct Joiner
{
Mac::ExtAddress mExtAddress;
uint32_t mExpirationTime;
char mPsk[Dtls::kPskMaxLength + 1];
bool mValid : 1;
bool mAny : 1;
@@ -264,6 +271,7 @@ private:
};
uint16_t mJoinerPort;
uint16_t mJoinerRloc;
Timer mJoinerExpirationTimer;
Timer mTimer;
uint16_t mSessionId;
+1 -1
View File
@@ -60,9 +60,9 @@ JoinerRouter::JoinerRouter(ThreadNetif &aNetif):
mSocket(aNetif.GetIp6().mUdp),
mRelayTransmit(OPENTHREAD_URI_RELAY_TX, &JoinerRouter::HandleRelayTransmit, this),
mNetif(aNetif),
mTimer(aNetif.GetIp6().mTimerScheduler, &JoinerRouter::HandleTimer, this),
mJoinerUdpPort(0),
mIsJoinerPortConfigured(false),
mTimer(aNetif.GetIp6().mTimerScheduler, &JoinerRouter::HandleTimer, this),
mExpectJoinEntRsp(false)
{
mSocket.GetSockName().mPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
+5 -4
View File
@@ -118,12 +118,13 @@ private:
Coap::Resource mRelayTransmit;
ThreadNetif &mNetif;
uint16_t mJoinerUdpPort;
bool mIsJoinerPortConfigured;
Timer mTimer;
MessageQueue mDelayedJoinEnts;
bool mExpectJoinEntRsp;
uint16_t mJoinerUdpPort;
bool mIsJoinerPortConfigured : 1;
bool mExpectJoinEntRsp : 1;
};
/**