From d16d160e2c7d2558736968a33dd37919d968ca45 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 13 Jan 2025 15:56:56 -0800 Subject: [PATCH] [border-agent] update `CoapDtlsSession` to handle session functionality (#11131) This commit updates the `CoapDtlsSession` class in `BorderAgent` to move all session-related functionality into this class. It now handles its own state and uses its own `Timer`, ALOC, UDP receiver, etc. Many methods previously defined in `BorderAgent` are now defined in `CoapDtlsSession`, ensuring each session can be processed individually. The `ForwardContext`, which tracks forwarded TMF commands, is also moved into `CoapDtlsSession` and updated to track its associated session. This change prepares `BorderAgent` to support multiple concurrent sessions in future PRs. --- src/core/meshcop/border_agent.cpp | 322 ++++++++++++++++-------------- src/core/meshcop/border_agent.hpp | 101 +++++----- 2 files changed, 228 insertions(+), 195 deletions(-) diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index 2792bb27b..9b2babcd2 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -48,8 +48,6 @@ RegisterLogModule("BorderAgent"); BorderAgent::BorderAgent(Instance &aInstance) : InstanceLocator(aInstance) , mState(kStateStopped) - , mUdpReceiver(BorderAgent::HandleUdpReceive, this) - , mTimer(aInstance) , mDtlsTransport(aInstance, kNoLinkSecurity) , mCoapDtlsSession(nullptr) #if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE @@ -63,7 +61,6 @@ BorderAgent::BorderAgent(Instance &aInstance) , mEphemeralKeyTask(aInstance) #endif { - mCommissionerAloc.InitAsThreadOriginMeshLocal(); ClearAllBytes(mCounters); } @@ -160,7 +157,6 @@ void BorderAgent::Stop(void) } #endif - mTimer.Stop(); mDtlsTransport.Close(); mState = kStateStopped; @@ -222,18 +218,6 @@ exit: return; } -void BorderAgent::HandleTimeout(void) -{ - VerifyOrExit(mCoapDtlsSession != nullptr); - VerifyOrExit(mCoapDtlsSession->IsConnected()); - - mCoapDtlsSession->Disconnect(); - LogWarn("Reset secure session"); - -exit: - return; -} - SecureSession *BorderAgent::HandleAcceptSession(void *aContext, const Ip6::MessageInfo &aMessageInfo) { OT_UNUSED_VARIABLE(aMessageInfo); @@ -250,7 +234,6 @@ BorderAgent::CoapDtlsSession *BorderAgent::HandleAcceptSession(void) session = CoapDtlsSession::Allocate(GetInstance(), mDtlsTransport); VerifyOrExit(session != nullptr); - session->SetConnectCallback(HandleConnected, this); mCoapDtlsSession = session; exit: @@ -271,30 +254,18 @@ void BorderAgent::HandleRemoveSession(SecureSession &aSesssion) mCoapDtlsSession = nullptr; } -void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent, void *aContext) +void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent, void *aContext) { - static_cast(aContext)->HandleConnected(aEvent); + static_cast(aContext)->HandleConnected(aEvent); } -void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent) +void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent) { - if (aEvent == Dtls::Session::kConnected) + if (aEvent == kConnected) { LogInfo("SecureSession connected"); - mState = kStateConnected; mTimer.Start(kKeepAliveTimeout); -#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - if (mUsingEphemeralKey) - { - mDidConnectWithEphemeralKey = true; - mCounters.mEpskcSecureSessionSuccesses++; - mEphemeralKeyTask.Post(); - } - else -#endif - { - mCounters.mPskcSecureSessionSuccesses++; - } + Get().HandleSessionConnected(*this); } else { @@ -302,40 +273,67 @@ void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent) IgnoreError(Get().RemoveReceiver(mUdpReceiver)); Get().RemoveUnicastAddress(mCommissionerAloc); + Get().HandleSessionDisconnected(*this, aEvent); + } +} + +void BorderAgent::HandleSessionConnected(CoapDtlsSession &aSesssion) +{ + OT_UNUSED_VARIABLE(aSesssion); + + mState = kStateConnected; + #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - if (mUsingEphemeralKey) - { - if (mDidConnectWithEphemeralKey) - { - RestartAfterRemovingEphemeralKey(); - } - - if (aEvent == Dtls::Session::kDisconnectedError) - { - mCounters.mEpskcSecureSessionFailures++; - } - else if (aEvent == Dtls::Session::kDisconnectedPeerClosed) - { - mCounters.mEpskcDeactivationDisconnects++; - } - } - else + if (mUsingEphemeralKey) + { + mDidConnectWithEphemeralKey = true; + mCounters.mEpskcSecureSessionSuccesses++; + mEphemeralKeyTask.Post(); + } + else #endif - { - mState = kStateStarted; + { + mCounters.mPskcSecureSessionSuccesses++; + } +} - if (aEvent == Dtls::Session::kDisconnectedError) - { - mCounters.mPskcSecureSessionFailures++; - } +void BorderAgent::HandleSessionDisconnected(CoapDtlsSession &aSesssion, CoapDtlsSession::ConnectEvent aEvent) +{ + OT_UNUSED_VARIABLE(aSesssion); + +#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + if (mUsingEphemeralKey) + { + if (mDidConnectWithEphemeralKey) + { + RestartAfterRemovingEphemeralKey(); + } + + if (aEvent == CoapDtlsSession::kDisconnectedError) + { + mCounters.mEpskcSecureSessionFailures++; + } + else if (aEvent == CoapDtlsSession::kDisconnectedPeerClosed) + { + mCounters.mEpskcDeactivationDisconnects++; + } + } + else +#endif + { + mState = kStateStarted; + + if (aEvent == CoapDtlsSession::kDisconnectedError) + { + mCounters.mPskcSecureSessionFailures++; } } } -void BorderAgent::HandleTmfCommissionerKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +void BorderAgent::CoapDtlsSession::HandleTmfCommissionerKeepAlive(Coap::Message &aMessage, + const Ip6::MessageInfo &aMessageInfo) { - VerifyOrExit(mState == kStateAccepted); - + VerifyOrExit(mIsActiveCommissioner); SuccessOrExit(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderKeepAlive)); mTimer.Start(kKeepAliveTimeout); @@ -343,7 +341,9 @@ exit: return; } -Error BorderAgent::ForwardToLeader(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri) +Error BorderAgent::CoapDtlsSession::ForwardToLeader(const Coap::Message &aMessage, + const Ip6::MessageInfo &aMessageInfo, + Uri aUri) { Error error = kErrorNone; OwnedPtr forwardContext; @@ -353,8 +353,7 @@ Error BorderAgent::ForwardToLeader(const Coap::Message &aMessage, const Ip6::Mes bool separate = false; OffsetRange offsetRange; - VerifyOrExit(mState != kStateStopped); - VerifyOrExit(mCoapDtlsSession != nullptr); + VerifyOrExit(Get().mState != kStateStopped); switch (aUri) { @@ -371,10 +370,10 @@ Error BorderAgent::ForwardToLeader(const Coap::Message &aMessage, const Ip6::Mes if (separate) { - SuccessOrExit(error = mCoapDtlsSession->SendAck(aMessage, aMessageInfo)); + SuccessOrExit(error = SendAck(aMessage, aMessageInfo)); } - forwardContext.Reset(ForwardContext::AllocateAndInit(GetInstance(), aMessage, petition, separate)); + forwardContext.Reset(ForwardContext::Allocate(*this, aMessage, petition, separate)); VerifyOrExit(!forwardContext.IsNull(), error = kErrorNoBufs); message = Get().NewPriorityConfirmablePostMessage(aUri); @@ -409,30 +408,29 @@ exit: return error; } -void BorderAgent::HandleCoapResponse(void *aContext, - otMessage *aMessage, - const otMessageInfo *aMessageInfo, - otError aResult) +void BorderAgent::CoapDtlsSession::HandleCoapResponse(void *aContext, + otMessage *aMessage, + const otMessageInfo *aMessageInfo, + otError aResult) { OT_UNUSED_VARIABLE(aMessageInfo); OwnedPtr forwardContext(static_cast(aContext)); - forwardContext->Get().HandleCoapResponse(*forwardContext.Get(), AsCoapMessagePtr(aMessage), aResult); + forwardContext->mSession.HandleCoapResponse(*forwardContext.Get(), AsCoapMessagePtr(aMessage), aResult); } -void BorderAgent::HandleCoapResponse(const ForwardContext &aForwardContext, - const Coap::Message *aResponse, - Error aResult) +void BorderAgent::CoapDtlsSession::HandleCoapResponse(const ForwardContext &aForwardContext, + const Coap::Message *aResponse, + Error aResult) { Coap::Message *message = nullptr; Error error; SuccessOrExit(error = aResult); - VerifyOrExit(mCoapDtlsSession != nullptr); - VerifyOrExit((message = mCoapDtlsSession->NewPriorityMessage()) != nullptr, error = kErrorNoBufs); + VerifyOrExit((message = NewPriorityMessage()) != nullptr, error = kErrorNoBufs); - if (aForwardContext.IsPetition() && aResponse->GetCode() == Coap::kCodeChanged) + if (aForwardContext.mPetition && aResponse->GetCode() == Coap::kCodeChanged) { uint8_t state; @@ -447,18 +445,8 @@ void BorderAgent::HandleCoapResponse(const ForwardContext &aForwardContext, Get().GetCommissionerAloc(sessionId, mCommissionerAloc.GetAddress()); Get().AddUnicastAddress(mCommissionerAloc); IgnoreError(Get().AddReceiver(mUdpReceiver)); - mState = kStateAccepted; - -#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - if (mUsingEphemeralKey) - { - mCounters.mEpskcCommissionerPetitions++; - } - else -#endif - { - mCounters.mPskcCommissionerPetitions++; - } + mIsActiveCommissioner = true; + Get().HandleCommissionerPetitionAccepted(*this); LogInfo("Commissioner accepted - SessionId:%u ALOC:%s", sessionId, mCommissionerAloc.GetAddress().ToString().AsCString()); @@ -484,18 +472,38 @@ exit: { FreeMessage(message); - LogWarn("Commissioner request[%u] failed: %s", aForwardContext.GetMessageId(), ErrorToString(error)); + LogWarn("Commissioner request[%u] failed: %s", aForwardContext.mMessageId, ErrorToString(error)); SendErrorMessage(aForwardContext, error); } } -bool BorderAgent::HandleUdpReceive(void *aContext, const otMessage *aMessage, const otMessageInfo *aMessageInfo) +void BorderAgent::HandleCommissionerPetitionAccepted(CoapDtlsSession &aSesssion) { - return static_cast(aContext)->HandleUdpReceive(AsCoreType(aMessage), AsCoreType(aMessageInfo)); + OT_UNUSED_VARIABLE(aSesssion); + + mState = kStateAccepted; + +#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + if (mUsingEphemeralKey) + { + mCounters.mEpskcCommissionerPetitions++; + } + else +#endif + { + mCounters.mPskcCommissionerPetitions++; + } } -bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +bool BorderAgent::CoapDtlsSession::HandleUdpReceive(void *aContext, + const otMessage *aMessage, + const otMessageInfo *aMessageInfo) +{ + return static_cast(aContext)->HandleUdpReceive(AsCoreType(aMessage), AsCoreType(aMessageInfo)); +} + +bool BorderAgent::CoapDtlsSession::HandleUdpReceive(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { Error error = kErrorNone; Coap::Message *message = nullptr; @@ -505,13 +513,12 @@ bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageIn OffsetRange offsetRange; VerifyOrExit(aMessageInfo.GetSockAddr() == mCommissionerAloc.GetAddress()); - VerifyOrExit(mCoapDtlsSession != nullptr); didHandle = true; VerifyOrExit(aMessage.GetLength() > 0); - message = mCoapDtlsSession->NewPriorityNonConfirmablePostMessage(kUriProxyRx); + message = NewPriorityNonConfirmablePostMessage(kUriProxyRx); VerifyOrExit(message != nullptr, error = kErrorNoBufs); offsetRange.InitFromMessageOffsetToEnd(aMessage); @@ -528,7 +535,7 @@ bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageIn SuccessOrExit(error = Tlv::Append(*message, aMessageInfo.GetPeerAddr())); - SuccessOrExit(error = mCoapDtlsSession->SendMessage(*message)); + SuccessOrExit(error = SendMessage(*message)); LogInfo("Sent ProxyRx (c/ur) to commissioner"); @@ -539,17 +546,15 @@ exit: return didHandle; } -Error BorderAgent::ForwardToCommissioner(Coap::Message &aForwardMessage, const Message &aMessage) +Error BorderAgent::CoapDtlsSession::ForwardToCommissioner(Coap::Message &aForwardMessage, const Message &aMessage) { Error error = kErrorNone; OffsetRange offsetRange; - VerifyOrExit(mCoapDtlsSession != nullptr); - offsetRange.InitFromMessageOffsetToEnd(aMessage); SuccessOrExit(error = aForwardMessage.AppendBytesFromMessage(aMessage, offsetRange)); - SuccessOrExit(error = mCoapDtlsSession->SendMessage(aForwardMessage)); + SuccessOrExit(error = SendMessage(aForwardMessage)); LogInfo("Sent to commissioner"); @@ -558,30 +563,26 @@ exit: return error; } -void BorderAgent::SendErrorMessage(const ForwardContext &aForwardContext, Error aError) +void BorderAgent::CoapDtlsSession::SendErrorMessage(const ForwardContext &aForwardContext, Error aError) { Error error = kErrorNone; Coap::Message *message = nullptr; - VerifyOrExit(mCoapDtlsSession != nullptr); - - VerifyOrExit((message = mCoapDtlsSession->NewPriorityMessage()) != nullptr, error = kErrorNoBufs); + VerifyOrExit((message = NewPriorityMessage()) != nullptr, error = kErrorNoBufs); SuccessOrExit(error = aForwardContext.ToHeader(*message, CoapCodeFromError(aError))); - SuccessOrExit(error = mCoapDtlsSession->SendMessage(*message)); + SuccessOrExit(error = SendMessage(*message)); exit: FreeMessageOnError(message, error); LogWarnOnError(error, "send error CoAP message"); } -void BorderAgent::SendErrorMessage(const Coap::Message &aRequest, bool aSeparate, Error aError) +void BorderAgent::CoapDtlsSession::SendErrorMessage(const Coap::Message &aRequest, bool aSeparate, Error aError) { Error error = kErrorNone; Coap::Message *message = nullptr; - VerifyOrExit(mCoapDtlsSession != nullptr); - - VerifyOrExit((message = mCoapDtlsSession->NewPriorityMessage()) != nullptr, error = kErrorNoBufs); + VerifyOrExit((message = NewPriorityMessage()) != nullptr, error = kErrorNoBufs); if (aRequest.IsNonConfirmable() || aSeparate) { @@ -599,7 +600,7 @@ void BorderAgent::SendErrorMessage(const Coap::Message &aRequest, bool aSeparate SuccessOrExit(error = message->SetTokenFromMessage(aRequest)); - SuccessOrExit(error = mCoapDtlsSession->SendMessage(*message)); + SuccessOrExit(error = SendMessage(*message)); exit: FreeMessageOnError(message, error); @@ -646,24 +647,22 @@ template <> void BorderAgent::HandleTmf(Coap::Message &aMessage, co message = mCoapDtlsSession->NewPriorityNonConfirmablePostMessage(kUriRelayRx); VerifyOrExit(message != nullptr, error = kErrorNoBufs); - SuccessOrExit(error = ForwardToCommissioner(*message, aMessage)); + SuccessOrExit(error = mCoapDtlsSession->ForwardToCommissioner(*message, aMessage)); LogInfo("Sent to commissioner on RelayRx (c/rx)"); exit: FreeMessageOnError(message, error); } -void BorderAgent::HandleTmfProxyTx(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +void BorderAgent::CoapDtlsSession::HandleTmfProxyTx(Coap::Message &aMessage) { - OT_UNUSED_VARIABLE(aMessageInfo); - Error error = kErrorNone; Message *message = nullptr; Ip6::MessageInfo messageInfo; OffsetRange offsetRange; UdpEncapsulationTlvHeader udpEncapHeader; - VerifyOrExit(mState != kStateStopped); + VerifyOrExit(Get().mState != kStateStopped); SuccessOrExit(error = Tlv::FindTlvValueOffsetRange(aMessage, Tlv::kUdpEncapsulation, offsetRange)); @@ -690,17 +689,15 @@ exit: LogWarnOnError(error, "send proxy stream"); } -void BorderAgent::HandleTmfRelayTx(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +void BorderAgent::CoapDtlsSession::HandleTmfRelayTx(Coap::Message &aMessage) { - OT_UNUSED_VARIABLE(aMessageInfo); - Error error = kErrorNone; uint16_t joinerRouterRloc; Coap::Message *message = nullptr; Tmf::MessageInfo messageInfo(GetInstance()); OffsetRange offsetRange; - VerifyOrExit(mState != kStateStopped); + VerifyOrExit(Get().mState != kStateStopped); VerifyOrExit(aMessage.IsNonConfirmablePostRequest()); @@ -724,15 +721,11 @@ exit: LogWarnOnError(error, "send to joiner router request RelayTx (c/tx)"); } -void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri) +void BorderAgent::CoapDtlsSession::HandleTmfDatasetGet(Coap::Message &aMessage, Uri aUri) { - OT_UNUSED_VARIABLE(aMessageInfo); - Error error = kErrorNone; Coap::Message *response = nullptr; - VerifyOrExit(mCoapDtlsSession != nullptr); - // When processing `MGMT_GET` request directly on Border Agent, // the Security Policy flags (O-bit) should be ignored to allow // the commissioner candidate to get the full Operational Dataset. @@ -741,12 +734,12 @@ void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::Messag { case kUriActiveGet: response = Get().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags); - mCounters.mMgmtActiveGets++; + Get().mCounters.mMgmtActiveGets++; break; case kUriPendingGet: response = Get().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags); - mCounters.mMgmtPendingGets++; + Get().mCounters.mMgmtPendingGets++; break; case kUriCommissionerGet: @@ -759,7 +752,7 @@ void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::Messag VerifyOrExit(response != nullptr, error = kErrorParse); - SuccessOrExit(error = mCoapDtlsSession->SendMessage(*response)); + SuccessOrExit(error = SendMessage(*response)); LogInfo("Sent %s response to non-active commissioner", PathForUri(aUri)); @@ -897,6 +890,27 @@ void BorderAgent::HandleDtlsTransportClosed(void) //---------------------------------------------------------------------------------------------------------------------- // `BorderAgent::CoapDtlsSession +BorderAgent::CoapDtlsSession::CoapDtlsSession(Instance &aInstance, Dtls::Transport &aDtlsTransport) + : Coap::SecureSession(aInstance, aDtlsTransport) + , mIsActiveCommissioner(false) + , mTimer(aInstance, HandleTimer, this) + , mUdpReceiver(HandleUdpReceive, this) +{ + mCommissionerAloc.InitAsThreadOriginMeshLocal(); + + SetResourceHandler(&HandleResource); + SetConnectCallback(&HandleConnected, this); +} + +void BorderAgent::CoapDtlsSession::Cleanup(void) +{ + mTimer.Stop(); + IgnoreError(Get().RemoveReceiver(mUdpReceiver)); + Get().RemoveUnicastAddress(mCommissionerAloc); + + Coap::SecureSession::Cleanup(); +} + bool BorderAgent::CoapDtlsSession::HandleResource(CoapBase &aCoapBase, const char *aUriPath, Coap::Message &aMessage, @@ -915,21 +929,21 @@ bool BorderAgent::CoapDtlsSession::HandleResource(const char *aUriPa switch (uri) { case kUriCommissionerPetition: - IgnoreError(Get().ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition)); + IgnoreError(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition)); break; case kUriCommissionerKeepAlive: - Get().HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo); + HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo); break; case kUriRelayTx: - Get().HandleTmfRelayTx(aMessage, aMessageInfo); + HandleTmfRelayTx(aMessage); break; case kUriCommissionerGet: case kUriActiveGet: case kUriPendingGet: - Get().HandleTmfDatasetGet(aMessage, aMessageInfo, uri); + HandleTmfDatasetGet(aMessage, uri); break; case kUriProxyTx: - Get().HandleTmfProxyTx(aMessage, aMessageInfo); + HandleTmfProxyTx(aMessage); break; default: didHandle = false; @@ -939,26 +953,38 @@ bool BorderAgent::CoapDtlsSession::HandleResource(const char *aUriPa return didHandle; } -//---------------------------------------------------------------------------------------------------------------------- -// `BorderAgent::ForwardContext` - -Error BorderAgent::ForwardContext::Init(Instance &aInstance, - const Coap::Message &aMessage, - bool aPetition, - bool aSeparate) +void BorderAgent::CoapDtlsSession::HandleTimer(Timer &aTimer) { - InstanceLocatorInit::Init(aInstance); - mMessageId = aMessage.GetMessageId(); - mPetition = aPetition; - mSeparate = aSeparate; - mType = aMessage.GetType(); - mTokenLength = aMessage.GetTokenLength(); - memcpy(mToken, aMessage.GetToken(), mTokenLength); - - return kErrorNone; + static_cast(static_cast(aTimer).GetContext())->HandleTimer(); } -Error BorderAgent::ForwardContext::ToHeader(Coap::Message &aMessage, uint8_t aCode) const +void BorderAgent::CoapDtlsSession::HandleTimer(void) +{ + if (IsConnected()) + { + LogInfo("Session timed out - disconnecting"); + Disconnect(); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +// `BorderAgent::CoapDtlsSession::ForwardContext` + +BorderAgent::CoapDtlsSession::ForwardContext::ForwardContext(CoapDtlsSession &aSesssion, + const Coap::Message &aMessage, + bool aPetition, + bool aSeparate) + : mSession(aSesssion) + , mMessageId(aMessage.GetMessageId()) + , mPetition(aPetition) + , mSeparate(aSeparate) + , mTokenLength(aMessage.GetTokenLength()) + , mType(aMessage.GetType()) +{ + memcpy(mToken, aMessage.GetToken(), mTokenLength); +} + +Error BorderAgent::CoapDtlsSession::ForwardContext::ToHeader(Coap::Message &aMessage, uint8_t aCode) const { if ((mType == Coap::kTypeNonConfirmable) || mSeparate) { diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp index 960399070..c50886883 100644 --- a/src/core/meshcop/border_agent.hpp +++ b/src/core/meshcop/border_agent.hpp @@ -252,35 +252,61 @@ private: { friend Heap::Allocatable; - private: - CoapDtlsSession(Instance &aInstance, Dtls::Transport &aDtlsTransport) - : Coap::SecureSession(aInstance, aDtlsTransport) - { - SetResourceHandler(&HandleResource); - } + public: + Error ForwardToCommissioner(Coap::Message &aForwardMessage, const Message &aMessage); + void Cleanup(void); + private: + class ForwardContext : public Heap::Allocatable, private ot::NonCopyable + { + friend class Heap::Allocatable; + + public: + Error ToHeader(Coap::Message &aMessage, uint8_t aCode) const; + + CoapDtlsSession &mSession; + uint16_t mMessageId; + bool mPetition : 1; + bool mSeparate : 1; + uint8_t mTokenLength : 4; + uint8_t mType : 2; + uint8_t mToken[Coap::Message::kMaxTokenLength]; + + private: + ForwardContext(CoapDtlsSession &aSesssion, const Coap::Message &aMessage, bool aPetition, bool aSeparate); + }; + + CoapDtlsSession(Instance &aInstance, Dtls::Transport &aDtlsTransport); + + void HandleTmfCommissionerKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + void HandleTmfRelayTx(Coap::Message &aMessage); + void HandleTmfProxyTx(Coap::Message &aMessage); + void HandleTmfDatasetGet(Coap::Message &aMessage, Uri aUri); + Error ForwardToLeader(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri); + void SendErrorMessage(const ForwardContext &aForwardContext, Error aError); + void SendErrorMessage(const Coap::Message &aRequest, bool aSeparate, Error aError); + + static void HandleConnected(ConnectEvent aEvent, void *aContext); + void HandleConnected(ConnectEvent aEvent); + static void HandleCoapResponse(void *aContext, + otMessage *aMessage, + const otMessageInfo *aMessageInfo, + otError aResult); + void HandleCoapResponse(const ForwardContext &aForwardContext, const Coap::Message *aResponse, Error aResult); + static bool HandleUdpReceive(void *aContext, const otMessage *aMessage, const otMessageInfo *aMessageInfo); + bool HandleUdpReceive(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); static bool HandleResource(CoapBase &aCoapBase, const char *aUriPath, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); bool HandleResource(const char *aUriPath, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - }; + static void HandleTimer(Timer &aTimer); + void HandleTimer(void); - class ForwardContext : public InstanceLocatorInit, public Heap::Allocatable - { - public: - Error Init(Instance &aInstance, const Coap::Message &aMessage, bool aPetition, bool aSeparate); - bool IsPetition(void) const { return mPetition; } - uint16_t GetMessageId(void) const { return mMessageId; } - Error ToHeader(Coap::Message &aMessage, uint8_t aCode) const; - - private: - uint16_t mMessageId; // The CoAP Message ID of the original request. - bool mPetition : 1; // Whether the forwarding request is leader petition. - bool mSeparate : 1; // Whether the original request expects separate response. - uint8_t mTokenLength : 4; // The CoAP Token Length of the original request. - uint8_t mType : 2; // The CoAP Type of the original request. - uint8_t mToken[Coap::Message::kMaxTokenLength]; // The CoAP Token of the original request. + bool mIsActiveCommissioner; + TimerMilliContext mTimer; + Ip6::Udp::Receiver mUdpReceiver; + Ip6::Netif::UnicastAddress mCommissionerAloc; }; void Start(void) { IgnoreError(Start(kUdpPort)); } @@ -288,15 +314,6 @@ private: Error Start(uint16_t aUdpPort, const uint8_t *aPsk, uint8_t aPskLength); void Stop(void); void HandleNotifierEvents(Events aEvents); - void HandleTimeout(void); - Error ForwardToLeader(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri); - Error ForwardToCommissioner(Coap::Message &aForwardMessage, const Message &aMessage); - void SendErrorMessage(const ForwardContext &aForwardContext, Error aError); - void SendErrorMessage(const Coap::Message &aRequest, bool aSeparate, Error aError); - void HandleTmfCommissionerKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - void HandleTmfRelayTx(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - void HandleTmfProxyTx(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - void HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri); template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); @@ -305,15 +322,9 @@ private: static void HandleRemoveSession(void *aContext, SecureSession &aSesssion); void HandleRemoveSession(SecureSession &aSesssion); - static void HandleConnected(Dtls::Session::ConnectEvent aEvent, void *aContext); - void HandleConnected(Dtls::Session::ConnectEvent aEvent); - static void HandleCoapResponse(void *aContext, - otMessage *aMessage, - const otMessageInfo *aMessageInfo, - otError aResult); - void HandleCoapResponse(const ForwardContext &aForwardContext, const Coap::Message *aResponse, Error aResult); - static bool HandleUdpReceive(void *aContext, const otMessage *aMessage, const otMessageInfo *aMessageInfo); - bool HandleUdpReceive(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + void HandleSessionConnected(CoapDtlsSession &aSesssion); + void HandleSessionDisconnected(CoapDtlsSession &aSesssion, CoapDtlsSession::ConnectEvent aEvent); + void HandleCommissionerPetitionAccepted(CoapDtlsSession &aSesssion); static Coap::Message::Code CoapCodeFromError(Error aError); @@ -325,18 +336,14 @@ private: void HandleDtlsTransportClosed(void); #endif - using TimeoutTimer = TimerMilliIn; #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE using EphemeralKeyTimer = TimerMilliIn; using EphemeralKeyTask = TaskletIn; #endif - State mState; - Ip6::Udp::Receiver mUdpReceiver; - Ip6::Netif::UnicastAddress mCommissionerAloc; - TimeoutTimer mTimer; - Dtls::Transport mDtlsTransport; - CoapDtlsSession *mCoapDtlsSession; + State mState; + Dtls::Transport mDtlsTransport; + CoapDtlsSession *mCoapDtlsSession; #if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE Id mId; bool mIdInitialized;