Skip to content

Commit

Permalink
[wed] save wake-up parent when receiving a wake-up frame
Browse files Browse the repository at this point in the history
This commit introduces a basic `CslNeighborTable` which currently
assumes a single enhanced CSL capable neighbor: the Wake-up Parent.

When a valid wake-up frame is received the sender's information is
used to add such `CslNeighbor` to the table. `IndirectSender` and
`CslTxScheduler` modules are refactored to be able to enqueue
messages for enhanced CSL neighbors.

Actual link establishment actions are to be added in later commits.
  • Loading branch information
edmont committed Dec 13, 2024
1 parent c2d5265 commit 178c2c1
Show file tree
Hide file tree
Showing 19 changed files with 609 additions and 106 deletions.
2 changes: 2 additions & 0 deletions src/core/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ openthread_core_files = [
"thread/dua_manager.hpp",
"thread/energy_scan_server.cpp",
"thread/energy_scan_server.hpp",
"thread/enh_csl_neighbor_table.cpp",
"thread/enh_csl_neighbor_table.hpp",
"thread/indirect_sender.cpp",
"thread/indirect_sender.hpp",
"thread/indirect_sender_frame_context.hpp",
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ set(COMMON_SOURCES
thread/discover_scanner.cpp
thread/dua_manager.cpp
thread/energy_scan_server.cpp
thread/enh_csl_neighbor_table.cpp
thread/indirect_sender.cpp
thread/key_manager.cpp
thread/link_metrics.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/core/common/locator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ template <class InstanceGetProvider> class GetProvider
*
* @returns A reference to the `Type` object of the instance.
*/
template <typename Type> inline Type &Get(void) const; // Implemented in `locator_getters.hpp`.
template <typename Type> inline Type &Get(void) const;

protected:
GetProvider(void) = default;
Expand Down
20 changes: 20 additions & 0 deletions src/core/common/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ class Buffer : public otMessageBuffer, public LinkedListEntry<Buffer>
#endif
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
bool mTimeSync : 1; // Whether the message is also used for time sync purpose.
#endif
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
bool mIsEnhCslNeighbor : 1; // Whether the message is for an enhanced CSL neighbor.
#endif
uint8_t mPriority : 2; // The message priority level (higher value is higher priority).
uint8_t mOrigin : 2; // The origin of the message.
Expand Down Expand Up @@ -1469,6 +1472,23 @@ class Message : public otMessage, public Buffer, public GetProvider<Message>

#endif // #if OPENTHREAD_CONFIG_MULTI_RADIO

#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
/**
* Indicates whether the message is destined for an enhanced CSL neighbor.
*
* @retval TRUE If the message is destined for an enhanced CSL neighbor.
* @retval FALSE If the message is not destined for an enhanced CSL neighbor.
*/
bool IsForEnhancedCslNeighbor(void) const { return GetMetadata().mIsEnhCslNeighbor; }

/**
* Sets whether the message is destined for an enhanced CSL neighbor.
*
* @param[in] aIsEnhCslNeighbor TRUE if the message is destined for an enhanced CSL neighbor, FALSE otherwise.
*/
void SetForEnhancedCslNeighbor(bool aIsEnhCslNeighbor) { GetMetadata().mIsEnhCslNeighbor = aIsEnhCslNeighbor; }
#endif

protected:
class ConstIterator : public ItemPtrIterator<const Message, ConstIterator>
{
Expand Down
19 changes: 19 additions & 0 deletions src/core/config/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,25 @@
#define OPENTHREAD_CONFIG_MAC_DATA_POLL_TIMEOUT 100
#endif

/**
* @def OPENTHREAD_CONFIG_MAC_CSL_WAKEUP_INTERVAL
*
* Periodicity of wake-up frame transmission by WC (in units of 10 symbols).
*/
#ifndef OPENTHREAD_CONFIG_MAC_CSL_WAKEUP_INTERVAL
#define OPENTHREAD_CONFIG_MAC_CSL_WAKEUP_INTERVAL 47
#endif

/**
* @def OPENTHREAD_CONFIG_MAC_ENH_CSL_TX_ATTEMPTS
*
* Maximum number of TX attempts for the enhanced CSL communication before considering the peer de-synchronized.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_ENH_CSL_TX_ATTEMPTS
#define OPENTHREAD_CONFIG_MAC_ENH_CSL_TX_ATTEMPTS 8
#endif

/**
* @}
*/
Expand Down
2 changes: 1 addition & 1 deletion src/core/mac/data_poll_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ void DataPollHandler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError,
OT_ASSERT(false);
}

Get<IndirectSender>().HandleSentFrameToChild(aFrame, mFrameContext, aError, aChild);
Get<IndirectSender>().HandleSentFrameToCslNeighbor(aFrame, mFrameContext, aError, aChild);

exit:
return;
Expand Down
38 changes: 25 additions & 13 deletions src/core/mac/mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,8 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
{
uint32_t sequence;

// TODO: Avoid generating a new key if a wake-up frame was recently received already
// Avoid generating a new key if a wake-up frame was recently received already
VerifyOrExit(!Get<Mle::Mle>().IsWakeupParentPresent(), error = kErrorInvalidState);

IgnoreError(aFrame.GetKeyId(keyid));
sequence = BigEndian::ReadUint32(aFrame.GetKeySource());
Expand Down Expand Up @@ -2472,22 +2473,15 @@ bool Mac::IsCslSupported(void) const

void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr)
{
CslNeighbor *neighbor = nullptr;
CslNeighbor *neighbor = Get<Mle::Mle>().FindCslNeighbor(aSrcAddr);
const CslIe *csl;

VerifyOrExit(neighbor != nullptr);
VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled());

csl = aFrame.GetCslIe();
VerifyOrExit(csl != nullptr);

#if OPENTHREAD_FTD
neighbor = Get<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid);
#else
OT_UNUSED_VARIABLE(aSrcAddr);
#endif

VerifyOrExit(neighbor != nullptr);

VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod);

neighbor->SetCslPeriod(csl->GetPeriod());
Expand Down Expand Up @@ -2620,14 +2614,17 @@ void Mac::UpdateWakeupListening(void)

Error Mac::HandleWakeupFrame(const RxFrame &aFrame)
{
Error error = kErrorNone;
Error error = kErrorNone;
constexpr uint32_t kWakeupIntervalUs = kDefaultWakeupInterval * kUsPerTenSymbols;
const ConnectionIe *connectionIe;
uint32_t rvTimeUs;
uint64_t rvTimestampUs;
uint32_t attachDelayMs;
uint64_t radioNowUs;
uint8_t retryInterval;
uint8_t retryCount;
Address parentAddress;
CslNeighbor *parent;

VerifyOrExit(mWakeupListenEnabled && aFrame.IsWakeupFrame());
connectionIe = aFrame.GetConnectionIe();
Expand Down Expand Up @@ -2662,8 +2659,23 @@ Error Mac::HandleWakeupFrame(const RxFrame &aFrame)
// Stop receiving more wake up frames
IgnoreError(SetWakeupListenEnabled(false));

// TODO: start MLE attach process with the WC
OT_UNUSED_VARIABLE(attachDelayMs);
IgnoreError(aFrame.GetSrcAddr(parentAddress));
Get<Mle::Mle>().AddWakeupParent(parentAddress.GetExtended(), TimerMilli::GetNow() + attachDelayMs,
kWakeupIntervalUs * retryInterval * retryCount / 1000);

parent = Get<Mle::Mle>().GetWakeupParent();
OT_ASSERT(parent != nullptr);
parent->SetCslPeriod(kDefaultWakeupInterval * retryInterval);
parent->SetCslPhase(0);
parent->SetCslSynchronized(true);
parent->SetCslLastHeard(TimerMilli::GetNow());
// Rendezvous time is the time when the WC begins listening for the connection request from the awakened WED.
// Since EnhCslSender schedules a frame's PHR at `LastRxTimestamp + Phase + n*Period`, increase the timestamp
// by SHR length and the CSL uncertainty to make sure SHR begins while the WC is already listening.
parent->SetLastRxTimestamp(rvTimestampUs + kRadioHeaderShrDuration + Get<Radio>().GetCslUncertainty() * 10);
parent->SetEnhCslMaxTxAttempts(retryCount);

Get<Mle::Mle>().AttachToWakeupParent();

exit:
return error;
Expand Down
1 change: 1 addition & 0 deletions src/core/mac/mac.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ constexpr uint16_t kMinCslIePeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD;

constexpr uint32_t kDefaultWedListenInterval = OPENTHREAD_CONFIG_WED_LISTEN_INTERVAL;
constexpr uint32_t kDefaultWedListenDuration = OPENTHREAD_CONFIG_WED_LISTEN_DURATION;
constexpr uint16_t kDefaultWakeupInterval = OPENTHREAD_CONFIG_MAC_CSL_WAKEUP_INTERVAL;

/**
* Defines the function pointer called on receiving an IEEE 802.15.4 Beacon during an Active Scan.
Expand Down
29 changes: 23 additions & 6 deletions src/core/thread/csl_tx_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class CslTxScheduler : public InstanceLocator, private NonCopyable

public:
static constexpr uint8_t kMaxCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS;
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
static constexpr uint8_t kMaxEnhCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_ENH_CSL_TX_ATTEMPTS;
#endif

/**
* Defines all the neighbor info required for scheduling CSL transmissions.
Expand Down Expand Up @@ -98,13 +101,27 @@ class CslTxScheduler : public InstanceLocator, private NonCopyable
uint64_t GetLastRxTimestamp(void) const { return mLastRxTimestamp; }
void SetLastRxTimestamp(uint64_t aLastRxTimestamp) { mLastRxTimestamp = aLastRxTimestamp; }

#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
uint8_t GetEnhCslMaxTxAttempts(void) const
{
return mCslMaxTxAttempts != 0 ? mCslMaxTxAttempts : kMaxEnhCslTriggeredTxAttempts;
}
void SetEnhCslMaxTxAttempts(uint8_t txAttempts) { mCslMaxTxAttempts = txAttempts; }
void ResetEnhCslMaxTxAttempts() { mCslMaxTxAttempts = 0; }
#endif

private:
uint8_t mCslTxAttempts : 7; ///< Number of CSL triggered tx attempts.
bool mCslSynchronized : 1; ///< Indicates whether or not the child is CSL synchronized.
uint8_t mCslChannel; ///< The channel the device will listen on.
uint32_t mCslTimeout; ///< The sync timeout, in seconds.
uint16_t mCslPeriod; ///< CSL sampled listening period between consecutive channel samples in units of 10
///< symbols (160 microseconds).
uint8_t mCslTxAttempts : 7; ///< Number of CSL triggered tx attempts.
bool mCslSynchronized : 1; ///< Indicates whether or not the child is CSL synchronized.
uint8_t mCslChannel; ///< The channel the device will listen on.

#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
uint8_t mCslMaxTxAttempts; ///< Override for the maximum number of enhanced CSL triggered tx attempts.
#endif

uint32_t mCslTimeout; ///< The sync timeout, in seconds.
uint16_t mCslPeriod; ///< CSL sampled listening period between consecutive channel samples in units of 10
///< symbols (160 microseconds).

/**
* The time in units of 10 symbols from the first symbol of the frame
Expand Down
56 changes: 56 additions & 0 deletions src/core/thread/enh_csl_neighbor_table.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 includes definitions for enhanced CSL neighbor table.
*/

#include "enh_csl_neighbor_table.hpp"

#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE

#include "instance/instance.hpp"

namespace ot {

CslNeighborTable::CslNeighborTable(Instance &aInstance)
{
for (CslNeighbor &cslNeighbor : mCslNeighbors)
{
cslNeighbor.Init(aInstance);
}
}

CslNeighbor *CslNeighborTable::GetNewCslNeighbor(void) { return mCslNeighbors; }

CslNeighbor *CslNeighborTable::GetFirstCslNeighbor(void) { return mCslNeighbors; }

} // namespace ot

#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
89 changes: 89 additions & 0 deletions src/core/thread/enh_csl_neighbor_table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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 includes definitions for the CSL neighbors table.
*/

#ifndef ENH_CSL_NEIGHBOR_TABLE_HPP_
#define ENH_CSL_NEIGHBOR_TABLE_HPP_

#include "openthread-core-config.h"

#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE

#include "common/const_cast.hpp"
#include "common/iterator_utils.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "thread/neighbor.hpp"

namespace ot {

/**
* Represents the CSL neighbors table.
*/
class CslNeighborTable : private NonCopyable
{
public:
/**
* Initializes a `CslNeighborTable` instance.
*
* @param[in] aInstance A reference to the OpenThread instance.
*/
explicit CslNeighborTable(Instance &aInstance);

/**
* Gets a new/unused `CslNeighbor` entry from the enhanced CSL neighbor table.
*
* @note The returned neighbor entry will be cleared (`memset` to zero).
*
* @returns A pointer to a new `CslNeighbor` entry, or `nullptr` if all `CslNeighbor` entries are in use.
*/
CslNeighbor *GetNewCslNeighbor(void);

/**
* Gets the first `CslNeighbor` entry in the enhanced CSL neighbor table.
*
* @returns A pointer to the first `CslNeighbor` entry, or `nullptr` if the table is empty.
*/
CslNeighbor *GetFirstCslNeighbor(void);

private:
// static constexpr uint16_t kMaxCslNeighbors = OPENTHREAD_CONFIG_MLE_MAX_ENH_CSL_NEIGHBORS;
static constexpr uint16_t kMaxCslNeighbors = 1;

CslNeighbor mCslNeighbors[kMaxCslNeighbors];
};

} // namespace ot

#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE

#endif // ENH_CSL_NEIGHBOR_TABLE_HPP_
Loading

0 comments on commit 178c2c1

Please sign in to comment.