[core] remove legacy P2P and wake-up implementations (#13598)

The Peer-to-Peer (P2P) and Wake-up (Wake-up End Device / Wake-up
Initiator / Wake-up Listener) features were originally introduced in
OpenThread as experimental prototypes prior to the finalization of the
Thread Direct specification. As the Thread Direct design has since
evolved significantly, this legacy code is obsolete and no longer
compliant with the spec.

This commit removes the legacy implementations to make room for a clean
implementation of Thread Direct. The focus of this PR is strictly on
the core modules (`src/core/`), removing the internal implementations
while keeping external interfaces in place.

Public APIs (`otP2p*`, `otThreadWakeup`, and `otLink*Wakeup*`), existing
configurations, and CLI/NCP interfaces remain unchanged, with the
underlying API functions returning `OT_ERROR_NOT_IMPLEMENTED` (or
empty/false).
This commit is contained in:
Abtin Keshavarzian
2026-09-11 13:05:33 -07:00
committed by GitHub
parent 1322ebd0b4
commit 3476afa2ec
34 changed files with 45 additions and 2545 deletions
+1 -5
View File
@@ -366,11 +366,7 @@ otError otMacFrameProcessTransmitSecurity(otRadioFrame *aFrame, otRadioContext *
uint32_t frameCounter;
bool processKeyId;
processKeyId =
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
otMacFrameIsKeyIdMode2(aFrame) ||
#endif
otMacFrameIsKeyIdMode1(aFrame);
processKeyId = otMacFrameIsKeyIdMode1(aFrame);
VerifyOrExit(otMacFrameIsSecurityEnabled(aFrame) && processKeyId && !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
+1
View File
@@ -55,6 +55,7 @@
#include <openthread/thread.h>
#include <openthread/thread_ftd.h>
#include <openthread/udp.h>
#include <openthread/provisional/p2p.h>
#include "cli/cli_ba.hpp"
#include "cli/cli_bbr.hpp"
-9
View File
@@ -548,9 +548,6 @@ openthread_core_files = [
"mac/sub_mac.hpp",
"mac/sub_mac_callbacks.cpp",
"mac/sub_mac_csl_receiver.cpp",
"mac/sub_mac_wed.cpp",
"mac/wakeup_tx_scheduler.cpp",
"mac/wakeup_tx_scheduler.hpp",
"meshcop/border_agent.cpp",
"meshcop/border_agent.hpp",
"meshcop/border_agent_admitter.cpp",
@@ -725,7 +722,6 @@ openthread_core_files = [
"thread/mle.cpp",
"thread/mle.hpp",
"thread/mle_ftd.cpp",
"thread/mle_p2p.cpp",
"thread/mle_tlvs.cpp",
"thread/mle_tlvs.hpp",
"thread/mle_types.cpp",
@@ -763,10 +759,6 @@ openthread_core_files = [
"thread/network_data_types.hpp",
"thread/panid_query_server.cpp",
"thread/panid_query_server.hpp",
"thread/peer.cpp",
"thread/peer.hpp",
"thread/peer_table.cpp",
"thread/peer_table.hpp",
"thread/radio_selector.cpp",
"thread/radio_selector.hpp",
"thread/router.cpp",
@@ -863,7 +855,6 @@ openthread_radio_sources = [
"mac/sub_mac.cpp",
"mac/sub_mac_callbacks.cpp",
"mac/sub_mac_csl_receiver.cpp",
"mac/sub_mac_wed.cpp",
"radio/radio.cpp",
"radio/radio_callbacks.cpp",
"radio/radio_frame.cpp",
-6
View File
@@ -165,8 +165,6 @@ set(COMMON_SOURCES
mac/sub_mac.cpp
mac/sub_mac_callbacks.cpp
mac/sub_mac_csl_receiver.cpp
mac/sub_mac_wed.cpp
mac/wakeup_tx_scheduler.cpp
meshcop/border_agent.cpp
meshcop/border_agent_admitter.cpp
meshcop/border_agent_ephemeral_key.cpp
@@ -255,7 +253,6 @@ set(COMMON_SOURCES
thread/message_framer.cpp
thread/mle.cpp
thread/mle_ftd.cpp
thread/mle_p2p.cpp
thread/mle_tlvs.cpp
thread/mle_types.cpp
thread/mlr_manager.cpp
@@ -275,8 +272,6 @@ set(COMMON_SOURCES
thread/network_data_tlvs.cpp
thread/network_data_types.cpp
thread/panid_query_server.cpp
thread/peer.cpp
thread/peer_table.cpp
thread/radio_selector.cpp
thread/router.cpp
thread/router_table.cpp
@@ -340,7 +335,6 @@ set(RADIO_COMMON_SOURCES
mac/sub_mac.cpp
mac/sub_mac_callbacks.cpp
mac/sub_mac_csl_receiver.cpp
mac/sub_mac_wed.cpp
radio/radio.cpp
radio/radio_callbacks.cpp
radio/radio_frame.cpp
+7 -33
View File
@@ -85,22 +85,8 @@ uint8_t otLinkGetWakeupChannel(otInstance *aInstance)
return AsCoreType(aInstance).Get<Mac::Mac>().GetWakeupChannel();
}
otError otLinkSetWakeupChannel(otInstance *aInstance, uint8_t aChannel)
{
Error error = kErrorNone;
Instance &instance = AsCoreType(aInstance);
VerifyOrExit(instance.Get<Mle::Mle>().IsDisabled(), error = kErrorInvalidState);
SuccessOrExit(error = instance.Get<Mac::Mac>().SetWakeupChannel(aChannel));
instance.Get<MeshCoP::ActiveDatasetManager>().Clear();
instance.Get<MeshCoP::PendingDatasetManager>().Clear();
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
otError otLinkSetWakeupChannel(otInstance *, uint8_t) { return kErrorNotImplemented; }
#endif
uint32_t otLinkGetSupportedChannelMask(otInstance *aInstance)
{
@@ -502,23 +488,11 @@ otError otLinkGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
}
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
otError otLinkSetWakeUpListenEnabled(otInstance *aInstance, bool aEnable)
{
return AsCoreType(aInstance).Get<Mac::Mac>().SetWakeupListenEnabled(aEnable);
}
otError otLinkSetWakeUpListenEnabled(otInstance *, bool) { return kErrorNotImplemented; }
bool otLinkIsWakeupListenEnabled(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<Mac::Mac>().IsWakeupListenEnabled();
}
bool otLinkIsWakeupListenEnabled(otInstance *) { return false; }
void otLinkGetWakeupListenParameters(otInstance *aInstance, uint32_t *aInterval, uint32_t *aDuration)
{
AsCoreType(aInstance).Get<Mac::Mac>().GetWakeupListenParameters(*aInterval, *aDuration);
}
void otLinkGetWakeupListenParameters(otInstance *, uint32_t *, uint32_t *) {}
otError otLinkSetWakeupListenParameters(otInstance *aInstance, uint32_t aInterval, uint32_t aDuration)
{
return AsCoreType(aInstance).Get<Mac::Mac>().SetWakeupListenParameters(aInterval, aDuration);
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
otError otLinkSetWakeupListenParameters(otInstance *, uint32_t, uint32_t) { return kErrorNotImplemented; }
#endif
+9 -15
View File
@@ -35,30 +35,24 @@
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include <openthread/provisional/p2p.h>
#include "instance/instance.hpp"
using namespace ot;
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
otError otP2pWakeupAndLink(otInstance *aInstance,
const otP2pRequest *aP2pRequest,
otP2pLinkDoneCallback aCallback,
void *aContext)
otError otP2pWakeupAndLink(otInstance *, const otP2pRequest *, otP2pLinkDoneCallback, void *)
{
return AsCoreType(aInstance).Get<Mle::Mle>().P2pWakeupAndLink(AsCoreType(aP2pRequest), aCallback, aContext);
return kErrorNotImplemented;
}
#endif
void otP2pSetEventCallback(otInstance *aInstance, otP2pEventCallback aCallback, void *aContext)
void otP2pSetEventCallback(otInstance *, otP2pEventCallback, void *) {}
otError otP2pUnlink(otInstance *, const otExtAddress *, otP2pUnlinkDoneCallback, void *)
{
AsCoreType(aInstance).Get<Mle::Mle>().P2pSetEventCallback(aCallback, aContext);
return kErrorNotImplemented;
}
otError otP2pUnlink(otInstance *aInstance,
const otExtAddress *aExtAddress,
otP2pUnlinkDoneCallback aCallback,
void *aContext)
{
return AsCoreType(aInstance).Get<Mle::Mle>().P2pUnlink(AsCoreType(aExtAddress), aCallback, aContext);
}
#endif
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
+2 -8
View File
@@ -484,15 +484,9 @@ uint32_t otThreadGetStoreFrameCounterAhead(otInstance *aInstance)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
otError otThreadWakeup(otInstance *aInstance,
const otExtAddress *aWedAddress,
uint16_t aWakeupIntervalUs,
uint16_t aWakeupDurationMs,
otWakeupCallback aCallback,
void *aCallbackContext)
otError otThreadWakeup(otInstance *, const otExtAddress *, uint16_t, uint16_t, otWakeupCallback, void *)
{
return AsCoreType(aInstance).Get<Mle::Mle>().Wakeup(AsCoreType(aWedAddress), aWakeupIntervalUs, aWakeupDurationMs,
aCallback, aCallbackContext);
return kErrorNotImplemented;
}
#endif
-9
View File
@@ -89,7 +89,6 @@
#include "crypto/mbedtls.hpp"
#include "crypto/storage.hpp"
#include "mac/mac.hpp"
#include "mac/wakeup_tx_scheduler.hpp"
#include "meshcop/border_agent.hpp"
#include "meshcop/border_agent_admitter.hpp"
#include "meshcop/border_agent_ephemeral_key.hpp"
@@ -970,14 +969,6 @@ template <> inline ChildTable &Instance::Get(void) { return mMle.mChildTable; }
template <> inline RouterTable &Instance::Get(void) { return mMle.mRouterTable; }
#endif
#if OPENTHREAD_CONFIG_P2P_ENABLE
template <> inline PeerTable &Instance::Get(void) { return mMle.mP2p.mPeerTable; }
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
template <> inline WakeupTxScheduler &Instance::Get(void) { return mMle.mWakeupTxScheduler; }
#endif
template <> inline Ip6::Netif &Instance::Get(void) { return mThreadNetif; }
template <> inline ThreadNetif &Instance::Get(void) { return mThreadNetif; }
+1 -141
View File
@@ -65,9 +65,6 @@ Mac::Mac(Instance &aInstance)
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
, mShouldDelaySleep(false)
, mDelayingSleep(false)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
, mWakeupListenEnabled(false)
#endif
, mOperation(kOperationIdle)
, mPendingOperations(0)
@@ -91,10 +88,6 @@ Mac::Mac(Instance &aInstance)
, mCslPeriod(0)
#endif
, mWakeupChannel(OPENTHREAD_CONFIG_DEFAULT_WAKEUP_CHANNEL)
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
, mWakeupListenInterval(kDefaultWedListenInterval)
, mWakeupListenDuration(kDefaultWedListenDuration)
#endif
, mActiveScanCallback()
, mLinks(aInstance)
, mOperationTask(aInstance)
@@ -229,9 +222,6 @@ bool Mac::IsInTransmitState(void) const
#endif
case kOperationTransmitBeacon:
case kOperationTransmitPoll:
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kOperationTransmitWakeup:
#endif
retval = true;
break;
@@ -508,17 +498,6 @@ exit:
}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
void Mac::RequestWakeupFrameTransmission(void)
{
VerifyOrExit(IsEnabled());
StartOperation(kOperationTransmitWakeup);
exit:
return;
}
#endif
Error Mac::RequestDataPollTransmission(void)
{
Error error = kErrorNone;
@@ -613,9 +592,6 @@ void Mac::PerformNextOperation(void)
// remains in receive mode after a data poll ACK indicating a
// pending frame from the parent.
kOperationWaitingForData,
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
kOperationTransmitWakeup,
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
kOperationTransmitDataCsl,
#endif
@@ -690,9 +666,6 @@ void Mac::PerformNextOperation(void)
case kOperationTransmitDataCsl:
#endif
case kOperationTransmitPoll:
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kOperationTransmitWakeup:
#endif
BeginTransmit();
break;
@@ -990,16 +963,6 @@ void Mac::BeginTransmit(void)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kOperationTransmitWakeup:
frame = Get<WakeupTxScheduler>().PrepareWakeupFrame(txFrames);
VerifyOrExit(frame != nullptr);
frame->SetChannel(mWakeupChannel);
frame->SetRxChannelAfterTxDone(mRadioChannel);
shouldWriteSeqNum = false;
break;
#endif
default:
OT_ASSERT(false);
}
@@ -1537,13 +1500,6 @@ void Mac::HandleTransmitDone(TxFrame::ParseInfo &aFrameInfo, RxFrame *aAckFrame,
break;
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kOperationTransmitWakeup:
FinishOperation();
PerformNextOperation();
break;
#endif
default:
OT_ASSERT(false);
}
@@ -2318,7 +2274,7 @@ const char *Mac::OperationToString(Operation aOperation)
_(kOperationTransmitDataDirect, "TransmitDataDirect") \
_(kOperationTransmitPoll, "TransmitPoll") \
_(kOperationWaitingForData, "WaitingForData") \
FtdOperationMapList(_) CslTxOperationMapList(_) WakeupOperationMapList(_)
FtdOperationMapList(_) CslTxOperationMapList(_)
#if OPENTHREAD_FTD
#define FtdOperationMapList(_) _(kOperationTransmitDataIndirect, "TransmitDataIndirect")
@@ -2330,12 +2286,6 @@ const char *Mac::OperationToString(Operation aOperation)
#define CslTxOperationMapList(_) _(kOperationTransmitDataCsl, "TransmitDataCsl")
#else
#define CslTxOperationMapList(_)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#define WakeupOperationMapList(_) _(kOperationTransmitWakeup, "TransmitWakeup")
#else
#define WakeupOperationMapList(_)
#endif
DefineEnumStringArray(OperationMapList);
@@ -2464,14 +2414,6 @@ void Mac::SetCslPeriod(uint16_t aPeriod)
VerifyOrExit(mCslPeriod != aPeriod);
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
if (IsWakeupListenEnabled() && aPeriod != 0)
{
IgnoreError(SetWakeupListenEnabled(false));
LogWarn("Disabling wake-up frame listening due to CSL period change");
}
#endif
// A CSL period value of 0 means that the CSL is disabled.
shouldUpdateCslState = ((mCslPeriod == 0) != (aPeriod == 0));
mCslPeriod = aPeriod;
@@ -2618,87 +2560,5 @@ void Mac::SetRadioFilterEnabled(bool aFilterEnabled)
}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
Error Mac::SetWakeupChannel(uint8_t aChannel)
{
Error error = kErrorNone;
if (aChannel == 0)
{
mWakeupChannel = GetPanChannel();
ExitNow();
}
VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = kErrorInvalidArgs);
mWakeupChannel = aChannel;
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
UpdateWakeupListening();
#endif
exit:
return error;
}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void Mac::GetWakeupListenParameters(uint32_t &aInterval, uint32_t &aDuration) const
{
aInterval = mWakeupListenInterval;
aDuration = mWakeupListenDuration;
}
Error Mac::SetWakeupListenParameters(uint32_t aInterval, uint32_t aDuration)
{
Error error = kErrorNone;
VerifyOrExit(aDuration >= Radio::kMinWakeupListenDuration, error = kErrorInvalidArgs);
VerifyOrExit(aInterval > aDuration, error = kErrorInvalidArgs);
mWakeupListenInterval = aInterval;
mWakeupListenDuration = aDuration;
UpdateWakeupListening();
exit:
return error;
}
Error Mac::SetWakeupListenEnabled(bool aEnable)
{
Error error = kErrorNone;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (aEnable && GetCslPeriod() > 0)
{
LogWarn("Cannot enable wake-up frame listening while CSL is enabled");
ExitNow(error = kErrorInvalidState);
}
#endif
if (aEnable == mWakeupListenEnabled)
{
LogInfo("Listening for wake up frames was already %s", aEnable ? "started" : "stopped");
ExitNow();
}
mWakeupListenEnabled = aEnable;
UpdateWakeupListening();
LogInfo("Listening for wake up frames %s: chan:%u, addr:%s", aEnable ? "started" : "stopped", mWakeupChannel,
GetExtAddress().ToString().AsCString());
exit:
return error;
}
void Mac::UpdateWakeupListening(void)
{
uint8_t channel = mWakeupChannel ? mWakeupChannel : mPanChannel;
mLinks.UpdateWakeupListening(mWakeupListenEnabled, mWakeupListenInterval, mWakeupListenDuration, channel);
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
} // namespace Mac
} // namespace ot
-75
View File
@@ -202,13 +202,6 @@ public:
void RequestCslFrameTransmission(void);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Requests `Mac` to start a wake-up frame transmission.
*/
void RequestWakeupFrameTransmission(void);
#endif
/**
* Requests transmission of a data poll (MAC Data Request) frame.
*
@@ -630,61 +623,6 @@ public:
*/
uint8_t GetWakeupChannel(void) const { return mWakeupChannel; }
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Sets the wake-up channel.
*
* @param[in] aChannel The wake-up channel.
*
* @retval kErrorNone Successfully set the wake-up channel.
* @retval kErrorInvalidArgs The @p aChannel is not in the supported channel mask.
*/
Error SetWakeupChannel(uint8_t aChannel);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Gets the wake-up listen parameters.
*
* @param[out] aInterval A reference to return the wake-up listen interval in microseconds.
* @param[out] aDuration A reference to return the wake-up listen duration in microseconds.
*/
void GetWakeupListenParameters(uint32_t &aInterval, uint32_t &aDuration) const;
/**
* Sets the wake-up listen parameters.
*
* The listen interval must be greater than the listen duration.
* The listen duration must be greater or equal than `Radio::kMinWakeupListenDuration`.
*
* @param[in] aInterval The wake-up listen interval in microseconds.
* @param[in] aDuration The wake-up listen duration in microseconds.
*
* @retval kErrorNone Successfully set the wake-up listen parameters.
* @retval kErrorInvalidArgs Configured listen interval is not greater than listen duration.
*/
Error SetWakeupListenParameters(uint32_t aInterval, uint32_t aDuration);
/**
* Enables/disables listening for wake-up frames.
*
* @param[in] aEnable TRUE to enable listening for wake-up frames, FALSE otherwise
*
* @retval kErrorNone Successfully enabled/disabled listening for wake-up frames.
* @retval kErrorInvalidArgs Configured listen interval is not greater than listen duration.
* @retval kErrorInvalidState Could not enable/disable listening for wake-up frames.
*/
Error SetWakeupListenEnabled(bool aEnable);
/**
* Returns whether listening for wake-up frames is enabled.
*
* @retval TRUE If listening for wake-up frames is enabled.
* @retval FALSE If listening for wake-up frames is not enabled.
*/
bool IsWakeupListenEnabled(void) const { return mWakeupListenEnabled; }
#endif // OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
private:
static constexpr uint16_t kMaxCcaSampleCount = OPENTHREAD_CONFIG_CCA_FAILURE_RATE_AVERAGING_WINDOW;
@@ -716,9 +654,6 @@ private:
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
kOperationTransmitDataCsl,
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
kOperationTransmitWakeup,
#endif
};
@@ -822,9 +757,6 @@ private:
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
void ProcessEnhAckProbing(const RxFrame::ParseInfo &aFrameInfo, const Neighbor &aNeighbor);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void UpdateWakeupListening(void);
#endif
using OperationTask = TaskletIn<Mac, &Mac::PerformNextOperation>;
using MacTimer = TimerMilliIn<Mac, &Mac::HandleTimer>;
@@ -842,9 +774,6 @@ private:
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
bool mShouldDelaySleep : 1;
bool mDelayingSleep : 1;
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
bool mWakeupListenEnabled : 1;
#endif
Operation mOperation;
uint16_t mPendingOperations;
@@ -870,10 +799,6 @@ private:
uint16_t mCslPeriod;
#endif
uint8_t mWakeupChannel;
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
uint32_t mWakeupListenInterval;
uint32_t mWakeupListenDuration;
#endif
union
{
ScanResult::ScanCallback mActiveScanCallback;
-14
View File
@@ -774,20 +774,6 @@ public:
* @retval kErrorParse @p aRxFrame has incorrect format.
*/
Error GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength);
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Generate IEEE 802.15.4 Wake-up frame.
*
* @param[in] aPanId A destination PAN identifier
* @param[in] aWakeupRequest A const reference to the wake-up request.
* @param[in] aSource A source address (short or extended)
*
* @retval kErrorNone Successfully generated Wake-up frame.
* @retval kErrorInvalidArgs @p aDest or @p aSource have incorrect type.
*/
Error GenerateWakeupFrame(PanId, const WakeupRequest &, const Address &) { return kErrorNotImplemented; }
#endif
};
/**
-37
View File
@@ -79,42 +79,5 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
Error ConnectionIe::SetWakeupId(WakeupId aWakeupId)
{
Error error = kErrorNone;
uint8_t wakeupIdLength = GetWakeupIdLength(aWakeupId);
VerifyOrExit(GetSize() >= sizeof(ConnectionIe), error = kErrorParse);
VerifyOrExit(GetSize() - sizeof(ConnectionIe) == wakeupIdLength, error = kErrorParse);
aWakeupId = LittleEndian::HostSwap64(aWakeupId);
memcpy(GetBytes() + sizeof(ConnectionIe), reinterpret_cast<uint8_t *>(&aWakeupId), wakeupIdLength);
exit:
return error;
}
Error ConnectionIe::GetWakeupId(WakeupId &aWakeupId) const
{
Error error = kErrorNone;
uint8_t wakeupIdLength;
VerifyOrExit(GetSize() > sizeof(ConnectionIe), error = kErrorParse);
wakeupIdLength = GetSize() - sizeof(ConnectionIe);
VerifyOrExit(wakeupIdLength <= sizeof(WakeupId), error = kErrorParse);
aWakeupId = 0;
memcpy(reinterpret_cast<uint8_t *>(&aWakeupId), GetBytes() + sizeof(ConnectionIe), wakeupIdLength);
aWakeupId = LittleEndian::HostSwap64(aWakeupId);
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
} // namespace Mac
} // namespace ot
-138
View File
@@ -427,144 +427,6 @@ private:
} OT_TOOL_PACKED_END;
/**
* This class implements Rendezvous Time IE data structure.
*
* IEEE 802.15.4 Rendezvous Time IE contains two fields, Rendezvous Time and
* Wake-up Interval, but the Wake-up Interval is not used in Thread, so it is
* not included in this class.
*/
OT_TOOL_PACKED_BEGIN
class RendezvousTimeIe : public HeaderIe
{
friend class HeaderIe;
public:
static constexpr uint8_t kId = 0x1d; ///< The Rendezvous Time IE Element ID.
/**
* Initializes the Rendezvous Time IE.
*/
void Init(void) { HeaderIe::Init(kId, sizeof(RendezvousTimeIe) - sizeof(HeaderIe)); }
/**
* This method returns the Rendezvous Time.
*
* @returns the Rendezvous Time in the units of 10 symbols.
*/
uint16_t GetRendezvousTime(void) const { return LittleEndian::HostSwap16(mRendezvousTime); }
/**
* This method sets the Rendezvous Time.
*
* @param[in] aRendezvousTime The Rendezvous Time in the units of 10 symbols.
*/
void SetRendezvousTime(uint16_t aRendezvousTime) { mRendezvousTime = LittleEndian::HostSwap16(aRendezvousTime); }
private:
bool IsValid(void) const { return GetSize() >= sizeof(RendezvousTimeIe); }
uint16_t mRendezvousTime;
} OT_TOOL_PACKED_END;
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Implements Connection IE data structure.
*/
OT_TOOL_PACKED_BEGIN
class ConnectionIe : public ThreadVendorIe
{
friend class HeaderIe;
public:
/**
* Initializes the Connection IE.
*
* @param[in] aWakeupIdLength The length of the Wakeup ID field in bytes.
*/
void Init(uint8_t aWakeupIdLength)
{
HeaderIe::Init(kId, sizeof(ConnectionIe) - sizeof(HeaderIe) + aWakeupIdLength);
SetVendorOui(kVendorOuiThread);
SetSubType(kSubType);
mConnectionWindow = 0;
}
/**
* Returns the Retry Interval.
*
* The Retry Interval defines how frequently the Wake-up End Device is
* supposed to retry sending the Parent Request to the Wake-up Coordinator.
*
* @returns the Retry Interval in the units of Wake-up Intervals (7.5ms by default).
*/
uint8_t GetRetryInterval(void) const { return ReadBits<uint8_t, kRetryIntervalMask>(mConnectionWindow); }
/**
* Sets the Retry Interval.
*
* @param[in] aRetryInterval The Retry Interval in the units of Wake-up Intervals (7.5ms by default).
*/
void SetRetryInterval(uint8_t aRetryInterval)
{
WriteBits<uint8_t, kRetryIntervalMask>(mConnectionWindow, aRetryInterval);
}
/**
* Returns the Retry Count.
*
* The Retry Count defines how many times the Wake-up End Device is supposed
* to retry sending the Parent Request to the Wakeup Coordinator.
*
* @returns the Retry Count.
*/
uint8_t GetRetryCount(void) const { return ReadBits<uint8_t, kRetryCountMask>(mConnectionWindow); }
/**
* Sets the Retry Count
*
* @param[in] aRetryCount The Retry Count.
*/
void SetRetryCount(uint8_t aRetryCount) { WriteBits<uint8_t, kRetryCountMask>(mConnectionWindow, aRetryCount); }
/**
* Sets the Wake-up Identifier.
*
* @param[in] aWakeupId The Wake-up Identifier.
*
* @retval kErrorNone Successfully set the Wake-up Identifier.
* @retval kErrorParse The length of the given Wake-up Identifier didn't match the reserved length.
*/
Error SetWakeupId(WakeupId aWakeupId);
/**
* Gets the Wake-up Identifier.
*
* @param[out] aWakeupId A reference to the Wake-up Identifier.
*
* @retval kErrorNone Successfully got the Wake-up Identifier.
* @retval kErrorParse Failed to parse the Wake-up Identifier from the Connection IE.
*/
Error GetWakeupId(WakeupId &aWakeupId) const;
private:
static constexpr uint8_t kSubType = 0x01;
static constexpr uint8_t kRetryIntervalMask = 0x3 << 4;
static constexpr uint8_t kRetryCountMask = 0xf << 0;
bool IsValid(void) const
{
return (GetSize() >= sizeof(ConnectionIe)) && (GetVendorOui() == kVendorOuiThread) &&
(GetSubType() == kSubType);
}
uint8_t mConnectionWindow;
// Followed by variable length Wakeup ID
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* @}
*/
-21
View File
@@ -460,27 +460,6 @@ public:
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Configures wake-up listening parameters in all radios.
*
* @param[in] aEnable Whether to enable or disable wake-up listening.
* @param[in] aInterval The wake-up listen interval in microseconds.
* @param[in] aDuration The wake-up listen duration in microseconds.
* @param[in] aChannel The wake-up channel.
*/
void UpdateWakeupListening(bool aEnable, uint32_t aInterval, uint32_t aDuration, uint8_t aChannel)
{
OT_UNUSED_VARIABLE(aEnable);
OT_UNUSED_VARIABLE(aInterval);
OT_UNUSED_VARIABLE(aDuration);
OT_UNUSED_VARIABLE(aChannel);
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
mSubMac.UpdateWakeupListening(aEnable, aInterval, aDuration, aChannel);
#endif
}
#endif
/**
* Transitions all radio links to Receive.
*
-40
View File
@@ -429,45 +429,5 @@ uint8_t DeterminePrevKeyIndex(uint8_t aKeyIndex)
return prevIndex;
}
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
uint8_t GetWakeupIdLength(WakeupId aWakeupId)
{
uint8_t zeroBytesCount = 0;
for (int i = static_cast<int>(sizeof(WakeupId)) - 1; i >= 1; --i)
{
if (((aWakeupId >> (i * kBitsPerByte)) & 0xFF) == 0)
{
zeroBytesCount++;
}
else
{
break;
}
}
return sizeof(WakeupId) - zeroBytesCount;
}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
void WakeupRequest::SetExtAddress(const ExtAddress &aExtAddress)
{
SetType(kTypeExtAddress);
aExtAddress.CopyTo(mShared.mExtAddress.m8);
}
const ExtAddress &WakeupRequest::GetExtAddress(void) const { return AsCoreType(&mShared.mExtAddress); }
ExtAddress &WakeupRequest::GetExtAddress(void) { return AsCoreType(&mShared.mExtAddress); }
void WakeupRequest::SetType(Type aType) { mType = MapEnum(aType); }
bool WakeupRequest::IsWakeupByExtAddress(void) const { return MapEnum(mType) == kTypeExtAddress; }
bool WakeupRequest::IsWakeupById(void) const { return MapEnum(mType) == kTypeWakeupId; }
bool WakeupRequest::IsWakeupByGroupId(void) const { return MapEnum(mType) == kTypeGroupWakeupId; }
#endif
} // namespace Mac
} // namespace ot
-134
View File
@@ -90,11 +90,6 @@ constexpr ShortAddress kShortAddrInvalid = OT_RADIO_INVALID_SHORT_ADDR; ///<
*/
typedef otLinkPcapCallback PcapCallback;
/**
* Represents the wake-up identifier.
*/
typedef otWakeupId WakeupId;
/**
* Represents the MAC layer counters.
*/
@@ -941,131 +936,6 @@ private:
uint8_t mUncertainty;
};
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Gets the length of the wake-up identifier.
*
* The length is the number of bytes remaining after removing the most significant zero bytes.
*
* @param[in] aWakeupId The wake-up identifier.
*
* @returns The length of the @p aWakeupId.
*/
uint8_t GetWakeupIdLength(WakeupId aWakeupId);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Represents a wake-up request.
*/
class WakeupRequest : public otWakeupRequest
{
public:
/**
* Represents a wake-up request type.
*/
enum Type : uint8_t
{
kTypeExtAddress = OT_WAKEUP_TYPE_EXT_ADDRESS,
kTypeWakeupId = OT_WAKEUP_TYPE_IDENTIFIER,
kTypeGroupWakeupId = OT_WAKEUP_TYPE_GROUP_IDENTIFIER,
};
/**
* Sets the wake-up request with an Extended Address.
*
* The type is also updated to indicate that the wake-up request type is `kTypeExtAddress`.
*
* @param[in] aExtAddress An Extended Address.
*/
void SetExtAddress(const ExtAddress &aExtAddress);
/**
* Gets the Extended Address of the wake-up request.
*
* MUST be used only if the wake-up request type is `kTypeExtAddress`.
*
* @returns A constant reference to the Extended Address.
*/
const ExtAddress &GetExtAddress(void) const;
/**
* Gets the Extended Address of the wake-up request.
*
* MUST be used only if the wake-up request type is `kTypeExtAddress`.
*
* @returns A reference to the Extended Address.
*/
ExtAddress &GetExtAddress(void);
/**
* Gets the Wake-up Identifier of the wake-up request.
*
* MUST be used only if the wake-up request type is `kTypeWakeupId` or `kTypeGroupWakeupId`.
*
* @returns The Wake-up Identifier.
*/
WakeupId GetWakeupId(void) const { return mShared.mWakeupId; }
/**
* Sets the wake-up request with the Wake-up Identifier.
*
* The type is also updated to indicate that the wake-up request type is `kTypeWakeupId`.
*
* @param[in] aWakeupId A Wake-up Identifier.
*/
void SetWakeupId(WakeupId aWakeupId)
{
SetType(kTypeWakeupId);
mShared.mWakeupId = aWakeupId;
}
/**
* Sets the wake-up request type.
*
* @param[in] aType The wake-up request type.
*/
void SetType(Type aType);
/**
* Indicates whether the peer is set to be woken up by the extended address.
*
* @retval TRUE If the peer is set to be woken up by the extended address.
* @retval FALSE If the peer is not not set to be woken up by the extended address.
*/
bool IsWakeupByExtAddress(void) const;
/**
* Indicates whether the peer is set to be woken up by the wake-up identifier.
*
* @retval TRUE If the peer is set to be woken up by the wake-up identifier.
* @retval FALSE If the peer is not set to be woken up by the wake-up identifier.
*/
bool IsWakeupById(void) const;
/**
* Indicates whether the peer is set to be woken up by the group wake-up identifier.
*
* @retval TRUE If the peer is set to be woken up by the group wake-up identifier.
* @retval FALSE If the peer is not set to be woken up by the group wake-up identifier.
*/
bool IsWakeupByGroupId(void) const;
};
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Represents the information of the received wake-up frame.
*/
struct WakeupInfo
{
ExtAddress mExtAddress; ///< The extended address of the Wake-up Coordinator.
uint32_t mAttachDelayMs; ///< The delay before linking to the peer.
uint8_t mRetryInterval : 2; ///< The interval of the periodic connection windows.
uint8_t mRetryCount : 4; ///< The maximum number of retries the action by the Wake-up Listener.
};
#endif
/**
* @}
*/
@@ -1075,10 +945,6 @@ struct WakeupInfo
DefineCoreType(otExtAddress, Mac::ExtAddress);
DefineCoreType(otMacKey, Mac::Key);
DefineCoreType(otMacKeyMaterial, Mac::KeyMaterial);
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
DefineCoreType(otWakeupRequest, Mac::WakeupRequest);
DefineMapEnum(otWakeupType, Mac::WakeupRequest::Type);
#endif
} // namespace ot
-9
View File
@@ -55,9 +55,6 @@ SubMac::SubMac(Instance &aInstance)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
, mCslReceiver(aInstance)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
, mWedTimer(aInstance)
#endif
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && !OPENTHREAD_CONFIG_MAC_SOFTWARE_RETX_SECURITY_ENABLE
// Assuming the platform must deal with the retransmission security correctly.
@@ -97,9 +94,6 @@ void SubMac::Init(void)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
mCslReceiver.Init();
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
WedInit();
#endif
}
#if OPENTHREAD_FTD || OPENTHREAD_MTD
@@ -235,9 +229,6 @@ Error SubMac::Disable(void)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
mCslReceiver.Stop();
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
mWedTimer.Stop();
#endif
mTimer.Stop();
SuccessOrExit(error = Get<Radio::Radio>().Sleep());
-38
View File
@@ -522,18 +522,6 @@ public:
bool IsRadioFilterEnabled(void) const { return mRadioFilterEnabled; }
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Configures wake-up listening parameters in all radios.
*
* @param[in] aEnable Whether to enable or disable wake-up listening.
* @param[in] aInterval The wake-up listen interval in microseconds.
* @param[in] aDuration The wake-up listen duration in microseconds.
* @param[in] aChannel The wake-up channel.
*/
void UpdateWakeupListening(bool aEnable, uint32_t aInterval, uint32_t aDuration, uint8_t aChannel);
#endif
private:
static constexpr uint8_t kCsmaMinBe = 3; // macMinBE (IEEE 802.15.4-2006).
static constexpr uint8_t kCsmaMaxBe = 5; // macMaxBE (IEEE 802.15.4-2006).
@@ -600,16 +588,6 @@ private:
#endif
};
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
// Wake-up listening receivers would wake up `kWedReceiveTimeAhead` earlier
// than expected sample window. The value is in usec.
static constexpr uint32_t kWedReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
// Margin to be applied after the end of a wake-up listen duration to schedule the next listen interval.
// The value is in usec.
static constexpr uint32_t kWedReceiveTimeAfter = 500;
#endif
#if OT_CONFIG_MAC_TARGET_TIME_TX_ENABLE
// Lead time (in microseconds) to schedule a delayed tx earlier
// than expected target tx time. Only used when radio does not
@@ -725,11 +703,6 @@ private:
void SetState(State aState);
static const char *StateToString(State aState);
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void WedInit(void);
void HandleWedTimer(void);
#endif
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
using SubMacTimer = TimerMicroIn<SubMac, &SubMac::HandleTimer>;
#else
@@ -767,17 +740,6 @@ private:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
CslReceiver mCslReceiver;
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
using WedTimer = TimerMicroIn<SubMac, &SubMac::HandleWedTimer>;
bool mIsWedEnabled; // Indicates if the WED is enabled.
uint32_t mWakeupListenInterval; // The wake-up listen interval, in microseconds.
uint32_t mWakeupListenDuration; // The wake-up listen duration, in microseconds.
uint8_t mWakeupChannel; // The wake-up sample channel.
Radio::SyncedTime mWedSampleTime; // The WED sample time of the current interval.
WedTimer mWedTimer;
#endif
};
/**
-83
View File
@@ -1,83 +0,0 @@
/*
* 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.
*/
/**
* @file
* This file implements the Wake-up End Device of the subset of IEEE 802.15.4 MAC primitives.
*/
#include "sub_mac.hpp"
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
#include "instance/instance.hpp"
namespace ot {
namespace Mac {
RegisterLogModule("SubMac");
void SubMac::WedInit(void)
{
mIsWedEnabled = false;
mWakeupListenInterval = 0;
mWedTimer.Stop();
}
void SubMac::UpdateWakeupListening(bool aEnable, uint32_t aInterval, uint32_t aDuration, uint8_t aChannel)
{
mWakeupListenInterval = aInterval;
mWakeupListenDuration = aDuration;
mWakeupChannel = aChannel;
mIsWedEnabled = aEnable;
mWedTimer.Stop();
if (aEnable)
{
mWedSampleTime.SetToNow(Get<Radio::Radio>());
mWedSampleTime += kWedReceiveTimeAhead;
mWedSampleTime -= mWakeupListenInterval;
HandleWedTimer();
}
}
void SubMac::HandleWedTimer(void)
{
mWedSampleTime += mWakeupListenInterval;
mWedTimer.FireAt(mWedSampleTime.GetAsLocalTimeMicro() + mWakeupListenDuration + kWedReceiveTimeAfter);
ReceiveAt(mWedSampleTime.GetAsTime64(), mWakeupListenDuration, mWakeupChannel);
}
} // namespace Mac
} // namespace ot
#endif // OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
-181
View File
@@ -1,181 +0,0 @@
/*
* 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.
*/
#include "wakeup_tx_scheduler.hpp"
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#include "common/code_utils.hpp"
#include "common/log.hpp"
#include "common/num_utils.hpp"
#include "common/time.hpp"
#include "core/instance/instance.hpp"
#include "radio/radio.hpp"
namespace ot {
RegisterLogModule("WakeupTxSched");
WakeupTxScheduler::WakeupTxScheduler(Instance &aInstance)
: InstanceLocator(aInstance)
, mTxTimeUs(0)
, mTxEndTimeUs(0)
, mTimer(aInstance)
, mIsRunning(false)
{
HandleRadioBusLatencyChanged();
}
Error WakeupTxScheduler::WakeUp(const Mac::WakeupRequest &aWakeupRequest, uint16_t aIntervalUs, uint16_t aDurationMs)
{
Error error = kErrorNone;
VerifyOrExit(!mIsRunning, error = kErrorInvalidState);
// TODO: Add support for wake-up identifiers.
VerifyOrExit(aWakeupRequest.IsWakeupByExtAddress(), error = kErrorInvalidState);
mWakeupRequest = aWakeupRequest;
mTxTimeUs = TimerMicro::GetNow() + mTxRequestAheadTimeUs;
mTxEndTimeUs = mTxTimeUs + aDurationMs * Time::kOneMsecInUsec + aIntervalUs;
mIntervalUs = aIntervalUs;
mIsRunning = true;
LogInfo("Started wake-up sequence to %s", aWakeupRequest.GetExtAddress().ToString().AsCString());
ScheduleTimer();
exit:
return error;
}
void WakeupTxScheduler::RequestWakeupFrameTransmission(void) { Get<Mac::Mac>().RequestWakeupFrameTransmission(); }
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames)
{
Mac::TxFrame *frame = nullptr;
Mac::TxFrame::ParseInfo txFrameInfo;
Mac::Address source;
uint32_t radioTxDelay;
uint32_t rendezvousTimeUs;
TimeMicro nowUs = TimerMicro::GetNow();
Radio::Time64 radioNow = Get<Radio::Radio>().GetNow();
Mac::RendezvousTimeIe *rendezvousTimeIe;
Mac::ConnectionIe *connectionIe;
VerifyOrExit(mIsRunning);
source.SetExtended(Get<Mac::Mac>().GetExtAddress());
VerifyOrExit(mTxTimeUs >= nowUs);
radioTxDelay = mTxTimeUs - nowUs;
#if OPENTHREAD_CONFIG_MULTI_RADIO
frame = &aTxFrames.GetTxFrame(Radio::kTypeIeee802154);
#else
frame = &aTxFrames.GetTxFrame();
#endif
VerifyOrExit(frame->GenerateWakeupFrame(Get<Mac::Mac>().GetPanId(), mWakeupRequest, source) == kErrorNone,
frame = nullptr);
if (txFrameInfo.ParseFrom(*frame, Mac::Frame::kParseFully) != kErrorNone)
{
ExitNow(frame = nullptr);
}
frame->SetTargetTxTime(radioNow + radioTxDelay, radioNow);
frame->SetCsmaCaEnabled(kWakeupFrameTxCca);
frame->SetMaxCsmaBackoffs(0);
frame->SetMaxFrameRetries(0);
// Rendezvous Time is the time between the end of a wake-up frame and the start of the first payload frame.
// For the n-th wake-up frame, set the Rendezvous Time so that the expected reception of a Parent Request happens in
// the "free space" between the "n+1"-th and "n+2"-th wake-up frame.
rendezvousTimeUs = mIntervalUs;
rendezvousTimeUs += (mIntervalUs - (kWakeupFrameLength + kParentRequestLength) * Radio::kOctetDuration) / 2;
rendezvousTimeIe = txFrameInfo.Find<Mac::RendezvousTimeIe>();
VerifyOrExit(rendezvousTimeIe != nullptr, frame = nullptr);
rendezvousTimeIe->SetRendezvousTime(ClampToUint16(rendezvousTimeUs / Radio::kTenSymbolsDuration));
connectionIe = txFrameInfo.Find<Mac::ConnectionIe>();
VerifyOrExit(connectionIe != nullptr, frame = nullptr);
connectionIe->SetRetryInterval(kConnectionRetryInterval);
connectionIe->SetRetryCount(kConnectionRetryCount);
// Advance to the time of the next wake-up frame.
mTxTimeUs = Max(mTxTimeUs + mIntervalUs, TimerMicro::GetNow() + mTxRequestAheadTimeUs);
// Schedule the next timer right away before waiting for the transmission completion
// to keep up with the high rate of wake-up frames in the RCP architecture.
ScheduleTimer();
exit:
return frame;
}
#else // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &) { return nullptr; }
#endif // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
void WakeupTxScheduler::ScheduleTimer(void)
{
if (mTxTimeUs >= mTxEndTimeUs)
{
mIsRunning = false;
LogInfo("Stopped wake-up sequence");
ExitNow();
}
mTimer.FireAt(mTxTimeUs - mTxRequestAheadTimeUs);
exit:
return;
}
void WakeupTxScheduler::Stop(void)
{
mIsRunning = false;
mTimer.Stop();
}
void WakeupTxScheduler::HandleRadioBusLatencyChanged(void)
{
// A rough estimate of the size of data that has to be exchanged with the radio to schedule a wake-up frame TX.
// This is used to make sure that a wake-up frame is received by the radio early enough to be transmitted on time.
constexpr uint32_t kWakeupFrameSize = 100;
mTxRequestAheadTimeUs = Mac::kCslRequestAhead + Get<Radio::Radio>().CalculateBusTransferTime(kWakeupFrameSize);
}
} // namespace ot
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
-137
View File
@@ -1,137 +0,0 @@
/*
* 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.
*/
#ifndef OT_CORE_MAC_WAKEUP_TX_SCHEDULER_HPP_
#define OT_CORE_MAC_WAKEUP_TX_SCHEDULER_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "mac/mac.hpp"
#include "radio/radio.hpp"
namespace ot {
class Child;
/**
* Implements wake-up sequence TX scheduling functionality.
*/
class WakeupTxScheduler : public InstanceLocator, private NonCopyable
{
friend class Mac::Mac;
friend class Radio::Callbacks;
public:
/**
* Initializes the wake-up sequence TX scheduler object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*/
explicit WakeupTxScheduler(Instance &aInstance);
/**
* Initiates the wake-up sequence to a Wake-up End Device.
*
* @param[in] aWakeupRequest The wake-up request.
* @param[in] aIntervalUs An interval between consecutive wake-up frames (in microseconds).
* @param[in] aDurationMs Duration of the wake-up sequence (in milliseconds).
*
* @retval kErrorNone Successfully started the wake-up sequence.
* @retval kErrorInvalidState This or another device is currently being woken-up.
*/
Error WakeUp(const Mac::WakeupRequest &aWakeupRequest, uint16_t aIntervalUs, uint16_t aDurationMs);
/**
* Returns the connection window used by this device.
*
* The connection window is amount of time that this device waits for an initial link establishment message after
* sending the last wake-up frame.
*
* @returns Connection window in the units of microseconds.
*/
uint32_t GetConnectionWindowUs(void) const
{
return mIntervalUs * kConnectionRetryInterval * kConnectionRetryCount;
}
/**
* Returns the end of the wake-up sequence time.
*
* @returns End of the wake-up sequence time.
*/
TimeMicro GetTxEndTime(void) const { return mTxEndTimeUs; }
/**
* Stops the ongoing wake-up sequence.
*/
void Stop(void);
/**
* Returns the wake-up request.
*/
const Mac::WakeupRequest &GetWakeupRequest(void) const { return mWakeupRequest; }
private:
static constexpr uint8_t kConnectionRetryInterval = 1;
static constexpr uint8_t kConnectionRetryCount = 12;
static constexpr uint32_t kWakeupFrameLength = 54; // Includes SHR
static constexpr bool kWakeupFrameTxCca = true;
static constexpr uint32_t kParentRequestLength = 78; // Includes SHR
// Called by the MAC layer when a wake-up frame transmission is about to be started.
Mac::TxFrame *PrepareWakeupFrame(Mac::TxFrames &aTxFrames);
// Callback from `Radio`
void HandleRadioBusLatencyChanged(void);
// Called at the beginning of a wake-up sequence and right after a wake-up frame has been prepared for transmission.
void ScheduleTimer(void);
void RequestWakeupFrameTransmission(void);
using WakeupTimer = TimerMicroIn<WakeupTxScheduler, &WakeupTxScheduler::RequestWakeupFrameTransmission>;
Mac::WakeupRequest mWakeupRequest;
TimeMicro mTxTimeUs; // Point in time when the next TX occurs.
TimeMicro mTxEndTimeUs; // Point in time when the wake-up sequence is over.
uint32_t mTxRequestAheadTimeUs; // How much ahead the TX MAC operation needs to be requested.
uint16_t mIntervalUs; // Interval between consecutive wake-up frames.
WakeupTimer mTimer;
bool mIsRunning;
};
} // namespace ot
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#endif // OT_CORE_MAC_WAKEUP_TX_SCHEDULER_HPP_
-11
View File
@@ -187,17 +187,6 @@ Error DatasetManager::ApplyConfiguration(const Dataset &aDataset) const
break;
}
case Tlv::kWakeupChannel:
{
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
uint8_t channel = static_cast<uint8_t>(cur->ReadValueAs<WakeupChannelTlv>().GetChannel());
error = Get<Mac::Mac>().SetWakeupChannel(channel);
LogCritOnError(error, "set wake-up channel to %u when applying dataset", channel);
#endif
break;
}
case Tlv::kPanId:
Get<Mac::Mac>().SetPanId(cur->ReadValueAs<PanIdTlv>());
break;
-7
View File
@@ -71,13 +71,6 @@ constexpr uint32_t kHeaderShrDuration = 160; ///< Duration of SHR in us
constexpr uint32_t kHeaderPhrDuration = 32; ///< Duration of PHR in us
constexpr uint32_t kOctetDuration = 32; ///< Duration of one octet in us
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Minimum wake-up listen duration supported in microseconds.
*/
constexpr uint32_t kMinWakeupListenDuration = 100;
#endif
#if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD) && \
!OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
#error "OPENTHREAD_CONFIG_RADIO_STATS_ENABLE requires OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE".
-3
View File
@@ -63,9 +63,6 @@ void Callbacks::HandleBusLatencyChanged(void)
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
Get<CslTxScheduler>().HandleRadioBusLatencyChanged();
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
Get<WakeupTxScheduler>().HandleRadioBusLatencyChanged();
#endif
}
#if OPENTHREAD_CONFIG_DIAG_ENABLE
+1 -102
View File
@@ -74,11 +74,6 @@ Mle::Mle(Instance &aInstance)
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
, mParentSearch(aInstance)
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
, mWakeupTxScheduler(aInstance)
, mWedAttachState(kWedDetached)
, mWedAttachTimer(aInstance)
#endif
#if OPENTHREAD_FTD
, mAddressSolicitPending(false)
, mAddressSolicitRejected(false)
@@ -102,9 +97,6 @@ Mle::Mle(Instance &aInstance)
, mRoleTransitioner(aInstance)
, mTxChallengeTable(aInstance)
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_P2P_ENABLE
, mP2p(aInstance)
#endif
{
mParent.Init(aInstance);
@@ -1814,28 +1806,6 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
break;
#endif
#if OPENTHREAD_CONFIG_P2P_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kCommandP2pLinkRequest:
mP2p.HandleP2pLinkRequest(rxInfo);
break;
case kCommandP2pLinkAccept:
mP2p.HandleP2pLinkAccept(rxInfo);
break;
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
case kCommandP2pLinkAcceptAndRequest:
mP2p.HandleP2pLinkAcceptAndRequest(rxInfo);
break;
#endif
case kCommandP2pLinkTearDown:
mP2p.HandleP2pLinkTearDown(rxInfo);
break;
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
default:
ExitNow(error = kErrorDrop);
}
@@ -2936,7 +2906,7 @@ const char *Mle::MessageTypeToString(MessageType aType)
_(kTypeParentRequestToRouters, "Parent Request") \
_(kTypeParentRequestToRoutersReeds, "Parent Request") \
_(kTypeParentResponse, "Parent Response") \
FtdMessageTypeMapList(_) LinkMetricsMessageTypeMapList(_) TimeSyncMessageTypeMapList(_) P2pMessageTypeMapList(_)
FtdMessageTypeMapList(_) LinkMetricsMessageTypeMapList(_) TimeSyncMessageTypeMapList(_)
#if OPENTHREAD_FTD
#define FtdMessageTypeMapList(_) \
@@ -2969,16 +2939,6 @@ const char *Mle::MessageTypeToString(MessageType aType)
#define TimeSyncMessageTypeMapList(_) _(kTypeTimeSync, "Time Sync")
#else
#define TimeSyncMessageTypeMapList(_)
#endif
#if OPENTHREAD_CONFIG_P2P_ENABLE
#define P2pMessageTypeMapList(_) \
_(kTypeP2pLinkRequest, "P2P Link Request") \
_(kTypeP2pLinkAcceptAndRequest, "P2P Link Accept and Request") \
_(kTypeP2pLinkAccept, "P2P Link Accept") \
_(kTypeP2pLinkTearDown, "P2P Link Tear Down")
#else
#define P2pMessageTypeMapList(_)
#endif
DefineEnumStringArray(MessageTypeMapList);
@@ -3061,67 +3021,6 @@ uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const
}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
void Mle::HandleWedAttachTimer(void)
{
switch (mWedAttachState)
{
case kWedAttaching:
// Connection timeout
if (!IsRxOnWhenIdle())
{
Get<MeshForwarder>().SetRxOnWhenIdle(false);
}
LogInfo("Connection window closed");
mWedAttachState = kWedDetached;
mWakeupCallback.InvokeAndClearIfSet(kErrorFailed);
break;
default:
break;
}
}
Error Mle::Wakeup(const Mac::ExtAddress &aWedAddress,
uint16_t aIntervalUs,
uint16_t aDurationMs,
WakeupCallback aCallback,
void *aCallbackContext)
{
Error error = kErrorNone;
Mac::WakeupRequest wakeupRequest;
VerifyOrExit((aIntervalUs > 0) && (aDurationMs > 0), error = kErrorInvalidArgs);
VerifyOrExit(aIntervalUs < aDurationMs * Time::kOneMsecInUsec, error = kErrorInvalidArgs);
VerifyOrExit(mWedAttachState == kWedDetached, error = kErrorInvalidState);
wakeupRequest.SetExtAddress(aWedAddress);
SuccessOrExit(error = mWakeupTxScheduler.WakeUp(wakeupRequest, aIntervalUs, aDurationMs));
mWedAttachState = kWedAttaching;
mWakeupCallback.Set(aCallback, aCallbackContext);
Get<MeshForwarder>().SetRxOnWhenIdle(true);
mWedAttachTimer.FireAt(mWakeupTxScheduler.GetTxEndTime() + mWakeupTxScheduler.GetConnectionWindowUs());
LogInfo("Connection window open");
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void Mle::HandleWakeupFrame(const Mac::WakeupInfo &aWakeupInfo)
{
OT_UNUSED_VARIABLE(aWakeupInfo);
#if OPENTHREAD_CONFIG_P2P_ENABLE
mP2p.HandleP2pWakeup(aWakeupInfo);
#endif
}
#endif
//---------------------------------------------------------------------------------------------------------------------
// TlvList
+1 -196
View File
@@ -37,7 +37,6 @@
#include "openthread-core-config.h"
#include <openthread/thread_ftd.h>
#include <openthread/provisional/p2p.h>
#include "coap/coap_message.hpp"
#include "common/as_core_type.hpp"
@@ -55,7 +54,6 @@
#include "crypto/aes_ccm.hpp"
#include "mac/mac.hpp"
#include "mac/mac_types.hpp"
#include "mac/wakeup_tx_scheduler.hpp"
#include "meshcop/dataset.hpp"
#include "meshcop/joiner_router.hpp"
#include "meshcop/meshcop.hpp"
@@ -71,8 +69,6 @@
#include "thread/mle_types.hpp"
#include "thread/neighbor_table.hpp"
#include "thread/network_data_types.hpp"
#include "thread/peer.hpp"
#include "thread/peer_table.hpp"
#include "thread/router.hpp"
#include "thread/router_table.hpp"
#include "thread/thread_tlvs.hpp"
@@ -137,11 +133,6 @@ class Mle : public InstanceLocator, private NonCopyable
public:
typedef otDetachGracefullyCallback DetachCallback; ///< Callback to signal end of graceful detach.
typedef otP2pLinkDoneCallback P2pLinkDoneCallback; ///< Callback to inform the result of establishing P2P links.
typedef otP2pUnlinkDoneCallback
P2pUnlinkDoneCallback; ///< Callback to inform the result of tearing down the P2P link.
typedef otP2pEventCallback P2pEventCallback; ///< Callback to signal events of the P2P link.
typedef otWakeupCallback WakeupCallback; ///< Callback to communicate the result of waking a Wake-up End Device.
/**
* Initializes the MLE object.
@@ -766,27 +757,6 @@ public:
bool IsCslSupported(void) const;
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Attempts to wake a Wake-up End Device.
*
* @param[in] aWedAddress The extended address of the Wake-up End Device.
* @param[in] aIntervalUs An interval between consecutive wake-up frames (in microseconds).
* @param[in] aDurationMs Duration of the wake-up sequence (in milliseconds).
* @param[in] aCallback A pointer to function that is called when the wake-up succeeds or fails.
* @param[in] aContext A pointer to callback application-specific context.
*
* @retval kErrorNone Successfully started the wake-up.
* @retval kErrorInvalidState Another wake-up request is still in progress.
* @retval kErrorInvalidArgs The wake-up interval or duration are invalid.
*/
Error Wakeup(const Mac::ExtAddress &aWedAddress,
uint16_t aIntervalUs,
uint16_t aDurationMs,
WakeupCallback aCallback,
void *aCallbackContext);
#endif // OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
#if OPENTHREAD_FTD
/**
* Sets whether or not the device is router-eligible.
@@ -1231,65 +1201,6 @@ public:
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_P2P_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Attempts to wake up peers and establish P2P links with peers.
*
* If the @p aP2pRequest indicates a group identifier, this method establishes multiple P2P links with peers.
* Otherwise, it establishes at most one P2P link.
*
* @param[in] aP2pRequest A constant reference to the P2P request.
* @param[in] aCallback A pointer to the function that is called when the P2P link succeeds or fails.
* @param[in] aContext A pointer to the callback application-specific context.
*
* @retval kErrorNone Successfully started to establish P2P links.
* @retval kErrorBusy Establishing a P2P link in progress.
* @retval kErrorInvalidState Device was disabled or not fully configured.
* @retval kErrorNoBufs Insufficient buffer space to establish a P2P link.
*/
Error P2pWakeupAndLink(const P2pRequest &aP2pRequest, P2pLinkDoneCallback aCallback, void *aContext)
{
return mP2p.WakeupAndLink(aP2pRequest, aCallback, aContext);
}
#endif
/**
* Tears down the P2P link specified by the Extended Address.
*
* @param[in] aExtAddress A constant reference to the P2P peer's Extended Address.
* @param[in] aCallback A pointer to function that is called when the P2P link tear down process has ended.
* @param[in] aContext A pointer to callback application-specific context.
*
* @retval OT_ERROR_NONE Successfully started to tear down the P2P link.
* @retval OT_ERROR_BUSY Tearing down or establishing a P2P link process is in progress.
* @retval OT_ERROR_NOT_FOUND The P2P link identified by the @p aExtAddress was not found.
*/
Error P2pUnlink(const Mac::ExtAddress &aExtAddress, P2pUnlinkDoneCallback aCallback, void *aContext)
{
return mP2p.Unlink(aExtAddress, aCallback, aContext);
}
/**
* Sets the callback function to notify event changes of P2P links.
*
* A subsequent call to this function will replace any previously set callback.
*
* @param[in] aCallback The callback function pointer.
* @param[in] aContext A pointer to the callback application-specific context.
*/
void P2pSetEventCallback(P2pEventCallback aCallback, void *aContext) { mP2p.SetEventCallback(aCallback, aContext); }
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
/**
* Notifies MLE that a wake-up frame was received successfully.
*
* @param[in] aWakeupInfo A reference to the wake-up frame information.
*/
void HandleWakeupFrame(const Mac::WakeupInfo &aWakeupInfo);
#endif
private:
//------------------------------------------------------------------------------------------------------------------
// Constants
@@ -1567,25 +1478,9 @@ private:
#endif
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
kTypeTimeSync,
#endif
#if OPENTHREAD_CONFIG_P2P_ENABLE
kTypeP2pLinkRequest,
kTypeP2pLinkAcceptAndRequest,
kTypeP2pLinkAccept,
kTypeP2pLinkTearDown,
#endif
};
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
enum WedAttachState : uint8_t
{
kWedDetached,
kWedAttaching,
kWedAttached,
kWedDetaching,
};
#endif
//------------------------------------------------------------------------------------------------------------------
// Nested types
@@ -1744,7 +1639,7 @@ private:
};
#endif
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_P2P_ENABLE
#if OPENTHREAD_FTD
struct LinkAcceptInfo
{
Mac::ExtAddress mExtAddress; // The neighbor/router extended address.
@@ -2373,78 +2268,6 @@ private:
#endif // OPENTHREAD_FTD
//------------------------------------------------------------------------------------------------------------------
#if OPENTHREAD_CONFIG_P2P_ENABLE
void HandleP2pLinkTimer(void) { mP2p.HandleLinkTimer(); }
class P2p : public InstanceLocator
{
friend class ot::Instance;
public:
P2p(Instance &aInstance);
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
Error WakeupAndLink(const P2pRequest &aP2pRequest, P2pLinkDoneCallback aCallback, void *aContext);
void HandleP2pLinkRequest(RxInfo &aRxInfo);
void HandleP2pLinkAccept(RxInfo &aRxInfo);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void HandleP2pWakeup(const Mac::WakeupInfo &aWakeupInfo);
void HandleP2pLinkAcceptAndRequest(RxInfo &aRxInfo);
#endif
Error Unlink(const Mac::ExtAddress &aExtAddress, P2pUnlinkDoneCallback aCallback, void *aContext);
void HandleP2pLinkTearDown(RxInfo &aRxInfo);
void SetEventCallback(P2pEventCallback aCallback, void *aContext);
void HandleLinkTimer(void);
private:
static constexpr uint16_t kWakeupMaxDuration = 1090;
static constexpr uint16_t kWakeupTxInterval = 7500;
static constexpr uint32_t kEstablishP2pLinkTimeoutUs = 500000;
enum State : uint8_t
{
kStateIdle,
kStateWakingUp,
kStateWaitingLinkAccept,
kStateAttachDelay,
kStateWaitingLinkAcceptAndRequest,
kStateTearingDown,
};
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void SendP2pLinkRequest(Peer *aPeer);
Error SendP2pLinkAccept(const LinkAcceptInfo &aInfo);
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
Error SendP2pLinkAcceptAndRequest(const LinkAcceptInfo &aInfo);
#endif
static void HandleLinkTearDownTxDone(const otMessage *aMessage, otError aError, void *aContext);
void HandleLinkTearDownTxDone(const Message &aMessage);
Error SendP2pLinkAcceptVariant(const LinkAcceptInfo &aInfo, bool aIsLinkAcceptorRequest);
void HandleP2pLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType);
void SetWakeupListenerEnabled(void);
void ClearPeersInLinkRequestState(void);
Error SendLinkTearDown(Peer &aPeer);
void PeerUnlinked(Peer &aPeer);
using P2pLinkTimer = TimerMicroIn<Mle, &Mle::HandleP2pLinkTimer>;
State mState;
PeerTable mPeerTable;
P2pLinkTimer mTimer;
Callback<P2pLinkDoneCallback> mLinkDoneCallback;
Callback<P2pUnlinkDoneCallback> mUnlinkDoneCallback;
Callback<P2pEventCallback> mEventCallback;
Peer *mPeer;
};
#endif
//------------------------------------------------------------------------------------------------------------------
// Methods
@@ -2533,10 +2356,6 @@ private:
static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {}
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
void HandleWedAttachTimer(void);
#endif
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
static void LogError(MessageAction aAction, MessageType aType, Error aError);
static const char *MessageActionToString(MessageAction aAction);
@@ -2624,9 +2443,6 @@ private:
// Variables
using MleSocket = Ip6::Udp::SocketIn<Mle, &Mle::HandleUdpReceive>;
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
using WedAttachTimer = TimerMicroIn<Mle, &Mle::HandleWedAttachTimer>;
#endif
static const otMeshLocalPrefix kMeshLocalPrefixInit;
@@ -2667,13 +2483,6 @@ private:
Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes;
Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes;
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
WakeupTxScheduler mWakeupTxScheduler;
WedAttachState mWedAttachState;
WedAttachTimer mWedAttachTimer;
Callback<WakeupCallback> mWakeupCallback;
#endif
#if OPENTHREAD_FTD
bool mAddressSolicitPending : 1;
@@ -2712,10 +2521,6 @@ private:
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_P2P_ENABLE
P2p mP2p;
#endif
};
#if OPENTHREAD_FTD
-512
View File
@@ -1,512 +0,0 @@
/*
* Copyright (c) 2025, 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.
*/
/**
* @file
* This file implements MLE functionality required for the Thread peer-to-peer (P2P) link.
*/
#include "mle.hpp"
#if OPENTHREAD_CONFIG_P2P_ENABLE
#if !(OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE)
#error "OPENTHREAD_CONFIG_P2P_ENABLE requires OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE or "\
"OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE"
#endif
#include "common/code_utils.hpp"
#include "instance/instance.hpp"
#include "openthread/platform/toolchain.h"
namespace ot {
namespace Mle {
RegisterLogModule("P2p");
Mle::P2p::P2p(Instance &aInstance)
: InstanceLocator(aInstance)
, mState(kStateIdle)
, mPeerTable(aInstance)
, mTimer(aInstance)
, mLinkDoneCallback()
, mUnlinkDoneCallback()
, mEventCallback()
, mPeer(nullptr)
{
}
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
Error Mle::P2p::WakeupAndLink(const P2pRequest &aP2pRequest, P2pLinkDoneCallback aCallback, void *aContext)
{
Error error = kErrorNone;
VerifyOrExit(!Get<Radio::Radio>().GetPromiscuous(), error = kErrorInvalidState);
VerifyOrExit(Get<ThreadNetif>().IsUp(), error = kErrorInvalidState);
VerifyOrExit(!Get<Mle>().IsDisabled(), error = kErrorInvalidState);
VerifyOrExit(mState == kStateIdle, error = kErrorBusy);
VerifyOrExit(!mPeerTable.IsFull(), error = kErrorNoBufs);
// TODO: support rx-off-when-idle device later.
VerifyOrExit(Get<Mle>().IsRxOnWhenIdle(), error = kErrorInvalidState);
SuccessOrExit(
error = Get<WakeupTxScheduler>().WakeUp(aP2pRequest.GetWakeupRequest(), kWakeupTxInterval, kWakeupMaxDuration));
mState = kStateWakingUp;
mLinkDoneCallback.Set(aCallback, aContext);
mTimer.FireAt(Get<WakeupTxScheduler>().GetTxEndTime() + Get<WakeupTxScheduler>().GetConnectionWindowUs());
exit:
return error;
}
void Mle::P2p::HandleP2pLinkRequest(RxInfo &aRxInfo)
{
Error error = kErrorNone;
LinkAcceptInfo info;
DeviceMode mode;
Peer *peer;
uint16_t version;
Log(kMessageReceive, kTypeP2pLinkRequest, aRxInfo.mMessageInfo.GetPeerAddr());
VerifyOrExit(mState == kStateWakingUp, error = kErrorInvalidState);
VerifyOrExit(aRxInfo.mMessageInfo.GetPeerAddr().IsLinkLocalUnicast(), error = kErrorDrop);
info.mExtAddress.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid());
VerifyOrExit(Get<NeighborTable>().FindNeighbor(info.mExtAddress, Neighbor::kInStateAnyExceptInvalid) == nullptr,
error = kErrorDrop);
SuccessOrExit(error = aRxInfo.mMessage.ReadModeTlv(mode));
// TODO: support the rx-off-when-idle device later.
VerifyOrExit(mode.IsRxOnWhenIdle(), error = kErrorDrop);
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(info.mRxChallenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadVersionTlv(version));
Get<Mle>().ProcessKeySequence(aRxInfo);
VerifyOrExit((peer = mPeerTable.GetNewPeer()) != nullptr, error = kErrorNoBufs);
Get<Mle>().InitNeighbor(*peer, aRxInfo);
peer->SetDeviceMode(mode);
peer->SetVersion(version);
peer->SetState(Neighbor::kStateLinkRequest);
SuccessOrExit(error = SendP2pLinkAcceptAndRequest(info));
Get<WakeupTxScheduler>().Stop();
mState = kStateWaitingLinkAccept;
mTimer.Start(kEstablishP2pLinkTimeoutUs);
exit:
LogProcessError(kTypeP2pLinkRequest, error);
}
Error Mle::P2p::SendP2pLinkAcceptAndRequest(const LinkAcceptInfo &aInfo)
{
return SendP2pLinkAcceptVariant(aInfo, true /* aIsLinkAcceptAndRequest*/);
}
void Mle::P2p::HandleP2pLinkAccept(RxInfo &aRxInfo) { HandleP2pLinkAcceptVariant(aRxInfo, kTypeP2pLinkAccept); }
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
void Mle::P2p::HandleP2pWakeup(const Mac::WakeupInfo &aWakeupInfo)
{
Peer *peer = nullptr;
VerifyOrExit(mState == kStateIdle);
peer = mPeerTable.FindPeer(aWakeupInfo.mExtAddress, Peer::kInStateAnyExceptInvalid);
VerifyOrExit(peer == nullptr);
peer = mPeerTable.GetNewPeer();
VerifyOrExit(peer != nullptr);
peer->GetLinkInfo().Clear();
peer->ResetLinkFailures();
peer->SetLastHeard(TimerMilli::GetNow());
peer->SetExtAddress(aWakeupInfo.mExtAddress);
peer->SetState(Neighbor::kStateRestored);
mPeer = peer;
mState = kStateAttachDelay;
mTimer.Start(aWakeupInfo.mAttachDelayMs * Time::kOneMsecInUsec);
exit:
if (peer == nullptr)
{
SetWakeupListenerEnabled();
}
return;
}
void Mle::P2p::SendP2pLinkRequest(Peer *aPeer)
{
Error error = kErrorNone;
TxMessage *message = nullptr;
Ip6::Address destination;
VerifyOrExit(aPeer != nullptr, error = kErrorInvalidArgs);
VerifyOrExit((message = Get<Mle>().NewMleMessage(kCommandP2pLinkRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = message->AppendModeTlv());
SuccessOrExit(error = message->AppendVersionTlv());
aPeer->GenerateChallenge();
SuccessOrExit(error = message->AppendChallengeTlv(aPeer->GetChallenge()));
aPeer->GetLinkLocalIp6Address(destination);
SuccessOrExit(error = message->SendTo(destination));
aPeer->SetState(Neighbor::kStateLinkRequest);
mState = kStateWaitingLinkAcceptAndRequest;
mTimer.Start(kEstablishP2pLinkTimeoutUs);
Log(kMessageSend, kTypeP2pLinkRequest, destination);
exit:
if (error != kErrorNone)
{
if (aPeer != nullptr)
{
aPeer->SetState(Neighbor::kStateInvalid);
}
mState = kStateIdle;
SetWakeupListenerEnabled();
}
FreeMessageOnError(message, error);
}
void Mle::P2p::HandleP2pLinkAcceptAndRequest(RxInfo &aRxInfo)
{
HandleP2pLinkAcceptVariant(aRxInfo, kTypeP2pLinkAcceptAndRequest);
}
Error Mle::P2p::SendP2pLinkAccept(const LinkAcceptInfo &aInfo)
{
return SendP2pLinkAcceptVariant(aInfo, false /* aIsLinkAcceptAndRequest*/);
}
#endif // OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
Error Mle::P2p::SendP2pLinkAcceptVariant(const LinkAcceptInfo &aInfo, bool aIsLinkAcceptAndRequest)
{
Error error = kErrorNone;
Command command = aIsLinkAcceptAndRequest ? kCommandP2pLinkAcceptAndRequest : kCommandP2pLinkAccept;
TxMessage *message = nullptr;
Peer *peer = nullptr;
Ip6::Address destination;
VerifyOrExit((message = Get<Mle>().NewMleMessage(command)) != nullptr, error = kErrorNoBufs);
if (command == kCommandP2pLinkAcceptAndRequest)
{
SuccessOrExit(error = message->AppendModeTlv());
SuccessOrExit(error = message->AppendVersionTlv());
}
SuccessOrExit(error = message->AppendResponseTlv(aInfo.mRxChallenge));
if (command == kCommandP2pLinkAcceptAndRequest)
{
VerifyOrExit((peer = mPeerTable.FindPeer(aInfo.mExtAddress, Peer::kInStateLinkRequest)) != nullptr,
error = kErrorNotFound);
peer->GenerateChallenge();
SuccessOrExit(error = message->AppendChallengeTlv(peer->GetChallenge()));
message->SetDirectTransmission();
}
else
{
peer = mPeerTable.FindPeer(aInfo.mExtAddress, Peer::kInStateValid);
VerifyOrExit(peer != nullptr, error = kErrorNotFound);
}
SuccessOrExit(error = message->AppendLinkMarginTlv(aInfo.mLinkMargin));
SuccessOrExit(error = message->AppendLinkAndMleFrameCounterTlvs());
peer->GetLinkLocalIp6Address(destination);
SuccessOrExit(error = message->SendTo(destination));
if (command == kCommandP2pLinkAccept)
{
mState = kStateIdle;
mTimer.Stop();
SetWakeupListenerEnabled();
LogInfo("P2P link to %s is established", aInfo.mExtAddress.ToString().AsCString());
mEventCallback.InvokeIfSet(OT_P2P_EVENT_LINKED, &aInfo.mExtAddress);
}
Log(kMessageSend, (command == kCommandP2pLinkAccept) ? kTypeP2pLinkAccept : kTypeP2pLinkAcceptAndRequest,
destination);
exit:
FreeMessageOnError(message, error);
return error;
}
void Mle::P2p::HandleP2pLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType)
{
Error error = kErrorNone;
DeviceMode mode;
uint16_t version;
RxChallenge response;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
Peer *peer;
LinkAcceptInfo info;
uint8_t linkMargin;
Log(kMessageReceive, aMessageType, aRxInfo.mMessageInfo.GetPeerAddr());
info.mExtAddress.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid());
VerifyOrExit((peer = mPeerTable.FindPeer(info.mExtAddress, Peer::kInStateLinkRequest)) != nullptr,
error = kErrorNotFound);
aRxInfo.mNeighbor = peer;
if (aMessageType == kTypeP2pLinkAcceptAndRequest)
{
SuccessOrExit(error = aRxInfo.mMessage.ReadModeTlv(mode));
SuccessOrExit(error = aRxInfo.mMessage.ReadVersionTlv(version));
peer->SetDeviceMode(mode);
peer->SetVersion(version);
}
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
VerifyOrExit(response == peer->GetChallenge(), error = kErrorSecurity);
SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter));
SuccessOrExit(error = Tlv::Find<LinkMarginTlv>(aRxInfo.mMessage, linkMargin));
Get<Mle>().InitNeighbor(*peer, aRxInfo);
peer->SetState(Neighbor::kStateValid);
peer->GetLinkFrameCounters().SetAll(linkFrameCounter);
peer->SetLinkAckFrameCounter(linkFrameCounter);
peer->SetMleFrameCounter(mleFrameCounter);
peer->SetKeySequence(aRxInfo.mKeySequence);
aRxInfo.mClass = RxInfo::kAuthoritativeMessage;
Get<Mle>().ProcessKeySequence(aRxInfo);
if (aMessageType == kTypeP2pLinkAcceptAndRequest)
{
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(info.mRxChallenge));
info.mExtAddress = aRxInfo.mNeighbor->GetExtAddress();
info.mLinkMargin = Get<Mac::Mac>().ComputeLinkMargin(aRxInfo.mMessage.GetAverageRss());
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
SuccessOrExit(error = SendP2pLinkAccept(info));
#endif
}
else
{
LogInfo("P2P link to %s is established", peer->GetExtAddress().ToString().AsCString());
mEventCallback.InvokeIfSet(OT_P2P_EVENT_LINKED, &peer->GetExtAddress());
if (!mPeerTable.HasPeers(Peer::kInStateLinkRequest))
{
// All P2P links have been established.
mState = kStateIdle;
mTimer.Stop();
mLinkDoneCallback.InvokeAndClearIfSet();
}
}
exit:
LogProcessError(aMessageType, error);
}
Error Mle::P2p::Unlink(const Mac::ExtAddress &aExtAddress, P2pUnlinkDoneCallback aCallback, void *aContext)
{
Error error = kErrorNone;
Peer *peer;
VerifyOrExit(mState == kStateIdle, error = kErrorBusy);
VerifyOrExit((peer = mPeerTable.FindPeer(aExtAddress, Peer::kInStateValid)) != nullptr, error = kErrorNotFound);
SuccessOrExit(error = SendLinkTearDown(*peer));
mState = kStateTearingDown;
mUnlinkDoneCallback.Set(aCallback, aContext);
exit:
return error;
}
Error Mle::P2p::SendLinkTearDown(Peer &aPeer)
{
Error error = kErrorNone;
TxMessage *message;
Ip6::Address destination;
aPeer.GetLinkLocalIp6Address(destination);
VerifyOrExit((message = Get<Mle>().NewMleMessage(kCommandP2pLinkTearDown)) != nullptr, error = kErrorNoBufs);
message->RegisterTxCallback(HandleLinkTearDownTxDone, this);
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeP2pLinkTearDown, destination);
exit:
FreeMessageOnError(message, error);
return error;
}
void Mle::P2p::HandleLinkTearDownTxDone(const otMessage *aMessage, otError aError, void *aContext)
{
OT_UNUSED_VARIABLE(aError);
static_cast<Mle::P2p *>(aContext)->HandleLinkTearDownTxDone(AsCoreType(aMessage));
}
void Mle::P2p::HandleLinkTearDownTxDone(const Message &aMessage)
{
Ip6::Header ip6Header;
Mac::ExtAddress extAddress;
Peer *peer;
SuccessOrExit(aMessage.Read(0, ip6Header));
VerifyOrExit(ip6Header.GetDestination().IsLinkLocalUnicast());
extAddress.SetFromIid(ip6Header.GetDestination().GetIid());
peer = mPeerTable.FindPeer(extAddress, Peer::kInStateValid);
if (peer == nullptr)
{
// Peer may have been removed if we received a tear down from it. In this case, we can consider the unlink done.
mState = kStateIdle;
mUnlinkDoneCallback.InvokeAndClearIfSet();
ExitNow();
}
if (!aMessage.GetTxSuccess() && (peer->GetTearDownCount() < Peer::kMaxRetransmitLinkTearDowns))
{
peer->IncrementTearDownCount();
if (SendLinkTearDown(*peer) == kErrorNone)
{
ExitNow();
}
}
PeerUnlinked(*peer);
mUnlinkDoneCallback.InvokeAndClearIfSet();
exit:
return;
}
void Mle::P2p::PeerUnlinked(Peer &aPeer)
{
aPeer.SetState(Neighbor::kStateInvalid);
if (mState == kStateTearingDown)
{
mState = kStateIdle;
}
mEventCallback.InvokeIfSet(OT_P2P_EVENT_UNLINKED, &aPeer.GetExtAddress());
}
void Mle::P2p::HandleP2pLinkTearDown(RxInfo &aRxInfo)
{
Peer *peer;
Mac::ExtAddress extAddress;
Log(kMessageReceive, kTypeP2pLinkTearDown, aRxInfo.mMessageInfo.GetPeerAddr());
VerifyOrExit(aRxInfo.mMessageInfo.GetPeerAddr().IsLinkLocalUnicast());
extAddress.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid());
VerifyOrExit((peer = mPeerTable.FindPeer(extAddress, Peer::kInStateValid)) != nullptr);
Get<Mle>().ProcessKeySequence(aRxInfo);
PeerUnlinked(*peer);
exit:
return;
}
void Mle::P2p::HandleLinkTimer(void)
{
switch (mState)
{
#if OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
case kStateWakingUp:
case kStateWaitingLinkAccept:
{
if (mState == kStateWakingUp)
{
LogInfo("Connection window closed");
}
mState = kStateIdle;
ClearPeersInLinkRequestState();
mLinkDoneCallback.InvokeAndClearIfSet();
}
break;
#endif
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
case kStateAttachDelay:
SendP2pLinkRequest(mPeer);
break;
case kStateWaitingLinkAcceptAndRequest:
LogWarn("Waiting for the P2P link accept and request timeout");
mState = kStateIdle;
ClearPeersInLinkRequestState();
SetWakeupListenerEnabled();
break;
#endif
default:
break;
}
}
void Mle::P2p::SetWakeupListenerEnabled(void)
{
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
// The wake-up listener is disabled after a wake-up frame is received, here enables the wake-up listener again.
IgnoreError(Get<Mac::Mac>().SetWakeupListenEnabled(true));
#endif
}
void Mle::P2p::ClearPeersInLinkRequestState(void)
{
for (Peer &peer : mPeerTable.Iterate(Peer::kInStateLinkRequest))
{
peer.SetState(Neighbor::kStateInvalid);
}
}
void Mle::P2p::SetEventCallback(otP2pEventCallback aCallback, void *aContext)
{
mEventCallback.Set(aCallback, aContext);
}
} // namespace Mle
} // namespace ot
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
+22 -48
View File
@@ -39,9 +39,6 @@
#include <stdint.h>
#include <string.h>
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include <openthread/provisional/p2p.h>
#endif
#include <openthread/netdiag.h>
#include <openthread/thread.h>
#include <openthread/thread_ftd.h>
@@ -145,32 +142,28 @@ enum Status : uint8_t
*/
enum Command : uint8_t
{
kCommandLinkRequest = 0, ///< Link Request command
kCommandLinkAccept = 1, ///< Link Accept command
kCommandLinkAcceptAndRequest = 2, ///< Link Accept And Request command
kCommandLinkReject = 3, ///< Link Reject command
kCommandAdvertisement = 4, ///< Advertisement command
kCommandUpdate = 5, ///< Update command
kCommandUpdateRequest = 6, ///< Update Request command
kCommandDataRequest = 7, ///< Data Request command
kCommandDataResponse = 8, ///< Data Response command
kCommandParentRequest = 9, ///< Parent Request command
kCommandParentResponse = 10, ///< Parent Response command
kCommandChildIdRequest = 11, ///< Child ID Request command
kCommandChildIdResponse = 12, ///< Child ID Response command
kCommandChildUpdateRequest = 13, ///< Child Update Request command
kCommandChildUpdateResponse = 14, ///< Child Update Response command
kCommandAnnounce = 15, ///< Announce command
kCommandDiscoveryRequest = 16, ///< Discovery Request command
kCommandDiscoveryResponse = 17, ///< Discovery Response command
kCommandLinkMetricsManagementRequest = 18, ///< Link Metrics Management Request command
kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response command
kCommandLinkProbe = 20, ///< Link Probe command
kCommandTimeSync = 99, ///< Time Sync command
kCommandP2pLinkRequest = 100, ///< P2P Link Request command
kCommandP2pLinkAccept = 101, ///< P2P Link Accept command
kCommandP2pLinkAcceptAndRequest = 102, ///< P2P Link Accept And Request command
kCommandP2pLinkTearDown = 103, ///< P2P Link Tear Down command
kCommandLinkRequest = 0, ///< Link Request command
kCommandLinkAccept = 1, ///< Link Accept command
kCommandLinkAcceptAndRequest = 2, ///< Link Accept And Request command
kCommandLinkReject = 3, ///< Link Reject command
kCommandAdvertisement = 4, ///< Advertisement command
kCommandUpdate = 5, ///< Update command
kCommandUpdateRequest = 6, ///< Update Request command
kCommandDataRequest = 7, ///< Data Request command
kCommandDataResponse = 8, ///< Data Response command
kCommandParentRequest = 9, ///< Parent Request command
kCommandParentResponse = 10, ///< Parent Response command
kCommandChildIdRequest = 11, ///< Child ID Request command
kCommandChildIdResponse = 12, ///< Child ID Response command
kCommandChildUpdateRequest = 13, ///< Child Update Request command
kCommandChildUpdateResponse = 14, ///< Child Update Response command
kCommandAnnounce = 15, ///< Announce command
kCommandDiscoveryRequest = 16, ///< Discovery Request command
kCommandDiscoveryResponse = 17, ///< Discovery Response command
kCommandLinkMetricsManagementRequest = 18, ///< Link Metrics Management Request command
kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response command
kCommandLinkProbe = 20, ///< Link Probe command
kCommandTimeSync = 99, ///< Time Sync command
};
/**
@@ -1002,22 +995,6 @@ inline bool IsChildRloc16(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16)
*/
const char *RoleToString(DeviceRole aRole);
#if OPENTHREAD_CONFIG_P2P_ENABLE && OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* Represents a P2P request.
*/
class P2pRequest : public otP2pRequest
{
public:
/**
* Gets the wake-up request.
*
* @returns The wake-up request.
*/
const Mac::WakeupRequest &GetWakeupRequest(void) const { return AsCoreType(&mWakeupRequest); }
};
#endif // OPENTHREAD_CONFIG_P2P_ENABLE && OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
/**
* @}
*/
@@ -1030,9 +1007,6 @@ DefineMapEnum(otDeviceRole, Mle::DeviceRole);
DefineCoreType(otDeviceProperties, Mle::DeviceProperties);
DefineMapEnum(otPowerSupply, Mle::DeviceProperties::PowerSupply);
#endif
#if OPENTHREAD_CONFIG_P2P_ENABLE && OPENTHREAD_CONFIG_TD_WAKE_INITIATOR_ENABLE
DefineCoreType(otP2pRequest, Mle::P2pRequest);
#endif
} // namespace ot
-14
View File
@@ -90,13 +90,6 @@ Neighbor *NeighborTable::FindNeighbor(const Neighbor::AddressMatcher &aMatcher)
neighbor = FindParent(aMatcher);
}
#if OPENTHREAD_CONFIG_P2P_ENABLE
if (neighbor == nullptr)
{
neighbor = FindPeer(aMatcher);
}
#endif
return neighbor;
}
@@ -121,13 +114,6 @@ Neighbor *NeighborTable::FindNeighbor(const Mac::Address &aMacAddress, Neighbor:
return FindNeighbor(Neighbor::AddressMatcher(aMacAddress, aFilter));
}
#if OPENTHREAD_CONFIG_P2P_ENABLE
Neighbor *NeighborTable::FindPeer(const Neighbor::AddressMatcher &aMatcher)
{
return Get<PeerTable>().FindPeer(aMatcher);
}
#endif
#if OPENTHREAD_FTD
Neighbor *NeighborTable::FindChildOrRouter(const Neighbor::AddressMatcher &aMatcher)
-4
View File
@@ -162,10 +162,6 @@ public:
Neighbor *FindNeighbor(const Mac::Address &aMacAddress,
Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
#if OPENTHREAD_CONFIG_P2P_ENABLE
Neighbor *FindPeer(const Neighbor::AddressMatcher &aMatcher);
#endif
#if OPENTHREAD_FTD
/**
-64
View File
@@ -1,64 +0,0 @@
/*
* Copyright (c) 2025, 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.
*/
/**
* @file
* This file includes definitions for a Thread P2P `Peer`.
*/
#include "peer.hpp"
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include "instance/instance.hpp"
namespace ot {
void Peer::Clear(void)
{
Instance &instance = GetInstance();
ClearAllBytes(*this);
Init(instance);
}
void Peer::SetDeviceMode(Mle::DeviceMode aMode)
{
VerifyOrExit(aMode != GetDeviceMode());
Neighbor::SetDeviceMode(aMode);
VerifyOrExit(IsStateValid());
exit:
return;
}
} // namespace ot
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
-126
View File
@@ -1,126 +0,0 @@
/*
* Copyright (c) 2025, 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.
*/
/**
* @file
* This file includes definitions for a Thread P2P `Peer`.
*/
#ifndef OT_CORE_THREAD_PEER_HPP_
#define OT_CORE_THREAD_PEER_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include "thread/neighbor.hpp"
namespace ot {
/**
* Represents a P2P Peer.
*/
class Peer : public CslNeighbor
{
public:
/**
* Max number of re-transmitted the P2P link tear down messages.
*/
static constexpr uint8_t kMaxRetransmitLinkTearDowns = 4;
/**
* Initializes the `Peer` object.
*
* @param[in] aInstance The OpenThread instance.
*/
void Init(Instance &aInstance)
{
Neighbor::Init(aInstance);
mTearDownCount = 0;
}
/**
* Clears the peer entry.
*/
void Clear(void);
/**
* Sets the device mode flags.
*
* @param[in] aMode The device mode flags.
*/
void SetDeviceMode(Mle::DeviceMode aMode);
/**
* Gets the link local IPv6 address of the peer.
*
* @returns The link local IPv6 address of the peer.
*/
void GetLinkLocalIp6Address(Ip6::Address &aIp6Address) const
{
aIp6Address.InitAsLinkLocalAddress(GetExtAddress());
}
/**
* Generates a new challenge value to use during a child attach.
*/
void GenerateChallenge(void) { mAttachChallenge.GenerateRandom(); }
/**
* Gets the current challenge value used during attach.
*
* @returns The current challenge value.
*/
const Mle::TxChallenge &GetChallenge(void) const { return mAttachChallenge; }
/**
* Increments the count of re-transmitted link tear down messages.
*/
void IncrementTearDownCount(void) { mTearDownCount++; }
/**
* Resets the count of re-transmitted link tear down messages to zero.
*/
void ResetTearDownCount(void) { mTearDownCount = 0; }
/**
* Returns the count of re-transmitted link tear down messages.
*/
uint8_t GetTearDownCount(void) const { return mTearDownCount; }
private:
Mle::TxChallenge mAttachChallenge;
uint8_t mTearDownCount : 3; // The count of re-transmitted link tear down messages.
};
} // namespace ot
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
#endif // OT_CORE_THREAD_PEER_HPP_
-135
View File
@@ -1,135 +0,0 @@
/*
* Copyright (c) 2025, 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.
*/
/**
* @file
* This file includes definitions for the Thread Peer table.
*/
#include "peer_table.hpp"
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include "instance/instance.hpp"
namespace ot {
PeerTable::Iterator::Iterator(Instance &aInstance, Peer::StateFilter aFilter)
: InstanceLocator(aInstance)
, ItemPtrIterator(nullptr)
, mFilter(aFilter)
{
Reset();
}
void PeerTable::Iterator::Reset(void)
{
mItem = &Get<PeerTable>().mPeers[0];
if (!mItem->Matches(mFilter))
{
Advance();
}
}
void PeerTable::Iterator::Advance(void)
{
VerifyOrExit(mItem != nullptr);
do
{
mItem++;
VerifyOrExit(mItem < &Get<PeerTable>().mPeers[Get<PeerTable>().kMaxPeers], mItem = nullptr);
} while (!mItem->Matches(mFilter));
exit:
return;
}
PeerTable::PeerTable(Instance &aInstance)
: InstanceLocator(aInstance)
{
for (Peer &peer : mPeers)
{
peer.Init(aInstance);
peer.Clear();
}
}
void PeerTable::Clear(void)
{
for (Peer &peer : mPeers)
{
peer.Clear();
}
}
Peer *PeerTable::GetNewPeer(void)
{
Peer *peer = FindPeer(Peer::AddressMatcher(Peer::kInStateInvalid));
VerifyOrExit(peer != nullptr);
peer->Clear();
exit:
return peer;
}
const Peer *PeerTable::FindPeer(const Peer::AddressMatcher &aMatcher) const
{
const Peer *peer = mPeers;
for (uint16_t num = kMaxPeers; num != 0; num--, peer++)
{
if (peer->Matches(aMatcher))
{
ExitNow();
}
}
peer = nullptr;
exit:
return peer;
}
Peer *PeerTable::FindPeer(const Mac::ExtAddress &aExtAddress, Peer::StateFilter aFilter)
{
return FindPeer(Peer::AddressMatcher(aExtAddress, aFilter));
}
bool PeerTable::HasPeers(Peer::StateFilter aFilter) const
{
return (FindPeer(Peer::AddressMatcher(aFilter)) != nullptr);
}
bool PeerTable::IsFull(void) const { return FindPeer(Peer::AddressMatcher(Peer::kInStateInvalid)) == nullptr; }
} // namespace ot
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
-190
View File
@@ -1,190 +0,0 @@
/*
* Copyright (c) 2025, 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.
*/
/**
* @file
* This file includes definitions for the Thread Peer table.
*/
#ifndef OT_CORE_THREAD_PEER_TABLE_HPP_
#define OT_CORE_THREAD_PEER_TABLE_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_P2P_ENABLE
#include "common/const_cast.hpp"
#include "common/iterator_utils.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "thread/peer.hpp"
namespace ot {
/**
* Represents the Thread Peer table.
*/
class PeerTable : public InstanceLocator, private NonCopyable
{
friend class NeighborTable;
class IteratorBuilder;
public:
/**
* Represents an iterator for iterating through the peer entries in the peer table.
*/
class Iterator : public InstanceLocator, public ItemPtrIterator<Peer, Iterator>
{
friend class ItemPtrIterator<Peer, Iterator>;
friend class IteratorBuilder;
public:
/**
* Initializes an `Iterator` instance.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aFilter A peer state filter.
*/
Iterator(Instance &aInstance, Peer::StateFilter aFilter);
/**
* Resets the iterator to start over.
*/
void Reset(void);
/**
* Gets the `Peer` entry to which the iterator is currently pointing.
*
* @returns A pointer to the `Peer` entry, or `nullptr` if the iterator is done and/or empty.
*/
Peer *GetPeer(void) { return mItem; }
private:
explicit Iterator(Instance &aInstance)
: InstanceLocator(aInstance)
, mFilter(Peer::StateFilter::kInStateValid)
{
}
void Advance(void);
Peer::StateFilter mFilter;
};
/**
* Initializes a `PeerTable` instance.
*
* @param[in] aInstance A reference to the OpenThread instance.
*/
explicit PeerTable(Instance &aInstance);
/**
* Clears the peer table.
*/
void Clear(void);
/**
* Gets a new/unused `Peer` entry from the peer table.
*
* @note The returned peer entry will be cleared (`memset` to zero).
*
* @returns A pointer to a new `Peer` entry, or `nullptr` if all `Peer` entries are in use.
*/
Peer *GetNewPeer(void);
/**
* Searches the peer table for a `Peer` with a given extended address also matching a given state
* filter.
*
* @param[in] aExtAddress A reference to an extended address.
* @param[in] aFilter A peer state filter.
*
* @returns A pointer to the `Peer` entry if one is found, or `nullptr` otherwise.
*/
Peer *FindPeer(const Mac::ExtAddress &aExtAddress, Peer::StateFilter aFilter);
/**
* Indicates whether the peer table contains any peer matching a given state filter.
*
* @param[in] aFilter A peer state filter.
*
* @returns TRUE if the table contains at least one peer table matching the given filter, FALSE otherwise.
*/
bool HasPeers(Peer::StateFilter aFilter) const;
/**
* Enables range-based `for` loop iteration over all peer entries in the peer table matching a given
* state filter.
*
* Should be used as follows:
*
* for (Peer &peer : aPeerTable.Iterate(aFilter)) { ... }
*
* @param[in] aFilter A peer state filter.
*
* @returns An IteratorBuilder instance.
*/
IteratorBuilder Iterate(Peer::StateFilter aFilter) { return IteratorBuilder(GetInstance(), aFilter); }
/**
* Indicates whether the peer table is full.
*
* @returns TRUE if the table is full, FALSE otherwise.
*/
bool IsFull(void) const;
private:
static constexpr uint16_t kMaxPeers = OPENTHREAD_CONFIG_P2P_MAX_PEERS;
class IteratorBuilder : public InstanceLocator
{
public:
IteratorBuilder(Instance &aInstance, Peer::StateFilter aFilter)
: InstanceLocator(aInstance)
, mFilter(aFilter)
{
}
Iterator begin(void) { return Iterator(GetInstance(), mFilter); }
Iterator end(void) { return Iterator(GetInstance()); }
private:
Peer::StateFilter mFilter;
};
Peer *FindPeer(const Peer::AddressMatcher &aMatcher) { return AsNonConst(AsConst(this)->FindPeer(aMatcher)); }
const Peer *FindPeer(const Peer::AddressMatcher &aMatcher) const;
Peer mPeers[kMaxPeers];
};
} // namespace ot
#endif // OPENTHREAD_CONFIG_P2P_ENABLE
#endif // OT_CORE_THREAD_PEER_TABLE_HPP_