[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.
This commit is contained in:
Abtin Keshavarzian
2025-01-13 15:56:56 -08:00
committed by GitHub
parent 000ef41f5a
commit d16d160e2c
2 changed files with 228 additions and 195 deletions
+174 -148
View File
@@ -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<BorderAgent *>(aContext)->HandleConnected(aEvent);
static_cast<CoapDtlsSession *>(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<BorderAgent>().HandleSessionConnected(*this);
}
else
{
@@ -302,40 +273,67 @@ void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent)
IgnoreError(Get<Ip6::Udp>().RemoveReceiver(mUdpReceiver));
Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
Get<BorderAgent>().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> 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<BorderAgent>().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<Tmf::Agent>().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> forwardContext(static_cast<ForwardContext *>(aContext));
forwardContext->Get<BorderAgent>().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<Mle::Mle>().GetCommissionerAloc(sessionId, mCommissionerAloc.GetAddress());
Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
IgnoreError(Get<Ip6::Udp>().AddReceiver(mUdpReceiver));
mState = kStateAccepted;
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
if (mUsingEphemeralKey)
{
mCounters.mEpskcCommissionerPetitions++;
}
else
#endif
{
mCounters.mPskcCommissionerPetitions++;
}
mIsActiveCommissioner = true;
Get<BorderAgent>().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<BorderAgent *>(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<CoapDtlsSession *>(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<Ip6AddressTlv>(*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<kUriRelayRx>(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<BorderAgent>().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<BorderAgent>().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<ActiveDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
mCounters.mMgmtActiveGets++;
Get<BorderAgent>().mCounters.mMgmtActiveGets++;
break;
case kUriPendingGet:
response = Get<PendingDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
mCounters.mMgmtPendingGets++;
Get<BorderAgent>().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<Ip6::Udp>().RemoveReceiver(mUdpReceiver));
Get<ThreadNetif>().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<BorderAgent>().ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition));
IgnoreError(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition));
break;
case kUriCommissionerKeepAlive:
Get<BorderAgent>().HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo);
HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo);
break;
case kUriRelayTx:
Get<BorderAgent>().HandleTmfRelayTx(aMessage, aMessageInfo);
HandleTmfRelayTx(aMessage);
break;
case kUriCommissionerGet:
case kUriActiveGet:
case kUriPendingGet:
Get<BorderAgent>().HandleTmfDatasetGet(aMessage, aMessageInfo, uri);
HandleTmfDatasetGet(aMessage, uri);
break;
case kUriProxyTx:
Get<BorderAgent>().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<CoapDtlsSession *>(static_cast<TimerMilliContext &>(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)
{
+54 -47
View File
@@ -252,35 +252,61 @@ private:
{
friend Heap::Allocatable<CoapDtlsSession>;
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<ForwardContext>, private ot::NonCopyable
{
friend class Heap::Allocatable<ForwardContext>;
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<ForwardContext>
{
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 <Uri kUri> 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<BorderAgent, &BorderAgent::HandleTimeout>;
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
using EphemeralKeyTimer = TimerMilliIn<BorderAgent, &BorderAgent::HandleEphemeralKeyTimeout>;
using EphemeralKeyTask = TaskletIn<BorderAgent, &BorderAgent::InvokeEphemeralKeyCallback>;
#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;