mirror of
https://github.com/espressif/openthread.git
synced 2026-09-30 04:47:42 +00:00
[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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
Reference in New Issue
Block a user