mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[epskc] add API for ePSKc telemetry (#10608)
Adds API to get border agent counters which include counters for ePSKc, PSKc and coap messages.
This commit is contained in:
@@ -110,6 +110,38 @@ typedef enum otBorderAgentState
|
||||
OT_BORDER_AGENT_STATE_ACTIVE = 2, ///< Border agent is connected with external commissioner.
|
||||
} otBorderAgentState;
|
||||
|
||||
typedef struct otBorderAgentCounters
|
||||
{
|
||||
uint32_t mEpskcActivations; ///< The number of ePSKc activations
|
||||
uint32_t mEpskcDeactivationClears; ///< The number of ePSKc deactivations via API
|
||||
uint32_t mEpskcDeactivationTimeouts; ///< The number of ePSKc deactivations due to timeout
|
||||
uint32_t mEpskcDeactivationMaxAttempts; ///< The number of ePSKc deactivations due to reached max attempts
|
||||
uint32_t mEpskcDeactivationDisconnects; ///< The number of ePSKc deactivations due to commissioner disconnected
|
||||
uint32_t mEpskcInvalidBaStateErrors; ///< The number of invalid border agent state errors at ePSKc activation
|
||||
uint32_t mEpskcInvalidArgsErrors; ///< The number of invalid args errors at ePSKc activation
|
||||
uint32_t mEpskcStartSecureSessionErrors; ///< The number of start secure session errors at ePSKc activation
|
||||
uint32_t mEpskcSecureSessionSuccesses; ///< The number of established secure sessions with ePSKc
|
||||
uint32_t mEpskcSecureSessionFailures; ///< The number of failed secure sessions with ePSKc
|
||||
uint32_t mEpskcCommissionerPetitions; ///< The number of successful commissioner petitions with ePSKc
|
||||
|
||||
uint32_t mPskcSecureSessionSuccesses; ///< The number of established secure sessions with PSKc
|
||||
uint32_t mPskcSecureSessionFailures; ///< The number of failed secure sessions with PSKc
|
||||
uint32_t mPskcCommissionerPetitions; ///< The number of successful commissioner petitions with PSKc
|
||||
|
||||
uint32_t mMgmtActiveGets; ///< The number of MGMT_ACTIVE_GET.req sent over secure sessions
|
||||
uint32_t mMgmtPendingGets; ///< The number of MGMT_PENDING_GET.req sent over secure sessions
|
||||
} otBorderAgentCounters;
|
||||
|
||||
/**
|
||||
* Gets the counters of the Thread Border Agent.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to the Border Agent counters.
|
||||
*
|
||||
*/
|
||||
const otBorderAgentCounters *otBorderAgentGetCounters(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Gets the #otBorderAgentState of the Thread Border Agent role.
|
||||
*
|
||||
|
||||
@@ -67,14 +67,27 @@ extern "C" {
|
||||
|
||||
#define OT_DEFAULT_COAP_SECURE_PORT 5684 ///< Default CoAP Secure port, as specified in RFC 7252
|
||||
|
||||
/**
|
||||
* CoAP secure connection event types.
|
||||
*
|
||||
*/
|
||||
typedef enum otCoapSecureConnectEvent
|
||||
{
|
||||
OT_COAP_SECURE_CONNECTED = 0, ///< Connection established
|
||||
OT_COAP_SECURE_DISCONNECTED_PEER_CLOSED, ///< Disconnected by peer
|
||||
OT_COAP_SECURE_DISCONNECTED_LOCAL_CLOSED, ///< Disconnected locally
|
||||
OT_COAP_SECURE_DISCONNECTED_MAX_ATTEMPTS, ///< Disconnected due to reaching the max connection attempts
|
||||
OT_COAP_SECURE_DISCONNECTED_ERROR, ///< Disconnected due to an error
|
||||
} otCoapSecureConnectEvent;
|
||||
|
||||
/**
|
||||
* Pointer is called when the DTLS connection state changes.
|
||||
*
|
||||
* @param[in] aConnected true, if a connection was established, false otherwise.
|
||||
* @param[in] aEvent The connection event.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
typedef void (*otHandleCoapSecureClientConnect)(bool aConnected, void *aContext);
|
||||
typedef void (*otHandleCoapSecureClientConnect)(otCoapSecureConnectEvent aEvent, void *aContext);
|
||||
|
||||
/**
|
||||
* Callback function pointer to notify when the CoAP secure agent is automatically stopped due to reaching the maximum
|
||||
@@ -368,17 +381,17 @@ void otCoapSecureRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseR
|
||||
void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* Sets the connected callback to indicate, when
|
||||
* a Client connect to the CoAP Secure server.
|
||||
* Sets the connect event callback to indicate when
|
||||
* a Client connection to the CoAP Secure server has changed.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aHandler A pointer to a function that will be called once DTLS connection is established.
|
||||
* @param[in] aHandler A pointer to a function that will be called once DTLS connection has changed.
|
||||
* @param[in] aContext A pointer to arbitrary context information. May be NULL if not used.
|
||||
*
|
||||
*/
|
||||
void otCoapSecureSetClientConnectedCallback(otInstance *aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void *aContext);
|
||||
void otCoapSecureSetClientConnectEventCallback(otInstance *aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void *aContext);
|
||||
|
||||
/**
|
||||
* Sends a CoAP response block-wise from the CoAP Secure server.
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (435)
|
||||
#define OPENTHREAD_API_VERSION (436)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -453,6 +453,33 @@ Disables callback from Border Agent for ephemeral key state changes.
|
||||
Done
|
||||
```
|
||||
|
||||
### ba counters
|
||||
|
||||
Get the border agent counter values.
|
||||
|
||||
Note that it requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE` to output the ePSKc counters.
|
||||
|
||||
```bash
|
||||
> ba counters
|
||||
epskcActivation: 2
|
||||
epskcApiDeactivation: 1
|
||||
epskcTimeoutDeactivation: 1
|
||||
epskcMaxAttemptDeactivation: 0
|
||||
epskcDisconnectDeactivation: 0
|
||||
epskcInvalidBaStateError: 1
|
||||
epskcInvalidArgsError: 1
|
||||
epskcStartSecureSessionError: 0
|
||||
epskcSecureSessionSuccess: 0
|
||||
epskcSecureSessionFailure: 0
|
||||
epskcCommissionerPetition: 0
|
||||
pskcSecureSessionSuccess: 0
|
||||
pskcSecureSessionFailure: 0
|
||||
pskcCommissionerPetition: 0
|
||||
mgmtActiveGet: 0
|
||||
mgmtPendingGet: 0
|
||||
Done
|
||||
```
|
||||
|
||||
### bufferinfo
|
||||
|
||||
Show the current message buffer information.
|
||||
|
||||
@@ -541,6 +541,36 @@ template <> otError Interpreter::Process<Cmd("ba")>(Arg aArgs[])
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
/**
|
||||
* @cli ba counters
|
||||
* @code
|
||||
* ba counters
|
||||
* epskcActivation: 0
|
||||
* epskcApiDeactivation: 0
|
||||
* epskcTimeoutDeactivation: 0
|
||||
* epskcMaxAttemptDeactivation: 0
|
||||
* epskcDisconnectDeactivation: 0
|
||||
* epskcInvalidBaStateError: 0
|
||||
* epskcInvalidArgsError: 0
|
||||
* epskcStartSecureSessionError: 0
|
||||
* epskcSecureSessionSuccess: 0
|
||||
* epskcSecureSessionFailure: 0
|
||||
* epskcCommissionerPetition: 0
|
||||
* pskcSecureSessionSuccess: 0
|
||||
* pskcSecureSessionFailure: 0
|
||||
* pskcCommissionerPetition: 0
|
||||
* mgmtActiveGet: 0
|
||||
* mgmtPendingGet: 0
|
||||
* Done
|
||||
* @endcode
|
||||
* @par
|
||||
* Gets the border agent counters.
|
||||
* @sa otBorderAgentGetCounters
|
||||
*/
|
||||
else if (aArgs[0] == "counters")
|
||||
{
|
||||
OutputBorderAgentCounters(*otBorderAgentGetCounters(GetInstancePtr()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_COMMAND);
|
||||
@@ -550,6 +580,28 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Interpreter::OutputBorderAgentCounters(const otBorderAgentCounters &aCounters)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
OutputLine("epskcActivation: %lu ", ToUlong(aCounters.mEpskcActivations));
|
||||
OutputLine("epskcApiDeactivation: %lu ", ToUlong(aCounters.mEpskcDeactivationClears));
|
||||
OutputLine("epskcTimeoutDeactivation: %lu ", ToUlong(aCounters.mEpskcDeactivationTimeouts));
|
||||
OutputLine("epskcMaxAttemptDeactivation: %lu ", ToUlong(aCounters.mEpskcDeactivationMaxAttempts));
|
||||
OutputLine("epskcDisconnectDeactivation: %lu ", ToUlong(aCounters.mEpskcDeactivationDisconnects));
|
||||
OutputLine("epskcInvalidBaStateError: %lu ", ToUlong(aCounters.mEpskcInvalidBaStateErrors));
|
||||
OutputLine("epskcInvalidArgsError: %lu ", ToUlong(aCounters.mEpskcInvalidArgsErrors));
|
||||
OutputLine("epskcStartSecureSessionError: %lu ", ToUlong(aCounters.mEpskcStartSecureSessionErrors));
|
||||
OutputLine("epskcSecureSessionSuccess: %lu ", ToUlong(aCounters.mEpskcSecureSessionSuccesses));
|
||||
OutputLine("epskcSecureSessionFailure: %lu ", ToUlong(aCounters.mEpskcSecureSessionFailures));
|
||||
OutputLine("epskcCommissionerPetition: %lu ", ToUlong(aCounters.mEpskcCommissionerPetitions));
|
||||
#endif
|
||||
OutputLine("pskcSecureSessionSuccess: %lu ", ToUlong(aCounters.mPskcSecureSessionSuccesses));
|
||||
OutputLine("pskcSecureSessionFailure: %lu ", ToUlong(aCounters.mPskcSecureSessionFailures));
|
||||
OutputLine("pskcCommissionerPetition: %lu ", ToUlong(aCounters.mPskcCommissionerPetitions));
|
||||
OutputLine("mgmtActiveGet: %lu ", ToUlong(aCounters.mMgmtActiveGets));
|
||||
OutputLine("mgmtPendingGet: %lu", ToUlong(aCounters.mMgmtPendingGets));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
void Interpreter::HandleBorderAgentEphemeralKeyStateChange(void *aContext)
|
||||
{
|
||||
|
||||
+5
-1
@@ -40,6 +40,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <openthread/border_agent.h>
|
||||
#include <openthread/cli.h>
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/dns_client.h>
|
||||
@@ -314,9 +315,12 @@ private:
|
||||
void HandleSntpResponse(uint64_t aTime, otError aResult);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
void OutputBorderAgentCounters(const otBorderAgentCounters &aCounters);
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
static void HandleBorderAgentEphemeralKeyStateChange(void *aContext);
|
||||
void HandleBorderAgentEphemeralKeyStateChange(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void HandleDetachGracefullyResult(void *aContext);
|
||||
|
||||
@@ -210,7 +210,7 @@ exit:
|
||||
* Starts the CoAP Secure service. @moreinfo{@coaps}.
|
||||
* @sa otCoapSecureStart
|
||||
* @sa otCoapSecureSetSslAuthMode
|
||||
* @sa otCoapSecureSetClientConnectedCallback
|
||||
* @sa otCoapSecureSetClientConnectEventCallback
|
||||
*/
|
||||
template <> otError CoapSecure::Process<Cmd("start")>(Arg aArgs[])
|
||||
{
|
||||
@@ -235,7 +235,7 @@ template <> otError CoapSecure::Process<Cmd("start")>(Arg aArgs[])
|
||||
}
|
||||
|
||||
otCoapSecureSetSslAuthMode(GetInstancePtr(), verifyPeerCert);
|
||||
otCoapSecureSetClientConnectedCallback(GetInstancePtr(), &CoapSecure::HandleConnected, this);
|
||||
otCoapSecureSetClientConnectEventCallback(GetInstancePtr(), &CoapSecure::HandleConnectEvent, this);
|
||||
|
||||
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
otCoapSecureSetDefaultHandler(GetInstancePtr(), &CoapSecure::DefaultHandler, this);
|
||||
@@ -629,7 +629,7 @@ template <> otError CoapSecure::Process<Cmd("connect")>(Arg aArgs[])
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCoapSecureConnect(GetInstancePtr(), &sockaddr, &CoapSecure::HandleConnected, this));
|
||||
SuccessOrExit(error = otCoapSecureConnect(GetInstancePtr(), &sockaddr, &CoapSecure::HandleConnectEvent, this));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -783,14 +783,14 @@ void CoapSecure::Stop(void)
|
||||
otCoapSecureStop(GetInstancePtr());
|
||||
}
|
||||
|
||||
void CoapSecure::HandleConnected(bool aConnected, void *aContext)
|
||||
void CoapSecure::HandleConnectEvent(otCoapSecureConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
static_cast<CoapSecure *>(aContext)->HandleConnected(aConnected);
|
||||
static_cast<CoapSecure *>(aContext)->HandleConnectEvent(aEvent);
|
||||
}
|
||||
|
||||
void CoapSecure::HandleConnected(bool aConnected)
|
||||
void CoapSecure::HandleConnectEvent(otCoapSecureConnectEvent aEvent)
|
||||
{
|
||||
if (aConnected)
|
||||
if (aEvent == OT_COAP_SECURE_CONNECTED)
|
||||
{
|
||||
OutputLine("coaps connected");
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ private:
|
||||
void DefaultHandler(otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
|
||||
static void HandleConnected(bool aConnected, void *aContext);
|
||||
void HandleConnected(bool aConnected);
|
||||
static void HandleConnectEvent(otCoapSecureConnectEvent aEvent, void *aContext);
|
||||
void HandleConnectEvent(otCoapSecureConnectEvent aEvent);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
otCoapBlockwiseResource mResource;
|
||||
|
||||
@@ -110,4 +110,9 @@ void otBorderAgentSetEphemeralKeyCallback(otInstance *aIns
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
|
||||
const otBorderAgentCounters *otBorderAgentGetCounters(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().GetCounters();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
@@ -178,11 +178,11 @@ void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource
|
||||
AsCoreType(aInstance).GetApplicationCoapSecure().RemoveResource(AsCoreType(aResource));
|
||||
}
|
||||
|
||||
void otCoapSecureSetClientConnectedCallback(otInstance *aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void *aContext)
|
||||
void otCoapSecureSetClientConnectEventCallback(otInstance *aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void *aContext)
|
||||
{
|
||||
AsCoreType(aInstance).GetApplicationCoapSecure().SetConnectedCallback(aHandler, aContext);
|
||||
AsCoreType(aInstance).GetApplicationCoapSecure().SetConnectEventCallback(aHandler, aContext);
|
||||
}
|
||||
|
||||
void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
|
||||
|
||||
@@ -85,8 +85,8 @@ Error CoapSecure::Open(uint16_t aMaxAttempts, AutoStopCallback aCallback, void *
|
||||
|
||||
SuccessOrExit(mDtls.SetMaxConnectionAttempts(aMaxAttempts, HandleDtlsAutoClose, this));
|
||||
mAutoStopCallback.Set(aCallback, aContext);
|
||||
mConnectedCallback.Clear();
|
||||
SuccessOrExit(mDtls.Open(HandleDtlsReceive, HandleDtlsConnected, this));
|
||||
mConnectEventCallback.Clear();
|
||||
SuccessOrExit(mDtls.Open(HandleDtlsReceive, HandleDtlsConnectEvent, this));
|
||||
|
||||
error = kErrorNone;
|
||||
|
||||
@@ -102,9 +102,9 @@ void CoapSecure::Stop(void)
|
||||
ClearRequestsAndResponses();
|
||||
}
|
||||
|
||||
Error CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext)
|
||||
Error CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectEventCallback aCallback, void *aContext)
|
||||
{
|
||||
mConnectedCallback.Set(aCallback, aContext);
|
||||
mConnectEventCallback.Set(aCallback, aContext);
|
||||
|
||||
return mDtls.Connect(aSockAddr);
|
||||
}
|
||||
@@ -178,12 +178,15 @@ Error CoapSecure::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
|
||||
void CoapSecure::HandleDtlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
return static_cast<CoapSecure *>(aContext)->HandleDtlsConnected(aConnected);
|
||||
return static_cast<CoapSecure *>(aContext)->HandleDtlsConnectEvent(aEvent);
|
||||
}
|
||||
|
||||
void CoapSecure::HandleDtlsConnected(bool aConnected) { mConnectedCallback.InvokeIfSet(aConnected); }
|
||||
void CoapSecure::HandleDtlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent)
|
||||
{
|
||||
mConnectEventCallback.InvokeIfSet(aEvent);
|
||||
}
|
||||
|
||||
void CoapSecure::HandleDtlsAutoClose(void *aContext)
|
||||
{
|
||||
|
||||
@@ -53,13 +53,10 @@ class CoapSecure : public CoapBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Pointer is called once DTLS connection is established.
|
||||
*
|
||||
* @param[in] aConnected TRUE if a connection was established, FALSE otherwise.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* Function pointer which is called reporting a connection event (when connection established or disconnected)
|
||||
*
|
||||
*/
|
||||
typedef void (*ConnectedCallback)(bool aConnected, void *aContext);
|
||||
typedef otHandleCoapSecureClientConnect ConnectEventCallback;
|
||||
|
||||
/**
|
||||
* Callback to notify when the agent is automatically stopped due to reaching the maximum number of connection
|
||||
@@ -122,9 +119,9 @@ public:
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
void SetConnectedCallback(ConnectedCallback aCallback, void *aContext)
|
||||
void SetConnectEventCallback(ConnectEventCallback aCallback, void *aContext)
|
||||
{
|
||||
mConnectedCallback.Set(aCallback, aContext);
|
||||
mConnectEventCallback.Set(aCallback, aContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,7 +140,7 @@ public:
|
||||
* @retval kErrorNone Successfully started DTLS connection.
|
||||
*
|
||||
*/
|
||||
Error Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext);
|
||||
Error Connect(const Ip6::SockAddr &aSockAddr, ConnectEventCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* Indicates whether or not the DTLS session is active.
|
||||
@@ -421,8 +418,8 @@ private:
|
||||
}
|
||||
Error Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleDtlsConnected(void *aContext, bool aConnected);
|
||||
void HandleDtlsConnected(bool aConnected);
|
||||
static void HandleDtlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent, void *aContext);
|
||||
void HandleDtlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent);
|
||||
|
||||
static void HandleDtlsAutoClose(void *aContext);
|
||||
void HandleDtlsAutoClose(void);
|
||||
@@ -433,11 +430,11 @@ private:
|
||||
static void HandleTransmit(Tasklet &aTasklet);
|
||||
void HandleTransmit(void);
|
||||
|
||||
MeshCoP::SecureTransport mDtls;
|
||||
Callback<ConnectedCallback> mConnectedCallback;
|
||||
Callback<AutoStopCallback> mAutoStopCallback;
|
||||
ot::MessageQueue mTransmitQueue;
|
||||
TaskletContext mTransmitTask;
|
||||
MeshCoP::SecureTransport mDtls;
|
||||
Callback<ConnectEventCallback> mConnectEventCallback;
|
||||
Callback<AutoStopCallback> mAutoStopCallback;
|
||||
ot::MessageQueue mTransmitQueue;
|
||||
TaskletContext mTransmitTask;
|
||||
};
|
||||
|
||||
} // namespace Coap
|
||||
|
||||
@@ -205,6 +205,17 @@ void BorderAgent::HandleCoapResponse(const ForwardContext &aForwardContext,
|
||||
IgnoreError(Get<Ip6::Udp>().AddReceiver(mUdpReceiver));
|
||||
mState = kStateAccepted;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
if (mUsingEphemeralKey)
|
||||
{
|
||||
mCounters.mEpskcCommissionerPetitions++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mCounters.mPskcCommissionerPetitions++;
|
||||
}
|
||||
|
||||
LogInfo("Commissioner accepted - SessionId:%u ALOC:%s", sessionId,
|
||||
mCommissionerAloc.GetAddress().ToString().AsCString());
|
||||
}
|
||||
@@ -252,6 +263,7 @@ BorderAgent::BorderAgent(Instance &aInstance)
|
||||
#endif
|
||||
{
|
||||
mCommissionerAloc.InitAsThreadOriginMeshLocal();
|
||||
ClearAllBytes(mCounters);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
|
||||
@@ -468,6 +480,7 @@ void BorderAgent::HandleTmf<kUriCommissionerSet>(Coap::Message &aMessage, const
|
||||
template <> void BorderAgent::HandleTmf<kUriActiveGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, Dataset::kActive);
|
||||
mCounters.mMgmtActiveGets++;
|
||||
}
|
||||
|
||||
template <> void BorderAgent::HandleTmf<kUriActiveSet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
@@ -478,6 +491,7 @@ template <> void BorderAgent::HandleTmf<kUriActiveSet>(Coap::Message &aMessage,
|
||||
template <> void BorderAgent::HandleTmf<kUriPendingGet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
HandleTmfDatasetGet(aMessage, aMessageInfo, Dataset::kPending);
|
||||
mCounters.mMgmtPendingGets++;
|
||||
}
|
||||
|
||||
template <> void BorderAgent::HandleTmf<kUriPendingSet>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
@@ -635,18 +649,28 @@ exit:
|
||||
FreeMessageOnError(response, error);
|
||||
}
|
||||
|
||||
void BorderAgent::HandleConnected(bool aConnected, void *aContext)
|
||||
void BorderAgent::HandleConnected(SecureTransport::ConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
static_cast<BorderAgent *>(aContext)->HandleConnected(aConnected);
|
||||
static_cast<BorderAgent *>(aContext)->HandleConnected(aEvent);
|
||||
}
|
||||
|
||||
void BorderAgent::HandleConnected(bool aConnected)
|
||||
void BorderAgent::HandleConnected(SecureTransport::ConnectEvent aEvent)
|
||||
{
|
||||
if (aConnected)
|
||||
if (aEvent == SecureTransport::kConnected)
|
||||
{
|
||||
LogInfo("SecureSession connected");
|
||||
mState = kStateConnected;
|
||||
mTimer.Start(kKeepAliveTimeout);
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
if (mUsingEphemeralKey)
|
||||
{
|
||||
mCounters.mEpskcSecureSessionSuccesses++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mCounters.mPskcSecureSessionSuccesses++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -658,12 +682,24 @@ void BorderAgent::HandleConnected(bool aConnected)
|
||||
if (mUsingEphemeralKey)
|
||||
{
|
||||
RestartAfterRemovingEphemeralKey();
|
||||
if (aEvent == SecureTransport::kDisconnectedError)
|
||||
{
|
||||
mCounters.mEpskcSecureSessionFailures++;
|
||||
}
|
||||
if (aEvent == SecureTransport::kDisconnectedPeerClosed)
|
||||
{
|
||||
mCounters.mEpskcDeactivationDisconnects++;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mState = kStateStarted;
|
||||
mUdpProxyPort = 0;
|
||||
if (aEvent == SecureTransport::kDisconnectedError)
|
||||
{
|
||||
mCounters.mPskcSecureSessionFailures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -702,7 +738,7 @@ Error BorderAgent::Start(uint16_t aUdpPort, const uint8_t *aPsk, uint8_t aPskLen
|
||||
|
||||
SuccessOrExit(error = Get<Tmf::SecureAgent>().SetPsk(aPsk, aPskLength));
|
||||
|
||||
Get<Tmf::SecureAgent>().SetConnectedCallback(HandleConnected, this);
|
||||
Get<Tmf::SecureAgent>().SetConnectEventCallback(HandleConnected, this);
|
||||
|
||||
mState = kStateStarted;
|
||||
mUdpProxyPort = 0;
|
||||
@@ -776,6 +812,7 @@ Error BorderAgent::SetEphemeralKey(const char *aKeyString, uint32_t aTimeout, ui
|
||||
{
|
||||
mUsingEphemeralKey = false;
|
||||
IgnoreError(Start(mOldUdpPort));
|
||||
mCounters.mEpskcStartSecureSessionErrors++;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -789,10 +826,23 @@ Error BorderAgent::SetEphemeralKey(const char *aKeyString, uint32_t aTimeout, ui
|
||||
aTimeout = Min(aTimeout, kMaxEphemeralKeyTimeout);
|
||||
|
||||
mEphemeralKeyTimer.Start(aTimeout);
|
||||
mCounters.mEpskcActivations++;
|
||||
|
||||
LogInfo("Allow ephemeral key for %lu msec on port %u", ToUlong(aTimeout), GetUdpPort());
|
||||
|
||||
exit:
|
||||
switch (error)
|
||||
{
|
||||
case kErrorInvalidState:
|
||||
mCounters.mEpskcInvalidBaStateErrors++;
|
||||
break;
|
||||
case kErrorInvalidArgs:
|
||||
mCounters.mEpskcInvalidArgsErrors++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -801,6 +851,16 @@ void BorderAgent::ClearEphemeralKey(void)
|
||||
VerifyOrExit(mUsingEphemeralKey);
|
||||
|
||||
LogInfo("Clearing ephemeral key");
|
||||
|
||||
if (mEphemeralKeyTimer.IsRunning())
|
||||
{
|
||||
mCounters.mEpskcDeactivationClears++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCounters.mEpskcDeactivationTimeouts++;
|
||||
}
|
||||
|
||||
mEphemeralKeyTimer.Stop();
|
||||
|
||||
switch (mState)
|
||||
@@ -847,6 +907,7 @@ void BorderAgent::HandleSecureAgentStopped(void)
|
||||
{
|
||||
LogInfo("Reached max allowed connection attempts with ephemeral key");
|
||||
RestartAfterRemovingEphemeralKey();
|
||||
mCounters.mEpskcDeactivationMaxAttempts++;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
|
||||
@@ -238,6 +238,14 @@ public:
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
|
||||
/**
|
||||
* Gets the set of border agent counters.
|
||||
*
|
||||
* @returns The border agent counters.
|
||||
*
|
||||
*/
|
||||
const otBorderAgentCounters *GetCounters(void) { return &mCounters; }
|
||||
|
||||
/**
|
||||
* Returns the UDP Proxy port to which the commissioner is currently
|
||||
* bound.
|
||||
@@ -285,8 +293,8 @@ private:
|
||||
void SendErrorMessage(const ForwardContext &aForwardContext, Error aError);
|
||||
void SendErrorMessage(const Coap::Message &aRequest, bool aSeparate, Error aError);
|
||||
|
||||
static void HandleConnected(bool aConnected, void *aContext);
|
||||
void HandleConnected(bool aConnected);
|
||||
static void HandleConnected(SecureTransport::ConnectEvent aEvent, void *aContext);
|
||||
void HandleConnected(SecureTransport::ConnectEvent aEvent);
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
@@ -333,6 +341,7 @@ private:
|
||||
EphemeralKeyTask mEphemeralKeyTask;
|
||||
Callback<EphemeralKeyCallback> mEphemeralKeyCallback;
|
||||
#endif
|
||||
otBorderAgentCounters mCounters;
|
||||
};
|
||||
|
||||
DeclareTmfHandler(BorderAgent, kUriRelayRx);
|
||||
|
||||
@@ -127,19 +127,20 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Commissioner::HandleSecureAgentConnected(bool aConnected, void *aContext)
|
||||
void Commissioner::HandleSecureAgentConnectEvent(SecureTransport::ConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandleSecureAgentConnected(aConnected);
|
||||
static_cast<Commissioner *>(aContext)->HandleSecureAgentConnectEvent(aEvent);
|
||||
}
|
||||
|
||||
void Commissioner::HandleSecureAgentConnected(bool aConnected)
|
||||
void Commissioner::HandleSecureAgentConnectEvent(SecureTransport::ConnectEvent aEvent)
|
||||
{
|
||||
if (!aConnected)
|
||||
bool isConnected = (aEvent == SecureTransport::kConnected);
|
||||
if (!isConnected)
|
||||
{
|
||||
mJoinerSessionTimer.Stop();
|
||||
}
|
||||
|
||||
SignalJoinerEvent(aConnected ? kJoinerEventConnected : kJoinerEventEnd, mActiveJoiner);
|
||||
SignalJoinerEvent(isConnected ? kJoinerEventConnected : kJoinerEventEnd, mActiveJoiner);
|
||||
}
|
||||
|
||||
Commissioner::Joiner *Commissioner::GetUnusedJoinerEntry(void)
|
||||
@@ -287,7 +288,7 @@ Error Commissioner::Start(StateCallback aStateCallback, JoinerCallback aJoinerCa
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = Get<Tmf::SecureAgent>().Start(SendRelayTransmit, this));
|
||||
Get<Tmf::SecureAgent>().SetConnectedCallback(&Commissioner::HandleSecureAgentConnected, this);
|
||||
Get<Tmf::SecureAgent>().SetConnectEventCallback(&Commissioner::HandleSecureAgentConnectEvent, this);
|
||||
|
||||
mStateCallback.Set(aStateCallback, aCallbackContext);
|
||||
mJoinerCallback.Set(aJoinerCallback, aCallbackContext);
|
||||
|
||||
@@ -440,8 +440,8 @@ private:
|
||||
Error aResult);
|
||||
void HandleLeaderKeepAliveResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult);
|
||||
|
||||
static void HandleSecureAgentConnected(bool aConnected, void *aContext);
|
||||
void HandleSecureAgentConnected(bool aConnected);
|
||||
static void HandleSecureAgentConnectEvent(SecureTransport::ConnectEvent aEvent, void *aContext);
|
||||
void HandleSecureAgentConnectEvent(SecureTransport::ConnectEvent aEvent);
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
|
||||
@@ -382,16 +382,16 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Joiner::HandleSecureCoapClientConnect(bool aConnected, void *aContext)
|
||||
void Joiner::HandleSecureCoapClientConnect(SecureTransport::ConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleSecureCoapClientConnect(aConnected);
|
||||
static_cast<Joiner *>(aContext)->HandleSecureCoapClientConnect(aEvent);
|
||||
}
|
||||
|
||||
void Joiner::HandleSecureCoapClientConnect(bool aConnected)
|
||||
void Joiner::HandleSecureCoapClientConnect(SecureTransport::ConnectEvent aEvent)
|
||||
{
|
||||
VerifyOrExit(mState == kStateConnect);
|
||||
|
||||
if (aConnected)
|
||||
if (aEvent == SecureTransport::kConnected)
|
||||
{
|
||||
SetState(kStateConnected);
|
||||
SendJoinerFinalize();
|
||||
|
||||
@@ -199,8 +199,8 @@ private:
|
||||
static void HandleDiscoverResult(Mle::DiscoverScanner::ScanResult *aResult, void *aContext);
|
||||
void HandleDiscoverResult(Mle::DiscoverScanner::ScanResult *aResult);
|
||||
|
||||
static void HandleSecureCoapClientConnect(bool aConnected, void *aContext);
|
||||
void HandleSecureCoapClientConnect(bool aConnected);
|
||||
static void HandleSecureCoapClientConnect(SecureTransport::ConnectEvent aEvent, void *aContext);
|
||||
void HandleSecureCoapClientConnect(SecureTransport::ConnectEvent aEvent);
|
||||
|
||||
static void HandleJoinerFinalizeResponse(void *aContext,
|
||||
otMessage *aMessage,
|
||||
|
||||
@@ -1043,15 +1043,15 @@ void SecureTransport::HandleTimer(void)
|
||||
if ((mMaxConnectionAttempts > 0) && (mRemainingConnectionAttempts == 0))
|
||||
{
|
||||
Close();
|
||||
mConnectedCallback.InvokeIfSet(false);
|
||||
mConnectEvent = kDisconnectedMaxAttempts;
|
||||
mAutoCloseCallback.InvokeIfSet();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState(kStateOpen);
|
||||
mTimer.Stop();
|
||||
mConnectedCallback.InvokeIfSet(false);
|
||||
}
|
||||
mConnectedCallback.InvokeIfSet(mConnectEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1070,7 +1070,8 @@ void SecureTransport::Process(void)
|
||||
if (mSsl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_HANDSHAKE_OVER)
|
||||
{
|
||||
SetState(kStateConnected);
|
||||
mConnectedCallback.InvokeIfSet(true);
|
||||
mConnectEvent = kConnected;
|
||||
mConnectedCallback.InvokeIfSet(mConnectEvent);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1092,6 +1093,7 @@ void SecureTransport::Process(void)
|
||||
{
|
||||
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
mConnectEvent = kDisconnectedPeerClosed;
|
||||
ExitNow(shouldDisconnect = true);
|
||||
OT_UNREACHABLE_CODE(break);
|
||||
|
||||
@@ -1100,6 +1102,7 @@ void SecureTransport::Process(void)
|
||||
|
||||
case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
mConnectEvent = kDisconnectedError;
|
||||
ExitNow(shouldDisconnect = true);
|
||||
OT_UNREACHABLE_CODE(break);
|
||||
|
||||
@@ -1108,6 +1111,7 @@ void SecureTransport::Process(void)
|
||||
{
|
||||
mbedtls_ssl_send_alert_message(&mSsl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
|
||||
mConnectEvent = kDisconnectedError;
|
||||
ExitNow(shouldDisconnect = true);
|
||||
}
|
||||
|
||||
@@ -1118,6 +1122,7 @@ void SecureTransport::Process(void)
|
||||
{
|
||||
mbedtls_ssl_send_alert_message(&mSsl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
|
||||
mConnectEvent = kDisconnectedError;
|
||||
ExitNow(shouldDisconnect = true);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <openthread/coap_secure.h>
|
||||
|
||||
#include "common/callback.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/log.hpp"
|
||||
@@ -87,8 +89,22 @@ namespace MeshCoP {
|
||||
class SecureTransport : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
typedef otCoapSecureConnectEvent ConnectEvent; ///< A connect event.
|
||||
|
||||
static constexpr ConnectEvent kConnected = OT_COAP_SECURE_CONNECTED;
|
||||
static constexpr ConnectEvent kDisconnectedPeerClosed = OT_COAP_SECURE_DISCONNECTED_PEER_CLOSED;
|
||||
static constexpr ConnectEvent kDisconnectedLocalClosed = OT_COAP_SECURE_DISCONNECTED_LOCAL_CLOSED;
|
||||
static constexpr ConnectEvent kDisconnectedMaxAttempts = OT_COAP_SECURE_DISCONNECTED_MAX_ATTEMPTS;
|
||||
static constexpr ConnectEvent kDisconnectedError = OT_COAP_SECURE_DISCONNECTED_ERROR;
|
||||
|
||||
static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length.
|
||||
|
||||
/**
|
||||
* Function pointer which is called reporting a connection event (when connection established or disconnected)
|
||||
*
|
||||
*/
|
||||
typedef otHandleCoapSecureClientConnect ConnectedHandler;
|
||||
|
||||
/**
|
||||
* Initializes the SecureTransport object.
|
||||
*
|
||||
@@ -99,15 +115,6 @@ public:
|
||||
*/
|
||||
explicit SecureTransport(Instance &aInstance, bool aLayerTwoSecurity, bool aDatagramTransport = true);
|
||||
|
||||
/**
|
||||
* Pointer is called when a connection is established or torn down.
|
||||
*
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* @param[in] aConnected TRUE if a connection was established, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
typedef void (*ConnectedHandler)(void *aContext, bool aConnected);
|
||||
|
||||
/**
|
||||
* Pointer is called when data is received from the session.
|
||||
*
|
||||
@@ -670,6 +677,8 @@ private:
|
||||
|
||||
Message::SubType mMessageSubType;
|
||||
Message::SubType mMessageDefaultSubType;
|
||||
|
||||
ConnectEvent mConnectEvent;
|
||||
};
|
||||
|
||||
} // namespace MeshCoP
|
||||
|
||||
@@ -83,7 +83,7 @@ Error BleSecure::Start(ConnectCallback aConnectHandler, ReceiveCallback aReceive
|
||||
SuccessOrExit(error = otPlatBleGapAdvSetData(&GetInstance(), advertisementData, advertisementLen));
|
||||
SuccessOrExit(error = otPlatBleGapAdvStart(&GetInstance(), OT_BLE_ADV_INTERVAL_DEFAULT));
|
||||
|
||||
SuccessOrExit(error = mTls.Open(&BleSecure::HandleTlsReceive, &BleSecure::HandleTlsConnected, this));
|
||||
SuccessOrExit(error = mTls.Open(&BleSecure::HandleTlsReceive, &BleSecure::HandleTlsConnectEvent, this));
|
||||
SuccessOrExit(error = mTls.Bind(HandleTransport, this));
|
||||
|
||||
exit:
|
||||
@@ -321,14 +321,14 @@ Error BleSecure::HandleBleMtuUpdate(uint16_t aMtu)
|
||||
return error;
|
||||
}
|
||||
|
||||
void BleSecure::HandleTlsConnected(void *aContext, bool aConnected)
|
||||
void BleSecure::HandleTlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent, void *aContext)
|
||||
{
|
||||
return static_cast<BleSecure *>(aContext)->HandleTlsConnected(aConnected);
|
||||
return static_cast<BleSecure *>(aContext)->HandleTlsConnectEvent(aEvent);
|
||||
}
|
||||
|
||||
void BleSecure::HandleTlsConnected(bool aConnected)
|
||||
void BleSecure::HandleTlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent)
|
||||
{
|
||||
if (aConnected)
|
||||
if (aEvent == MeshCoP::SecureTransport::kConnected)
|
||||
{
|
||||
if (mReceivedMessage == nullptr)
|
||||
{
|
||||
@@ -358,7 +358,7 @@ void BleSecure::HandleTlsConnected(bool aConnected)
|
||||
}
|
||||
}
|
||||
|
||||
mConnectCallback.InvokeIfSet(&GetInstance(), aConnected, true);
|
||||
mConnectCallback.InvokeIfSet(&GetInstance(), aEvent == MeshCoP::SecureTransport::kConnected, true);
|
||||
|
||||
exit:
|
||||
return;
|
||||
|
||||
@@ -464,8 +464,8 @@ private:
|
||||
static constexpr uint8_t kPacketBufferSize = OT_BLE_ATT_MTU_MAX - kGattOverhead;
|
||||
static constexpr uint16_t kTxBleHandle = 0; // Characteristics Handle for TX (not used)
|
||||
|
||||
static void HandleTlsConnected(void *aContext, bool aConnected);
|
||||
void HandleTlsConnected(bool aConnected);
|
||||
static void HandleTlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent, void *aContext);
|
||||
void HandleTlsConnectEvent(MeshCoP::SecureTransport::ConnectEvent aEvent);
|
||||
|
||||
static void HandleTlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
void HandleTlsReceive(uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
import config
|
||||
import thread_cert
|
||||
|
||||
# Test description:
|
||||
# This test verifies the counters of ephemeral key activations/deactivations.
|
||||
#
|
||||
# Topology:
|
||||
# --------------
|
||||
# |
|
||||
# BR1
|
||||
#
|
||||
|
||||
BR1 = 1
|
||||
|
||||
|
||||
class EphemeralKeyCountersTest(thread_cert.TestCase):
|
||||
USE_MESSAGE_FACTORY = False
|
||||
|
||||
TOPOLOGY = {
|
||||
BR1: {
|
||||
'name': 'BR_1',
|
||||
'is_otbr': True,
|
||||
'version': '1.4',
|
||||
'network_name': 'ot-br1',
|
||||
},
|
||||
}
|
||||
|
||||
def test(self):
|
||||
br1 = self.nodes[BR1]
|
||||
|
||||
counters = br1.get_border_agent_counters()
|
||||
self.assertEqual(counters['epskcActivation'], 0)
|
||||
self.assertEqual(counters['epskcApiDeactivation'], 0)
|
||||
self.assertEqual(counters['epskcTimeoutDeactivation'], 0)
|
||||
self.assertEqual(counters['epskcMaxAttemptDeactivation'], 0)
|
||||
self.assertEqual(counters['epskcDisconnectDeactivation'], 0)
|
||||
self.assertEqual(counters['epskcInvalidBaStateError'], 0)
|
||||
self.assertEqual(counters['epskcInvalidArgsError'], 0)
|
||||
self.assertEqual(counters['epskcStartSecureSessionError'], 0)
|
||||
self.assertEqual(counters['epskcSecureSessionSuccess'], 0)
|
||||
self.assertEqual(counters['epskcSecureSessionFailure'], 0)
|
||||
self.assertEqual(counters['epskcCommissionerPetition'], 0)
|
||||
self.assertEqual(counters['pskcSecureSessionSuccess'], 0)
|
||||
self.assertEqual(counters['pskcSecureSessionFailure'], 0)
|
||||
self.assertEqual(counters['pskcCommissionerPetition'], 0)
|
||||
self.assertEqual(counters['mgmtActiveGet'], 0)
|
||||
self.assertEqual(counters['mgmtPendingGet'], 0)
|
||||
|
||||
# activate epskc before border agent is up returns an error
|
||||
br1.set_epskc('123456789')
|
||||
|
||||
counters = br1.get_border_agent_counters()
|
||||
self.assertEqual(counters['epskcActivation'], 0)
|
||||
self.assertEqual(counters['epskcInvalidBaStateError'], 1)
|
||||
|
||||
br1.set_active_dataset(updateExisting=True, network_name='ot-br1')
|
||||
br1.start()
|
||||
self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY)
|
||||
self.assertEqual('leader', br1.get_state())
|
||||
|
||||
# activate epskc and let it timeout
|
||||
br1.set_epskc('123456789', 10)
|
||||
self.simulator.go(1)
|
||||
|
||||
counters = br1.get_border_agent_counters()
|
||||
self.assertEqual(counters['epskcActivation'], 1)
|
||||
self.assertEqual(counters['epskcApiDeactivation'], 0)
|
||||
self.assertEqual(counters['epskcTimeoutDeactivation'], 1)
|
||||
|
||||
# activate epskc and clear it
|
||||
br1.set_epskc('123456789', 10000)
|
||||
self.simulator.go(1)
|
||||
br1.clear_epskc()
|
||||
|
||||
counters = br1.get_border_agent_counters()
|
||||
self.assertEqual(counters['epskcActivation'], 2)
|
||||
self.assertEqual(counters['epskcApiDeactivation'], 1)
|
||||
self.assertEqual(counters['epskcTimeoutDeactivation'], 1)
|
||||
|
||||
# set epskc with invalid passcode
|
||||
br1.set_epskc('123')
|
||||
self.simulator.go(1)
|
||||
|
||||
counters = br1.get_border_agent_counters()
|
||||
self.assertEqual(counters['epskcActivation'], 2)
|
||||
self.assertEqual(counters['epskcApiDeactivation'], 1)
|
||||
self.assertEqual(counters['epskcTimeoutDeactivation'], 1)
|
||||
self.assertEqual(counters['epskcInvalidArgsError'], 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1451,6 +1451,31 @@ class NodeImpl:
|
||||
self.send_command(cmd)
|
||||
self._expect_done()
|
||||
|
||||
def set_epskc(self, keystring: str, timeout=120000, port=0):
|
||||
cmd = 'ba ephemeralkey set ' + keystring + ' ' + str(timeout) + ' ' + str(port)
|
||||
self.send_command(cmd)
|
||||
self._expect(r"(Done|Error .*)")
|
||||
|
||||
def clear_epskc(self):
|
||||
cmd = 'ba ephemeralkey clear'
|
||||
self.send_command(cmd)
|
||||
self._expect_done()
|
||||
|
||||
def get_border_agent_counters(self):
|
||||
cmd = 'ba counters'
|
||||
self.send_command(cmd)
|
||||
result = self._expect_command_output()
|
||||
|
||||
counters = {}
|
||||
for line in result:
|
||||
m = re.match(r'(\w+)\: (\d+)', line)
|
||||
if m:
|
||||
counter_name = m.group(1)
|
||||
counter_value = m.group(2)
|
||||
|
||||
counters[counter_name] = int(counter_value)
|
||||
return counters
|
||||
|
||||
def _encode_txt_entry(self, entry):
|
||||
"""Encodes the TXT entry to the DNS-SD TXT record format as a HEX string.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user