mirror of
https://github.com/espressif/openthread.git
synced 2026-07-29 07:07:47 +00:00
[border-agent] add epskc journey statistics (#11530)
This commit adds some new statistics for ePSKc to show the time duration of various sub process during the credential sharing. A Nexus unit test is added to verify the stats are counted correctly. A few small points to be noted: * The `StopReason` which was used internally in `EphemeralKeyManager` is renamed as `DeactivationReason`, defined as public and is mapped to the public enum `otHistoryTrackerEpskcDeactivationReason`. * The original reason `Timeout` is renamed to `SessionTimeout` to indicate this is a timeout of the secure session. This is to differentiate with the epskc mode timeout. * A new reason `EpskcTimeout` to indicate the timeout is due to epskc mode timeout.
This commit is contained in:
@@ -76,6 +76,7 @@ typedef enum otCoapSecureConnectEvent
|
||||
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
|
||||
OT_COAP_SECURE_DISCONNECTED_TIMEOUT, ///< Disconnected locally due to session timeout
|
||||
} otCoapSecureConnectEvent;
|
||||
|
||||
/**
|
||||
|
||||
@@ -235,6 +235,26 @@ typedef struct otHistoryTrackerExternalRouteInfo
|
||||
otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed).
|
||||
} otHistoryTrackerExternalRouteInfo;
|
||||
|
||||
/**
|
||||
* Represents events during the Border Agent's ePSKc journey.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED, ///< ePSKc mode is activated.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED, ///< Secure session is connected.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED, ///< Commissioner petition is received.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_ACTIVE_DATASET, ///< Active dataset is retrieved.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_PENDING_DATASET, ///< Pending dataset is retrieved.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_KEEP_ALIVE, ///< Keep alive message is received.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_LOCAL_CLOSE, ///< Deactivated by a call to the API.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_REMOTE_CLOSE, ///< Disconnected by the peer.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_SESSION_ERROR, ///< Disconnected due to some error.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_SESSION_TIMEOUT, ///< Disconnected due to timeout.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_MAX_ATTEMPTS, ///< Max allowed attempts reached.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_EPSKC_TIMEOUT, ///< ePSKc mode timed out.
|
||||
OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_UNKNOWN, ///< Deactivated for an unknown reason.
|
||||
} otHistoryTrackerBorderAgentEpskcEvent;
|
||||
|
||||
/**
|
||||
* Initializes an `otHistoryTrackerIterator`.
|
||||
*
|
||||
@@ -397,6 +417,23 @@ const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHis
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge);
|
||||
|
||||
/**
|
||||
* Iterates over the entries in the Border Agent ePSKc history list.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined.
|
||||
* @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL.
|
||||
* Age is provided as the duration (in milliseconds) from when entry was recorded to
|
||||
* @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
|
||||
* older than max age.
|
||||
*
|
||||
* @returns The `otHistoryTrackerBorderAgentEpskcEvent` entry or `NULL` if no more entries in the list.
|
||||
*/
|
||||
const otHistoryTrackerBorderAgentEpskcEvent *otHistoryTrackerIterateBorderAgentEpskcEventHistory(
|
||||
otInstance *aInstance,
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge);
|
||||
|
||||
/**
|
||||
* Converts a given entry age to a human-readable string.
|
||||
*
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (510)
|
||||
#define OPENTHREAD_API_VERSION (511)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -129,6 +129,19 @@ const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHis
|
||||
*aEntryAge);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
const otHistoryTrackerBorderAgentEpskcEvent *otHistoryTrackerIterateBorderAgentEpskcEventHistory(
|
||||
otInstance *aInstance,
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge)
|
||||
{
|
||||
AssertPointerIsNotNull(aEntryAge);
|
||||
|
||||
return AsCoreType(aInstance).Get<Utils::HistoryTracker>().IterateEpskcEventHistory(AsCoreType(aIterator),
|
||||
*aEntryAge);
|
||||
}
|
||||
#endif
|
||||
|
||||
void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize)
|
||||
{
|
||||
Utils::HistoryTracker::EntryAgeToString(aEntryAge, aBuffer, aSize);
|
||||
|
||||
@@ -160,6 +160,17 @@
|
||||
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_HISTORY_TRACKER_EPSKC_EVENT_SIZE
|
||||
*
|
||||
* Specifies the maximum number of entries in Border Agent ePSKc history list.
|
||||
*
|
||||
* Can be set to zero to configure History Tracker module not to collect any ePSKc journey info.
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_HISTORY_TRACKER_EPSKC_EVENT_SIZE
|
||||
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_EPSKC_EVENT_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -746,6 +746,9 @@ exit:
|
||||
{
|
||||
case kErrorNone:
|
||||
Get<BorderAgent>().mCounters.mEpskcActivations++;
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcActivated);
|
||||
#endif
|
||||
break;
|
||||
case kErrorInvalidState:
|
||||
Get<BorderAgent>().mCounters.mEpskcInvalidBaStateErrors++;
|
||||
@@ -763,7 +766,7 @@ exit:
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::Stop(void) { Stop(kReasonLocalDisconnect); }
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::Stop(StopReason aReason)
|
||||
void BorderAgent::EphemeralKeyManager::Stop(DeactivationReason aReason)
|
||||
{
|
||||
switch (mState)
|
||||
{
|
||||
@@ -776,37 +779,71 @@ void BorderAgent::EphemeralKeyManager::Stop(StopReason aReason)
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
LogInfo("Stopping ephemeral key use - reason: %s", StopReasonToString(aReason));
|
||||
LogInfo("Stopping ephemeral key use - reason: %s", DeactivationReasonToString(aReason));
|
||||
SetState(kStateStopped);
|
||||
|
||||
mTimer.Stop();
|
||||
mDtlsTransport.Close();
|
||||
|
||||
switch (aReason)
|
||||
{
|
||||
case kReasonLocalDisconnect:
|
||||
Get<BorderAgent>().mCounters.mEpskcDeactivationClears++;
|
||||
break;
|
||||
case kReasonPeerDisconnect:
|
||||
Get<BorderAgent>().mCounters.mEpskcDeactivationDisconnects++;
|
||||
break;
|
||||
case kReasonSessionError:
|
||||
Get<BorderAgent>().mCounters.mEpskcStartSecureSessionErrors++;
|
||||
break;
|
||||
case kReasonMaxFailedAttempts:
|
||||
Get<BorderAgent>().mCounters.mEpskcDeactivationMaxAttempts++;
|
||||
break;
|
||||
case kReasonTimeout:
|
||||
Get<BorderAgent>().mCounters.mEpskcDeactivationTimeouts++;
|
||||
break;
|
||||
case kReasonUnknown:
|
||||
break;
|
||||
}
|
||||
UpdateCountersAndRecordEvent(aReason);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::UpdateCountersAndRecordEvent(DeactivationReason aReason)
|
||||
{
|
||||
struct ReasonToCounterEventEntry
|
||||
{
|
||||
DeactivationReason mReason;
|
||||
uint8_t mEvent; // Raw values of `Utils::HistoryTracker::Epskc` enum.
|
||||
uint32_t Counters::*mCounterPtr;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
#define ReasonEntry(kReason, kCounter, kEvent) \
|
||||
{ \
|
||||
kReason, Utils::HistoryTracker::kEvent, &Counters::kCounter, \
|
||||
}
|
||||
#else
|
||||
#define ReasonEntry(kReason, kCounter, kEvent) \
|
||||
{ \
|
||||
kReason, 0, &Counters::kCounter \
|
||||
}
|
||||
#endif
|
||||
|
||||
static const ReasonToCounterEventEntry kReasonToCounterEventEntries[] = {
|
||||
ReasonEntry(kReasonLocalDisconnect, mEpskcDeactivationClears, kEpskcDeactivatedLocalClose),
|
||||
ReasonEntry(kReasonSessionTimeout, mEpskcDeactivationClears, kEpskcDeactivatedSessionTimeout),
|
||||
ReasonEntry(kReasonPeerDisconnect, mEpskcDeactivationDisconnects, kEpskcDeactivatedRemoteClose),
|
||||
ReasonEntry(kReasonSessionError, mEpskcStartSecureSessionErrors, kEpskcDeactivatedSessionError),
|
||||
ReasonEntry(kReasonMaxFailedAttempts, mEpskcDeactivationMaxAttempts, kEpskcDeactivatedMaxAttempts),
|
||||
ReasonEntry(kReasonEpskcTimeout, mEpskcDeactivationTimeouts, kEpskcDeactivatedEpskcTimeout),
|
||||
};
|
||||
|
||||
#undef ReasonEntry
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
Utils::HistoryTracker::EpskcEvent event = Utils::HistoryTracker::kEpskcDeactivatedUnknown;
|
||||
#endif
|
||||
|
||||
for (const ReasonToCounterEventEntry &entry : kReasonToCounterEventEntries)
|
||||
{
|
||||
if (aReason == entry.mReason)
|
||||
{
|
||||
(Get<BorderAgent>().mCounters.*(entry.mCounterPtr))++;
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
event = static_cast<Utils::HistoryTracker::EpskcEvent>(entry.mEvent);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(event);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::SetState(State aState)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
@@ -868,14 +905,16 @@ void BorderAgent::EphemeralKeyManager::HandleSessionConnected(void)
|
||||
{
|
||||
SetState(kStateConnected);
|
||||
Get<BorderAgent>().mCounters.mEpskcSecureSessionSuccesses++;
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcConnected);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::HandleSessionDisconnected(SecureSession::ConnectEvent aEvent)
|
||||
{
|
||||
StopReason reason = kReasonUnknown;
|
||||
DeactivationReason reason = kReasonUnknown;
|
||||
|
||||
// The ephemeral key can be used once
|
||||
|
||||
VerifyOrExit((mState == kStateConnected) || (mState == kStateAccepted));
|
||||
|
||||
switch (aEvent)
|
||||
@@ -889,6 +928,9 @@ void BorderAgent::EphemeralKeyManager::HandleSessionDisconnected(SecureSession::
|
||||
case SecureSession::kDisconnectedMaxAttempts:
|
||||
reason = kReasonMaxFailedAttempts;
|
||||
break;
|
||||
case SecureSession::kDisconnectedTimeout:
|
||||
reason = kReasonSessionTimeout;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -903,9 +945,12 @@ void BorderAgent::EphemeralKeyManager::HandleCommissionerPetitionAccepted(void)
|
||||
{
|
||||
SetState(kStateAccepted);
|
||||
Get<BorderAgent>().mCounters.mEpskcCommissionerPetitions++;
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcPetitioned);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::HandleTimer(void) { Stop(kReasonTimeout); }
|
||||
void BorderAgent::EphemeralKeyManager::HandleTimer(void) { Stop(kReasonEpskcTimeout); }
|
||||
|
||||
void BorderAgent::EphemeralKeyManager::HandleTask(void) { mCallback.InvokeIfSet(); }
|
||||
|
||||
@@ -992,15 +1037,16 @@ const char *BorderAgent::EphemeralKeyManager::StateToString(State aState)
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
|
||||
const char *BorderAgent::EphemeralKeyManager::StopReasonToString(StopReason aReason)
|
||||
const char *BorderAgent::EphemeralKeyManager::DeactivationReasonToString(DeactivationReason aReason)
|
||||
{
|
||||
static const char *const kReasonStrings[] = {
|
||||
"LocalDisconnect", // (0) kReasonLocalDisconnect
|
||||
"PeerDisconnect", // (1) kReasonPeerDisconnect
|
||||
"SessionError", // (2) kReasonSessionError
|
||||
"MaxFailedAttempts", // (3) kReasonMaxFailedAttempts
|
||||
"Timeout", // (4) kReasonTimeout
|
||||
"Unknown", // (5) kReasonUnknown
|
||||
"SessionTimeout", // (3) kReasonSessionTimeout
|
||||
"MaxFailedAttempts", // (4) kReasonMaxFailedAttempts
|
||||
"EpskcTimeout", // (5) kReasonTimeout
|
||||
"Unknown", // (6) kReasonUnknown
|
||||
};
|
||||
|
||||
struct EnumCheck
|
||||
@@ -1009,8 +1055,9 @@ const char *BorderAgent::EphemeralKeyManager::StopReasonToString(StopReason aRea
|
||||
ValidateNextEnum(kReasonLocalDisconnect);
|
||||
ValidateNextEnum(kReasonPeerDisconnect);
|
||||
ValidateNextEnum(kReasonSessionError);
|
||||
ValidateNextEnum(kReasonSessionTimeout);
|
||||
ValidateNextEnum(kReasonMaxFailedAttempts);
|
||||
ValidateNextEnum(kReasonTimeout);
|
||||
ValidateNextEnum(kReasonEpskcTimeout);
|
||||
ValidateNextEnum(kReasonUnknown);
|
||||
};
|
||||
|
||||
@@ -1124,6 +1171,12 @@ void BorderAgent::CoapDtlsSession::HandleTmfCommissionerKeepAlive(Coap::Message
|
||||
VerifyOrExit(mIsActiveCommissioner);
|
||||
SuccessOrExit(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderKeepAlive));
|
||||
mTimer.Start(kKeepAliveTimeout);
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE && OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
if (Get<EphemeralKeyManager>().OwnsSession(*this))
|
||||
{
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcKeepAlive);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -1454,11 +1507,23 @@ void BorderAgent::CoapDtlsSession::HandleTmfDatasetGet(Coap::Message &aMessage,
|
||||
case kUriActiveGet:
|
||||
response = Get<ActiveDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
|
||||
Get<BorderAgent>().mCounters.mMgmtActiveGets++;
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE && OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
if (Get<EphemeralKeyManager>().OwnsSession(*this))
|
||||
{
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcRetrievedActiveDataset);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case kUriPendingGet:
|
||||
response = Get<PendingDatasetManager>().ProcessGetRequest(aMessage, DatasetManager::kIgnoreSecurityPolicyFlags);
|
||||
Get<BorderAgent>().mCounters.mMgmtPendingGets++;
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE && OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
if (Get<EphemeralKeyManager>().OwnsSession(*this))
|
||||
{
|
||||
Get<Utils::HistoryTracker>().RecordEpskcEvent(Utils::HistoryTracker::kEpskcRetrievedPendingDataset);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case kUriCommissionerGet:
|
||||
@@ -1490,7 +1555,7 @@ void BorderAgent::CoapDtlsSession::HandleTimer(void)
|
||||
if (IsConnected())
|
||||
{
|
||||
LogInfo("Session timed out - disconnecting");
|
||||
Disconnect();
|
||||
DisconnectTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
#include <openthread/border_agent.h>
|
||||
#include <openthread/history_tracker.h>
|
||||
|
||||
#include "border_router/routing_manager.hpp"
|
||||
#include "common/appender.hpp"
|
||||
@@ -389,26 +390,28 @@ public:
|
||||
|
||||
static_assert(kMaxKeyLength <= Dtls::Transport::kPskMaxLength, "Max e-key len is larger than max PSK len");
|
||||
|
||||
enum StopReason : uint8_t
|
||||
enum DeactivationReason : uint8_t
|
||||
{
|
||||
kReasonLocalDisconnect,
|
||||
kReasonPeerDisconnect,
|
||||
kReasonSessionError,
|
||||
kReasonSessionTimeout,
|
||||
kReasonMaxFailedAttempts,
|
||||
kReasonTimeout,
|
||||
kReasonEpskcTimeout,
|
||||
kReasonUnknown,
|
||||
};
|
||||
|
||||
explicit EphemeralKeyManager(Instance &aInstance);
|
||||
|
||||
void SetState(State aState);
|
||||
void Stop(StopReason aReason);
|
||||
void Stop(DeactivationReason aReason);
|
||||
void HandleTimer(void);
|
||||
void HandleTask(void);
|
||||
bool OwnsSession(CoapDtlsSession &aSession) const { return mCoapDtlsSession == &aSession; }
|
||||
void HandleSessionConnected(void);
|
||||
void HandleSessionDisconnected(SecureSession::ConnectEvent aEvent);
|
||||
void HandleCommissionerPetitionAccepted(void);
|
||||
void UpdateCountersAndRecordEvent(DeactivationReason aReason);
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
bool ShouldRegisterService(void) const;
|
||||
void RegisterOrUnregisterService(void);
|
||||
@@ -423,7 +426,7 @@ public:
|
||||
void HandleTransportClosed(void);
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
static const char *StopReasonToString(StopReason aReason);
|
||||
static const char *DeactivationReasonToString(DeactivationReason aReason);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE
|
||||
|
||||
@@ -118,6 +118,7 @@ public:
|
||||
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 ConnectEvent kDisconnectedTimeout = OT_COAP_SECURE_DISCONNECTED_TIMEOUT;
|
||||
|
||||
/**
|
||||
* Function pointer which is called reporting a session connection event.
|
||||
@@ -176,6 +177,11 @@ public:
|
||||
*/
|
||||
void Disconnect(void) { Disconnect(kDisconnectedLocalClosed); }
|
||||
|
||||
/**
|
||||
* Disconnects the session due to timeout.
|
||||
*/
|
||||
void DisconnectTimeout(void) { Disconnect(kDisconnectedTimeout); }
|
||||
|
||||
/**
|
||||
* Sends message to the secure session.
|
||||
*
|
||||
|
||||
@@ -425,6 +425,19 @@ exit:
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
void HistoryTracker::RecordEpskcEvent(EpskcEvent aEvent)
|
||||
{
|
||||
EpskcEvent *entry = mEpskcEventHistory.AddNewEntry();
|
||||
|
||||
VerifyOrExit(entry != nullptr);
|
||||
*entry = aEvent;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void HistoryTracker::HandleNotifierEvents(Events aEvents)
|
||||
{
|
||||
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadRlocAdded | kEventThreadRlocRemoved |
|
||||
@@ -451,7 +464,9 @@ void HistoryTracker::HandleTimer(void)
|
||||
mNeighborHistory.UpdateAgedEntries();
|
||||
mOnMeshPrefixHistory.UpdateAgedEntries();
|
||||
mExternalRouteHistory.UpdateAgedEntries();
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
mEpskcEventHistory.UpdateAgedEntries();
|
||||
#endif
|
||||
mTimer.Start(kAgeCheckPeriod);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "meshcop/border_agent.hpp"
|
||||
#include "net/netif.hpp"
|
||||
#include "net/socket.hpp"
|
||||
#include "thread/mesh_forwarder.hpp"
|
||||
@@ -57,6 +58,7 @@
|
||||
#include "thread/router_table.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace Utils {
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||
@@ -81,6 +83,10 @@ class HistoryTracker : public InstanceLocator, private NonCopyable
|
||||
#if OPENTHREAD_FTD
|
||||
friend class ot::RouterTable;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
friend class ot::MeshCoP::BorderAgent;
|
||||
friend class ot::MeshCoP::BorderAgent::EphemeralKeyManager;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -134,6 +140,9 @@ public:
|
||||
typedef otHistoryTrackerRouterInfo RouterInfo; ///< Router info.
|
||||
typedef otHistoryTrackerOnMeshPrefixInfo OnMeshPrefixInfo; ///< Network Data on mesh prefix info.
|
||||
typedef otHistoryTrackerExternalRouteInfo ExternalRouteInfo; ///< Network Data external route info
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
typedef otHistoryTrackerBorderAgentEpskcEvent EpskcEvent; ///< Border Agent ePSKc Event.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes the `HistoryTracker`.
|
||||
@@ -242,6 +251,13 @@ public:
|
||||
return mExternalRouteHistory.Iterate(aIterator, aEntryAge);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
const EpskcEvent *IterateEpskcEventHistory(Iterator &aIterator, uint32_t &aEntryAge) const
|
||||
{
|
||||
return mEpskcEventHistory.Iterate(aIterator, aEntryAge);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts a given entry age to a human-readable string.
|
||||
*
|
||||
@@ -273,6 +289,7 @@ private:
|
||||
static constexpr uint16_t kRouterListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_ROUTER_LIST_SIZE;
|
||||
static constexpr uint16_t kOnMeshPrefixListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE;
|
||||
static constexpr uint16_t kExternalRouteListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE;
|
||||
static constexpr uint16_t kEpskcEventListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_EPSKC_EVENT_SIZE;
|
||||
|
||||
typedef otHistoryTrackerAddressEvent AddressEvent;
|
||||
|
||||
@@ -300,6 +317,27 @@ private:
|
||||
static constexpr NetDataEvent kNetDataEntryAdded = OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED;
|
||||
static constexpr NetDataEvent kNetDataEntryRemoved = OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
#define DefineEpskcEvent(aName, aPublicEnumName) \
|
||||
static constexpr EpskcEvent kEpskc##aName = OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_##aPublicEnumName
|
||||
|
||||
DefineEpskcEvent(Activated, ACTIVATED);
|
||||
DefineEpskcEvent(Connected, CONNECTED);
|
||||
DefineEpskcEvent(Petitioned, PETITIONED);
|
||||
DefineEpskcEvent(RetrievedActiveDataset, RETRIEVED_ACTIVE_DATASET);
|
||||
DefineEpskcEvent(RetrievedPendingDataset, RETRIEVED_PENDING_DATASET);
|
||||
DefineEpskcEvent(KeepAlive, KEEP_ALIVE);
|
||||
DefineEpskcEvent(DeactivatedLocalClose, DEACTIVATED_LOCAL_CLOSE);
|
||||
DefineEpskcEvent(DeactivatedRemoteClose, DEACTIVATED_REMOTE_CLOSE);
|
||||
DefineEpskcEvent(DeactivatedSessionError, DEACTIVATED_SESSION_ERROR);
|
||||
DefineEpskcEvent(DeactivatedSessionTimeout, DEACTIVATED_SESSION_TIMEOUT);
|
||||
DefineEpskcEvent(DeactivatedMaxAttempts, DEACTIVATED_MAX_ATTEMPTS);
|
||||
DefineEpskcEvent(DeactivatedEpskcTimeout, DEACTIVATED_EPSKC_TIMEOUT);
|
||||
DefineEpskcEvent(DeactivatedUnknown, DEACTIVATED_UNKNOWN);
|
||||
|
||||
#undef DefineEpskcEvent
|
||||
#endif
|
||||
|
||||
class Timestamp
|
||||
{
|
||||
public:
|
||||
@@ -408,6 +446,9 @@ private:
|
||||
void RecordOnMeshPrefixEvent(NetDataEvent aEvent, const NetworkData::OnMeshPrefixConfig &aPrefix);
|
||||
void RecordExternalRouteEvent(NetDataEvent aEvent, const NetworkData::ExternalRouteConfig &aRoute);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
void RecordEpskcEvent(EpskcEvent aEvent);
|
||||
#endif
|
||||
|
||||
using TrackerTimer = TimerMilliIn<HistoryTracker, &HistoryTracker::HandleTimer>;
|
||||
|
||||
@@ -420,6 +461,9 @@ private:
|
||||
EntryList<RouterInfo, kRouterListSize> mRouterHistory;
|
||||
EntryList<OnMeshPrefixInfo, kOnMeshPrefixListSize> mOnMeshPrefixHistory;
|
||||
EntryList<ExternalRouteInfo, kExternalRouteListSize> mExternalRouteHistory;
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
EntryList<EpskcEvent, kEpskcEventListSize> mEpskcEventHistory;
|
||||
#endif
|
||||
|
||||
TrackerTimer mTimer;
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ namespace Nexus {
|
||||
|
||||
using ActiveDatasetManager = MeshCoP::ActiveDatasetManager;
|
||||
using BorderAgent = MeshCoP::BorderAgent;
|
||||
using EphemeralKeyManager = ot::MeshCoP::BorderAgent::EphemeralKeyManager;
|
||||
using EphemeralKeyManager = MeshCoP::BorderAgent::EphemeralKeyManager;
|
||||
using HistoryTracker = Utils::HistoryTracker;
|
||||
using EpskcEvent = HistoryTracker::EpskcEvent;
|
||||
using Iterator = HistoryTracker::Iterator;
|
||||
using ExtendedPanIdManager = MeshCoP::ExtendedPanIdManager;
|
||||
using NameData = MeshCoP::NameData;
|
||||
using NetworkNameManager = MeshCoP::NetworkNameManager;
|
||||
@@ -754,6 +757,357 @@ void TestBorderAgentEphemeralKey(void)
|
||||
VerifyOrQuit(node0.Get<BorderAgent>().GetCounters().mEpskcInvalidArgsErrors == 2);
|
||||
}
|
||||
|
||||
EpskcEvent GetNewestEpskcEvent(Node &aNode)
|
||||
{
|
||||
const EpskcEvent *epskcEvent = nullptr;
|
||||
Iterator iter;
|
||||
uint32_t age;
|
||||
iter.Init();
|
||||
|
||||
epskcEvent = aNode.Get<HistoryTracker>().IterateEpskcEventHistory(iter, age);
|
||||
|
||||
VerifyOrQuit(epskcEvent != nullptr);
|
||||
return *epskcEvent;
|
||||
}
|
||||
|
||||
void TestHistoryTrackerBorderAgentEpskcEvent(void)
|
||||
{
|
||||
static const char kEphemeralKey[] = "nexus1234";
|
||||
|
||||
static constexpr uint16_t kEphemeralKeySize = sizeof(kEphemeralKey) - 1;
|
||||
static constexpr uint16_t kUdpPort = 49155;
|
||||
|
||||
Core nexus;
|
||||
Node &node0 = nexus.CreateNode();
|
||||
Node &node1 = nexus.CreateNode();
|
||||
Ip6::SockAddr sockAddr;
|
||||
Coap::Message *message;
|
||||
EpskcEvent epskcEvent;
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log("TestHistoryTrackerBorderAgentEpskcEvent");
|
||||
|
||||
nexus.AdvanceTime(0);
|
||||
|
||||
// Form the topology:
|
||||
// - node0 leader acting as Border Agent.
|
||||
// - node1 acting as candidate
|
||||
|
||||
node0.Form();
|
||||
nexus.AdvanceTime(50 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node0.Get<Mle::Mle>().IsLeader());
|
||||
sockAddr.SetAddress(node0.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
sockAddr.SetPort(kUdpPort);
|
||||
|
||||
SuccessOrQuit(node1.Get<Mac::Mac>().SetPanChannel(node0.Get<Mac::Mac>().GetPanChannel()));
|
||||
node1.Get<Mac::Mac>().SetPanId(node0.Get<Mac::Mac>().GetPanId());
|
||||
node1.Get<ThreadNetif>().Up();
|
||||
|
||||
// Enable the Ephemeral Key feature.
|
||||
node0.Get<EphemeralKeyManager>().SetEnabled(true);
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStopped);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 1: Epskc Mode is activated, then deactivated");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
node0.Get<EphemeralKeyManager>().Stop();
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_LOCAL_CLOSE);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 2: Epskc Mode is activated, then deactivated after max failed connection "
|
||||
"attempts");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
SuccessOrQuit(node0.Get<Ip6::Filter>().AddUnsecurePort(kUdpPort));
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
nexus.AdvanceTime(0);
|
||||
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Open());
|
||||
SuccessOrQuit(
|
||||
node1.Get<Tmf::SecureAgent>().SetPsk(reinterpret_cast<const uint8_t *>(kEphemeralKey), kEphemeralKeySize - 2));
|
||||
|
||||
for (uint8_t numAttempts = 1; numAttempts < 10; numAttempts++)
|
||||
{
|
||||
Log(" Attempt %u to connect with the wrong key", numAttempts);
|
||||
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
}
|
||||
|
||||
Log(" Attempt 10 (final attempt) to connect with the wrong key, check that ephemeral key use is stopped");
|
||||
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStopped);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_MAX_ATTEMPTS);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 3: The session is connected successfully, then disconnected by API");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
SuccessOrQuit(
|
||||
node1.Get<Tmf::SecureAgent>().SetPsk(reinterpret_cast<const uint8_t *>(kEphemeralKey), kEphemeralKeySize));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
node0.Get<EphemeralKeyManager>().Stop();
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_LOCAL_CLOSE);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 4: The session is connected successfully. And the candidate petitioned as an "
|
||||
"active commissioner. The session is disconnected by the remote.");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerPetition);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED);
|
||||
|
||||
node1.Get<Tmf::SecureAgent>().Disconnect();
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_REMOTE_CLOSE);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 5: The session is connected successfully. And the active dataset is fetched. "
|
||||
"The session is disconnected by the remote.");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerPetition);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriActiveGet);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_ACTIVE_DATASET);
|
||||
|
||||
node1.Get<Tmf::SecureAgent>().Disconnect();
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_REMOTE_CLOSE);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 6: The session is connected successfully. And the pending dataset is fetched. "
|
||||
"The session is disconnected by the remote.");
|
||||
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerPetition);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriActiveGet);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_ACTIVE_DATASET);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriPendingGet);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_PENDING_DATASET);
|
||||
|
||||
node1.Get<Tmf::SecureAgent>().Disconnect();
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_REMOTE_CLOSE);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 7: The session is connected successfully. And the pending dataset is fetched. "
|
||||
"The session is due to session timeout.");
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerPetition);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriActiveGet);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_ACTIVE_DATASET);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriPendingGet);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_RETRIEVED_PENDING_DATASET);
|
||||
|
||||
static constexpr uint32_t kKeepAliveTimeout = 50 * 1000; // Timeout to reject a commissioner (in msec)
|
||||
nexus.AdvanceTime(kKeepAliveTimeout); // Wait for the session timeout
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_SESSION_TIMEOUT);
|
||||
|
||||
Log("------------------------------------------------------------------------------------------------------");
|
||||
Log(" Check Ephemeral Key Journey 8: The session is connected successfully. The epskc mode is deactivated due to "
|
||||
"timeout.");
|
||||
SuccessOrQuit(node0.Get<EphemeralKeyManager>().Start(kEphemeralKey, /* aTimeout */ 0, kUdpPort));
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStarted);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_ACTIVATED);
|
||||
|
||||
VerifyOrQuit(!node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().Connect(sockAddr));
|
||||
|
||||
nexus.AdvanceTime(3 * Time::kOneSecondInMsec);
|
||||
VerifyOrQuit(node1.Get<Tmf::SecureAgent>().IsConnected());
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_CONNECTED);
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerPetition);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
nexus.AdvanceTime(1 * Time::kOneSecondInMsec);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_PETITIONED);
|
||||
|
||||
// Send a KeepAlive message every 30s until ePSKc mode timed out
|
||||
for (uint8_t i = 0; i < EphemeralKeyManager::kDefaultTimeout / (30 * Time::kOneSecondInMsec) - 1; i++)
|
||||
{
|
||||
if (!node1.Get<Tmf::SecureAgent>().IsConnected())
|
||||
{
|
||||
break;
|
||||
}
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerKeepAlive);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::StateTlv>(*message, MeshCoP::StateTlv::kAccept));
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
nexus.AdvanceTime(30 * Time::kOneSecondInMsec);
|
||||
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_KEEP_ALIVE);
|
||||
}
|
||||
|
||||
message = node1.Get<Tmf::SecureAgent>().NewPriorityConfirmablePostMessage(kUriCommissionerKeepAlive);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::StateTlv>(*message, MeshCoP::StateTlv::kAccept));
|
||||
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerIdTlv>(*message, "node1"));
|
||||
SuccessOrQuit(node1.Get<Tmf::SecureAgent>().SendMessage(*message));
|
||||
nexus.AdvanceTime(30 * Time::kOneSecondInMsec);
|
||||
|
||||
VerifyOrQuit(node0.Get<EphemeralKeyManager>().GetState() == EphemeralKeyManager::kStateStopped);
|
||||
epskcEvent = GetNewestEpskcEvent(node0);
|
||||
VerifyOrQuit(epskcEvent == OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_DEACTIVATED_EPSKC_TIMEOUT);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct TxtData
|
||||
@@ -1547,6 +1901,7 @@ int main(void)
|
||||
{
|
||||
ot::Nexus::TestBorderAgent();
|
||||
ot::Nexus::TestBorderAgentEphemeralKey();
|
||||
ot::Nexus::TestHistoryTrackerBorderAgentEpskcEvent();
|
||||
ot::Nexus::TestBorderAgentTxtDataCallback();
|
||||
ot::Nexus::TestBorderAgentServiceRegistration();
|
||||
printf("All tests passed\n");
|
||||
|
||||
Reference in New Issue
Block a user