diff --git a/src/core/config/commissioner.h b/src/core/config/commissioner.h index a875d8d23..ff43adb36 100644 --- a/src/core/config/commissioner.h +++ b/src/core/config/commissioner.h @@ -55,4 +55,15 @@ #define OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES 2 #endif +/** + * @def OPENTHREAD_CONFIG_COMMISSIONER_JOINER_SESSION_TIMEOUT + * + * The timeout for the Joiner's session, in seconds. After this timeout, + * the Commissioner tears down the session. + * + */ +#ifndef OPENTHREAD_CONFIG_COMMISSIONER_JOINER_SESSION_TIMEOUT +#define OPENTHREAD_CONFIG_COMMISSIONER_JOINER_SESSION_TIMEOUT 30 +#endif + #endif // CONFIG_COMMISSIONER_H_ diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index 9c3ecb8ec..be9815314 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -66,6 +66,7 @@ Commissioner::Commissioner(Instance &aInstance) , mTransmitAttempts(0) , mJoinerExpirationTimer(aInstance) , mTimer(aInstance) + , mJoinerSessionTimer(aInstance) , mAnnounceBegin(aInstance) , mEnergyScan(aInstance) , mPanIdQuery(aInstance) @@ -137,6 +138,11 @@ void Commissioner::HandleSecureAgentConnected(bool aConnected, void *aContext) void Commissioner::HandleSecureAgentConnected(bool aConnected) { + if (!aConnected) + { + mJoinerSessionTimer.Stop(); + } + SignalJoinerEvent(aConnected ? kJoinerEventConnected : kJoinerEventEnd, mActiveJoiner); } @@ -315,6 +321,7 @@ Error Commissioner::Stop(ResignMode aResignMode) VerifyOrExit(mState != kStateDisabled, error = kErrorAlready); + mJoinerSessionTimer.Stop(); Get().Stop(); if (mState == kStateActive) @@ -976,12 +983,20 @@ template <> void Commissioner::HandleTmf(Coap::Message &aMessage, c Get().SetPsk(joiner->mPskd); mActiveJoiner = joiner; + mJoinerSessionTimer.Start(kJoinerSessionTimeoutMillis); + LogJoinerEntry("Starting new session with", *joiner); SignalJoinerEvent(kJoinerEventStart, joiner); } else { - VerifyOrExit(mJoinerIid == joinerIid); + if (mJoinerIid != joinerIid) + { + LogNote("Ignore Relay Receive (%s, 0x%04x), session in progress with (%s, 0x%04x)", + joinerIid.ToString().AsCString(), joinerRloc, mJoinerIid.ToString().AsCString(), mJoinerRloc); + + ExitNow(); + } } mJoinerPort = joinerPort; @@ -1002,6 +1017,16 @@ exit: return; } +void Commissioner::HandleJoinerSessionTimer(void) +{ + if (mActiveJoiner != nullptr) + { + LogJoinerEntry("Timed out session with", *mActiveJoiner); + } + + Get().Disconnect(); +} + template <> void Commissioner::HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp index c3c4809b2..22e061fb5 100644 --- a/src/core/meshcop/commissioner.hpp +++ b/src/core/meshcop/commissioner.hpp @@ -499,6 +499,9 @@ private: static constexpr uint32_t kKeepAliveTimeout = 50; // TIMEOUT_COMM_PET (seconds) static constexpr uint32_t kRemoveJoinerDelay = 20; // Delay to remove successfully joined joiner + static constexpr uint32_t kJoinerSessionTimeoutMillis = + 1000 * OPENTHREAD_CONFIG_COMMISSIONER_JOINER_SESSION_TIMEOUT; // Expiration time for active Joiner session + enum ResignMode : uint8_t { kSendKeepAliveToResign, @@ -580,6 +583,8 @@ private: void HandleRelayReceive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + void HandleJoinerSessionTimer(void); + void SendJoinFinalizeResponse(const Coap::Message &aRequest, StateTlv::State aState); static Error SendRelayTransmit(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo); @@ -599,6 +604,7 @@ private: using JoinerExpirationTimer = TimerMilliIn; using CommissionerTimer = TimerMilliIn; + using JoinerSessionTimer = TimerMilliIn; Joiner mJoiners[OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES]; @@ -610,6 +616,7 @@ private: uint8_t mTransmitAttempts; JoinerExpirationTimer mJoinerExpirationTimer; CommissionerTimer mTimer; + JoinerSessionTimer mJoinerSessionTimer; AnnounceBeginClient mAnnounceBegin; EnergyScanClient mEnergyScan;