mirror of
https://github.com/espressif/openthread.git
synced 2026-10-03 22:37:36 +00:00
[mac] enable wake-up frame periodic sniffing (#10762)
When `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE` is enabled: - APIs are available to configure and enable wake-up frames sniffing. - `SubMac::HandleWedTimer` periodically schedules receive slots on wake-up channel. - Wake-up frames are processed. - Upon reception of a wake-up frame, WUL is stopped.
This commit is contained in:
@@ -52,7 +52,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (454)
|
#define OPENTHREAD_API_VERSION (455)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
|||||||
@@ -1126,6 +1126,60 @@ uint8_t otLinkGetWakeupChannel(otInstance *aInstance);
|
|||||||
*/
|
*/
|
||||||
otError otLinkSetWakeupChannel(otInstance *aInstance, uint8_t aChannel);
|
otError otLinkSetWakeupChannel(otInstance *aInstance, uint8_t aChannel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables listening for wake-up frames.
|
||||||
|
*
|
||||||
|
* Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aEnable true to enable listening for wake-up frames, or false otherwise.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully enabled / disabled the listening for wake-up frames.
|
||||||
|
* @retval OT_ERROR_INVALID_ARGS The listen duration is greater than the listen interval.
|
||||||
|
* @retval OT_ERROR_INVALID_STATE Could not enable listening for wake-up frames due to bad configuration.
|
||||||
|
*/
|
||||||
|
otError otLinkSetWakeUpListenEnabled(otInstance *aInstance, bool aEnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether listening for wake-up frames is enabled.
|
||||||
|
*
|
||||||
|
* Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
*
|
||||||
|
* @retval TRUE If listening for wake-up frames is enabled.
|
||||||
|
* @retval FALSE If listening for wake-up frames is not enabled.
|
||||||
|
*/
|
||||||
|
bool otLinkIsWakeupListenEnabled(otInstance *aInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the wake-up listen parameters.
|
||||||
|
*
|
||||||
|
* Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[out] aInterval A pointer to return the wake-up listen interval in microseconds.
|
||||||
|
* @param[out] aDuration A pointer to return the wake-up listen duration in microseconds.
|
||||||
|
*/
|
||||||
|
void otLinkGetWakeupListenParameters(otInstance *aInstance, uint32_t *aInterval, uint32_t *aDuration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the wake-up listen parameters.
|
||||||
|
*
|
||||||
|
* The listen interval must be greater than the listen duration.
|
||||||
|
* The listen duration must be greater or equal than the minimum supported.
|
||||||
|
*
|
||||||
|
* Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aInterval The wake-up listen interval in microseconds.
|
||||||
|
* @param[in] aDuration The wake-up listen duration in microseconds.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully set the wake-up listen parameters.
|
||||||
|
* @retval OT_ERROR_INVALID_ARGS Invalid wake-up listen parameters.
|
||||||
|
*/
|
||||||
|
otError otLinkSetWakeupListenParameters(otInstance *aInstance, uint32_t aInterval, uint32_t aDuration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|||||||
+52
-5
@@ -133,7 +133,7 @@ Done
|
|||||||
- [vendor](#vendor-name)
|
- [vendor](#vendor-name)
|
||||||
- [verhoeff](#verhoeff-calculate)
|
- [verhoeff](#verhoeff-calculate)
|
||||||
- [version](#version)
|
- [version](#version)
|
||||||
- [wakeupchannel](#wakeupchannel)
|
- [wakeup](#wakeup-channel)
|
||||||
|
|
||||||
## OpenThread Command Details
|
## OpenThread Command Details
|
||||||
|
|
||||||
@@ -4402,25 +4402,72 @@ Factory Diagnostics module is enabled only when building OpenThread with `OPENTH
|
|||||||
|
|
||||||
[diag]: ../../src/core/diags/README.md
|
[diag]: ../../src/core/diags/README.md
|
||||||
|
|
||||||
### wakeupchannel
|
### wakeup channel
|
||||||
|
|
||||||
Get the wake-up channel.
|
Get the wake-up channel.
|
||||||
|
|
||||||
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> wakeupchannel
|
> wakeup channel
|
||||||
12
|
12
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
### wakeupchannel \<channel\>
|
### wakeup channel \<channel\>
|
||||||
|
|
||||||
Set the wake-up channel.
|
Set the wake-up channel.
|
||||||
|
|
||||||
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> wakeupchannel 12
|
> wakeup channel 12
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
### wakeup parameters
|
||||||
|
|
||||||
|
Get the wake-up listen interval and duration.
|
||||||
|
|
||||||
|
Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> wakeup parameters
|
||||||
|
interval: 1000000us
|
||||||
|
duration: 8000us
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
### wakeup parameters \<interval\> \<duration\>
|
||||||
|
|
||||||
|
Set the wake-up listen interval and duration.
|
||||||
|
|
||||||
|
Requires `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> wakeup parameters 1000000 8000
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
### wakeup listen
|
||||||
|
|
||||||
|
Show the state of wake-up listening feature.
|
||||||
|
|
||||||
|
`OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE` is required.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> wakeup listen
|
||||||
|
Enabled
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
### wakeup listen \[enable|disable\]
|
||||||
|
|
||||||
|
Enable/disable listening for wake-up frames.
|
||||||
|
|
||||||
|
`OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE` is required.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> wakeup listen enable
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|||||||
+101
-18
@@ -8213,25 +8213,103 @@ exit:
|
|||||||
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
|
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
/**
|
template <> otError Interpreter::Process<Cmd("wakeup")>(Arg aArgs[])
|
||||||
* @cli wakeupchannel (get,set)
|
|
||||||
* @code
|
|
||||||
* wakeupchannel
|
|
||||||
* 12
|
|
||||||
* Done
|
|
||||||
* @endcode
|
|
||||||
* @code
|
|
||||||
* wakeupchannel 12
|
|
||||||
* Done
|
|
||||||
* @endcode
|
|
||||||
* @cparam wakeupchannel [@ca{channel}]
|
|
||||||
* Use `channel` to set the wake-up channel.
|
|
||||||
* @par
|
|
||||||
* Gets or sets the wake-up channel value.
|
|
||||||
*/
|
|
||||||
template <> otError Interpreter::Process<Cmd("wakeupchannel")>(Arg aArgs[])
|
|
||||||
{
|
{
|
||||||
return ProcessGetSet(aArgs, otLinkGetWakeupChannel, otLinkSetWakeupChannel);
|
otError error = OT_ERROR_NONE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @cli wakeup channel (get,set)
|
||||||
|
* @code
|
||||||
|
* wakeup channel
|
||||||
|
* 12
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @code
|
||||||
|
* wakeup channel 12
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @cparam wakeup channel [@ca{channel}]
|
||||||
|
* Use `channel` to set the wake-up channel.
|
||||||
|
* @par
|
||||||
|
* Gets or sets the wake-up channel value.
|
||||||
|
* @sa otLinkGetWakeupChannel
|
||||||
|
* @sa otLinkSetWakeupChannel
|
||||||
|
*/
|
||||||
|
if (aArgs[0] == "channel")
|
||||||
|
{
|
||||||
|
error = ProcessGetSet(aArgs + 1, otLinkGetWakeupChannel, otLinkSetWakeupChannel);
|
||||||
|
}
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
/**
|
||||||
|
* @cli wakeup parameters (get,set)
|
||||||
|
* @code
|
||||||
|
* wakeup parameters
|
||||||
|
* interval: 1000000us
|
||||||
|
* duration: 8000us
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @code
|
||||||
|
* wakeup parameters 1000000 8000
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @cparam wakeup parameters @ca{interval} @ca{duration}
|
||||||
|
* @par
|
||||||
|
* Gets or sets the wake-up listen interval and wake-up listen duration values.
|
||||||
|
* @sa otLinkGetWakeUpListenParameters
|
||||||
|
* @sa otLinkSetWakeUpListenParameters
|
||||||
|
*/
|
||||||
|
else if (aArgs[0] == "parameters")
|
||||||
|
{
|
||||||
|
uint32_t interval;
|
||||||
|
uint32_t duration;
|
||||||
|
|
||||||
|
if (aArgs[1].IsEmpty())
|
||||||
|
{
|
||||||
|
otLinkGetWakeupListenParameters(GetInstancePtr(), &interval, &duration);
|
||||||
|
OutputLine("interval: %luus", ToUlong(interval));
|
||||||
|
OutputLine("duration: %luus", ToUlong(duration));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = aArgs[1].ParseAsUint32(interval));
|
||||||
|
SuccessOrExit(error = aArgs[2].ParseAsUint32(duration));
|
||||||
|
error = otLinkSetWakeupListenParameters(GetInstancePtr(), interval, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @cli wakeup listen (enable,disable)
|
||||||
|
* @code
|
||||||
|
* wakeup listen
|
||||||
|
* disabled
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @code
|
||||||
|
* wakeup listen enable
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @code
|
||||||
|
* wakeup listen
|
||||||
|
* enabled
|
||||||
|
* Done
|
||||||
|
* @endcode
|
||||||
|
* @cparam wakeup listen @ca{enable}
|
||||||
|
* @par
|
||||||
|
* Gets or sets current wake-up listening link state.
|
||||||
|
* @sa otLinkIsWakeupListenEnabled
|
||||||
|
* @sa otLinkSetWakeUpListenEnabled
|
||||||
|
*/
|
||||||
|
else if (aArgs[0] == "listen")
|
||||||
|
{
|
||||||
|
error = ProcessEnableDisable(aArgs + 1, otLinkIsWakeupListenEnabled, otLinkSetWakeUpListenEnabled);
|
||||||
|
}
|
||||||
|
#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
#endif // OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
#endif // OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
|
||||||
@@ -8544,6 +8622,11 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
|
|||||||
#endif
|
#endif
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
CmdEntry("version"),
|
CmdEntry("version"),
|
||||||
|
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
CmdEntry("wakeup"),
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CmdEntry
|
#undef CmdEntry
|
||||||
|
|||||||
@@ -508,6 +508,7 @@ openthread_core_files = [
|
|||||||
"mac/sub_mac.hpp",
|
"mac/sub_mac.hpp",
|
||||||
"mac/sub_mac_callbacks.cpp",
|
"mac/sub_mac_callbacks.cpp",
|
||||||
"mac/sub_mac_csl_receiver.cpp",
|
"mac/sub_mac_csl_receiver.cpp",
|
||||||
|
"mac/sub_mac_wed.cpp",
|
||||||
"meshcop/announce_begin_client.cpp",
|
"meshcop/announce_begin_client.cpp",
|
||||||
"meshcop/announce_begin_client.hpp",
|
"meshcop/announce_begin_client.hpp",
|
||||||
"meshcop/border_agent.cpp",
|
"meshcop/border_agent.cpp",
|
||||||
@@ -777,6 +778,8 @@ openthread_radio_sources = [
|
|||||||
"mac/mac_types.cpp",
|
"mac/mac_types.cpp",
|
||||||
"mac/sub_mac.cpp",
|
"mac/sub_mac.cpp",
|
||||||
"mac/sub_mac_callbacks.cpp",
|
"mac/sub_mac_callbacks.cpp",
|
||||||
|
"mac/sub_mac_csl_receiver.cpp",
|
||||||
|
"mac/sub_mac_wed.cpp",
|
||||||
"radio/radio.cpp",
|
"radio/radio.cpp",
|
||||||
"radio/radio_callbacks.cpp",
|
"radio/radio_callbacks.cpp",
|
||||||
"radio/radio_platform.cpp",
|
"radio/radio_platform.cpp",
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ set(COMMON_SOURCES
|
|||||||
mac/sub_mac.cpp
|
mac/sub_mac.cpp
|
||||||
mac/sub_mac_callbacks.cpp
|
mac/sub_mac_callbacks.cpp
|
||||||
mac/sub_mac_csl_receiver.cpp
|
mac/sub_mac_csl_receiver.cpp
|
||||||
|
mac/sub_mac_wed.cpp
|
||||||
meshcop/announce_begin_client.cpp
|
meshcop/announce_begin_client.cpp
|
||||||
meshcop/border_agent.cpp
|
meshcop/border_agent.cpp
|
||||||
meshcop/commissioner.cpp
|
meshcop/commissioner.cpp
|
||||||
@@ -295,6 +296,7 @@ set(RADIO_COMMON_SOURCES
|
|||||||
mac/sub_mac.cpp
|
mac/sub_mac.cpp
|
||||||
mac/sub_mac_callbacks.cpp
|
mac/sub_mac_callbacks.cpp
|
||||||
mac/sub_mac_csl_receiver.cpp
|
mac/sub_mac_csl_receiver.cpp
|
||||||
|
mac/sub_mac_wed.cpp
|
||||||
radio/radio.cpp
|
radio/radio.cpp
|
||||||
radio/radio_callbacks.cpp
|
radio/radio_callbacks.cpp
|
||||||
radio/radio_platform.cpp
|
radio/radio_platform.cpp
|
||||||
|
|||||||
@@ -504,3 +504,25 @@ otError otLinkGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
otError otLinkSetWakeUpListenEnabled(otInstance *aInstance, bool aEnable)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Mac::Mac>().SetWakeupListenEnabled(aEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool otLinkIsWakeupListenEnabled(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Mac::Mac>().IsWakeupListenEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void otLinkGetWakeupListenParameters(otInstance *aInstance, uint32_t *aInterval, uint32_t *aDuration)
|
||||||
|
{
|
||||||
|
AsCoreType(aInstance).Get<Mac::Mac>().GetWakeupListenParameters(*aInterval, *aDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
otError otLinkSetWakeupListenParameters(otInstance *aInstance, uint32_t aInterval, uint32_t aDuration)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Mac::Mac>().SetWakeupListenParameters(aInterval, aDuration);
|
||||||
|
}
|
||||||
|
#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
|||||||
@@ -63,6 +63,34 @@
|
|||||||
#define OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE 0
|
#define OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_WED_LISTEN_INTERVAL
|
||||||
|
*
|
||||||
|
* The default wake-up listen interval in microseconds.
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_WED_LISTEN_INTERVAL
|
||||||
|
#define OPENTHREAD_CONFIG_WED_LISTEN_INTERVAL 1000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_WED_LISTEN_DURATION
|
||||||
|
*
|
||||||
|
* The default wake-up listen duration in microseconds.
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_WED_LISTEN_DURATION
|
||||||
|
#define OPENTHREAD_CONFIG_WED_LISTEN_DURATION 8000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_WED_RECEIVE_TIME_AFTER
|
||||||
|
*
|
||||||
|
* Margin to be applied after the end of a wake-up listen duration to schedule the next listen interval, in units of
|
||||||
|
* microseconds.
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_WED_RECEIVE_TIME_AFTER
|
||||||
|
#define OPENTHREAD_CONFIG_WED_RECEIVE_TIME_AFTER 500
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|||||||
+154
-2
@@ -59,6 +59,9 @@ Mac::Mac(Instance &aInstance)
|
|||||||
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
|
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
|
||||||
, mShouldDelaySleep(false)
|
, mShouldDelaySleep(false)
|
||||||
, mDelayingSleep(false)
|
, mDelayingSleep(false)
|
||||||
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
, mWakeupListenEnabled(false)
|
||||||
#endif
|
#endif
|
||||||
, mOperation(kOperationIdle)
|
, mOperation(kOperationIdle)
|
||||||
, mPendingOperations(0)
|
, mPendingOperations(0)
|
||||||
@@ -83,6 +86,10 @@ Mac::Mac(Instance &aInstance)
|
|||||||
, mCslPeriod(0)
|
, mCslPeriod(0)
|
||||||
#endif
|
#endif
|
||||||
, mWakeupChannel(OPENTHREAD_CONFIG_DEFAULT_WAKEUP_CHANNEL)
|
, mWakeupChannel(OPENTHREAD_CONFIG_DEFAULT_WAKEUP_CHANNEL)
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
, mWakeupListenInterval(kDefaultWedListenInterval)
|
||||||
|
, mWakeupListenDuration(kDefaultWedListenDuration)
|
||||||
|
#endif
|
||||||
, mActiveScanHandler(nullptr) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union
|
, mActiveScanHandler(nullptr) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union
|
||||||
, mScanHandlerContext(nullptr)
|
, mScanHandlerContext(nullptr)
|
||||||
, mLinks(aInstance)
|
, mLinks(aInstance)
|
||||||
@@ -1590,8 +1597,27 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Frame::kKeyIdMode2:
|
case Frame::kKeyIdMode2:
|
||||||
macKey = &mMode2KeyMaterial;
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
extAddress = &AsCoreType(&sMode2ExtAddress);
|
if (aFrame.IsWakeupFrame())
|
||||||
|
{
|
||||||
|
uint32_t sequence;
|
||||||
|
|
||||||
|
// TODO: Avoid generating a new key if a wake-up frame was recently received already
|
||||||
|
|
||||||
|
IgnoreError(aFrame.GetKeyId(keyid));
|
||||||
|
sequence = BigEndian::ReadUint32(aFrame.GetKeySource());
|
||||||
|
VerifyOrExit(((sequence & 0x7f) + 1) == keyid, error = kErrorSecurity);
|
||||||
|
|
||||||
|
macKey = (sequence == keyManager.GetCurrentKeySequence()) ? mLinks.GetCurrentMacKey(aFrame)
|
||||||
|
: &keyManager.GetTemporaryMacKey(sequence);
|
||||||
|
extAddress = &aSrcAddr.GetExtended();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
macKey = &mMode2KeyMaterial;
|
||||||
|
extAddress = &AsCoreType(&sMode2ExtAddress);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1973,6 +1999,12 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
|
|||||||
mCounters.mRxData++;
|
mCounters.mRxData++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
case Frame::kTypeMultipurpose:
|
||||||
|
SuccessOrExit(error = HandleWakeupFrame(*aFrame));
|
||||||
|
OT_FALL_THROUGH;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mCounters.mRxOther++;
|
mCounters.mRxOther++;
|
||||||
ExitNow();
|
ExitNow();
|
||||||
@@ -2317,6 +2349,14 @@ void Mac::SetCslChannel(uint8_t aChannel)
|
|||||||
|
|
||||||
void Mac::SetCslPeriod(uint16_t aPeriod)
|
void Mac::SetCslPeriod(uint16_t aPeriod)
|
||||||
{
|
{
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
if (IsWakeupListenEnabled() && aPeriod != 0)
|
||||||
|
{
|
||||||
|
IgnoreError(SetWakeupListenEnabled(false));
|
||||||
|
LogWarn("Disabling wake-up frame listening due to CSL period change");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mCslPeriod = aPeriod;
|
mCslPeriod = aPeriod;
|
||||||
UpdateCsl();
|
UpdateCsl();
|
||||||
}
|
}
|
||||||
@@ -2417,10 +2457,122 @@ Error Mac::SetWakeupChannel(uint8_t aChannel)
|
|||||||
VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = kErrorInvalidArgs);
|
VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = kErrorInvalidArgs);
|
||||||
mWakeupChannel = aChannel;
|
mWakeupChannel = aChannel;
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
UpdateWakeupListening();
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_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 >= 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Mac::HandleWakeupFrame(const RxFrame &aFrame)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
const ConnectionIe *connectionIe;
|
||||||
|
uint32_t rvTimeUs;
|
||||||
|
uint64_t rvTimestampUs;
|
||||||
|
uint32_t attachDelayMs;
|
||||||
|
uint64_t radioNowUs;
|
||||||
|
uint8_t retryInterval;
|
||||||
|
uint8_t retryCount;
|
||||||
|
|
||||||
|
VerifyOrExit(mWakeupListenEnabled && aFrame.IsWakeupFrame());
|
||||||
|
connectionIe = aFrame.GetConnectionIe();
|
||||||
|
retryInterval = connectionIe->GetRetryInterval();
|
||||||
|
retryCount = connectionIe->GetRetryCount();
|
||||||
|
VerifyOrExit(retryInterval > 0 && retryCount > 0, error = kErrorInvalidArgs);
|
||||||
|
|
||||||
|
radioNowUs = otPlatRadioGetNow(&GetInstance());
|
||||||
|
rvTimeUs = aFrame.GetRendezvousTimeIe()->GetRendezvousTime() * kUsPerTenSymbols;
|
||||||
|
rvTimestampUs = aFrame.GetTimestamp() + kRadioHeaderPhrDuration + aFrame.GetLength() * kOctetDuration + rvTimeUs;
|
||||||
|
if (rvTimestampUs > radioNowUs + OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US)
|
||||||
|
{
|
||||||
|
attachDelayMs = static_cast<uint32_t>(rvTimestampUs - radioNowUs - OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US);
|
||||||
|
attachDelayMs = attachDelayMs / 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attachDelayMs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||||
|
{
|
||||||
|
uint32_t frameCounter;
|
||||||
|
|
||||||
|
IgnoreError(aFrame.GetFrameCounter(frameCounter));
|
||||||
|
LogInfo("Received wake-up frame, fc:%lu, rendezvous:%luus, retries:%u/%u", ToUlong(frameCounter),
|
||||||
|
ToUlong(rvTimeUs), retryCount, retryInterval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Stop receiving more wake up frames
|
||||||
|
IgnoreError(SetWakeupListenEnabled(false));
|
||||||
|
|
||||||
|
// TODO: start MLE attach process with the WC
|
||||||
|
OT_UNUSED_VARIABLE(attachDelayMs);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
|
||||||
} // namespace Mac
|
} // namespace Mac
|
||||||
} // namespace ot
|
} // namespace ot
|
||||||
|
|||||||
+61
-5
@@ -89,6 +89,9 @@ constexpr uint8_t kTxNumBcast = OPENTHREAD_CONFIG_MAC_TX_NUM_BCAST; ///< Num of
|
|||||||
|
|
||||||
constexpr uint16_t kMinCslIePeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD;
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the function pointer called on receiving an IEEE 802.15.4 Beacon during an Active Scan.
|
* Defines the function pointer called on receiving an IEEE 802.15.4 Beacon during an Active Scan.
|
||||||
*/
|
*/
|
||||||
@@ -681,17 +684,17 @@ public:
|
|||||||
Error GetRegion(uint16_t &aRegionCode) const;
|
Error GetRegion(uint16_t &aRegionCode) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Wake-up channel.
|
* Gets the wake-up channel.
|
||||||
*
|
*
|
||||||
* @returns Wake-up channel.
|
* @returns wake-up channel.
|
||||||
*/
|
*/
|
||||||
uint8_t GetWakeupChannel(void) const { return mWakeupChannel; }
|
uint8_t GetWakeupChannel(void) const { return mWakeupChannel; }
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
/**
|
/**
|
||||||
* Sets the Wake-up channel.
|
* Sets the wake-up channel.
|
||||||
*
|
*
|
||||||
* @param[in] aChannel The Wake-up channel.
|
* @param[in] aChannel The wake-up channel.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Successfully set the wake-up channel.
|
* @retval kErrorNone Successfully set the wake-up channel.
|
||||||
* @retval kErrorInvalidArgs The @p aChannel is not in the supported channel mask.
|
* @retval kErrorInvalidArgs The @p aChannel is not in the supported channel mask.
|
||||||
@@ -699,6 +702,49 @@ public:
|
|||||||
Error SetWakeupChannel(uint8_t aChannel);
|
Error SetWakeupChannel(uint8_t aChannel);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_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 `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_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint16_t kMaxCcaSampleCount = OPENTHREAD_CONFIG_CCA_FAILURE_RATE_AVERAGING_WINDOW;
|
static constexpr uint16_t kMaxCcaSampleCount = OPENTHREAD_CONFIG_CCA_FAILURE_RATE_AVERAGING_WINDOW;
|
||||||
|
|
||||||
@@ -786,6 +832,10 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||||
void ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor);
|
void ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor);
|
||||||
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
Error HandleWakeupFrame(const RxFrame &aFrame);
|
||||||
|
void UpdateWakeupListening(void);
|
||||||
#endif
|
#endif
|
||||||
static const char *OperationToString(Operation aOperation);
|
static const char *OperationToString(Operation aOperation);
|
||||||
|
|
||||||
@@ -803,6 +853,9 @@ private:
|
|||||||
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
|
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
|
||||||
bool mShouldDelaySleep : 1;
|
bool mShouldDelaySleep : 1;
|
||||||
bool mDelayingSleep : 1;
|
bool mDelayingSleep : 1;
|
||||||
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
bool mWakeupListenEnabled : 1;
|
||||||
#endif
|
#endif
|
||||||
Operation mOperation;
|
Operation mOperation;
|
||||||
uint16_t mPendingOperations;
|
uint16_t mPendingOperations;
|
||||||
@@ -829,7 +882,10 @@ private:
|
|||||||
uint16_t mCslPeriod;
|
uint16_t mCslPeriod;
|
||||||
#endif
|
#endif
|
||||||
uint8_t mWakeupChannel;
|
uint8_t mWakeupChannel;
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
uint32_t mWakeupListenInterval;
|
||||||
|
uint32_t mWakeupListenDuration;
|
||||||
|
#endif
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
ActiveScanHandler mActiveScanHandler;
|
ActiveScanHandler mActiveScanHandler;
|
||||||
|
|||||||
@@ -473,6 +473,27 @@ public:
|
|||||||
}
|
}
|
||||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_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.
|
* Transitions all radio links to Receive.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ SubMac::SubMac(Instance &aInstance)
|
|||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
, mCslTimer(aInstance, SubMac::HandleCslTimer)
|
, mCslTimer(aInstance, SubMac::HandleCslTimer)
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
, mWedTimer(aInstance, SubMac::HandleWedTimer)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
mCslParentAccuracy.Init();
|
mCslParentAccuracy.Init();
|
||||||
@@ -90,6 +93,9 @@ void SubMac::Init(void)
|
|||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
CslInit();
|
CslInit();
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
WedInit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
otRadioCaps SubMac::GetCaps(void) const
|
otRadioCaps SubMac::GetCaps(void) const
|
||||||
@@ -203,6 +209,9 @@ Error SubMac::Disable(void)
|
|||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
mCslTimer.Stop();
|
mCslTimer.Stop();
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
mWedTimer.Stop();
|
||||||
|
#endif
|
||||||
|
|
||||||
mTimer.Stop();
|
mTimer.Stop();
|
||||||
SuccessOrExit(error = Get<Radio>().Sleep());
|
SuccessOrExit(error = Get<Radio>().Sleep());
|
||||||
|
|||||||
@@ -480,6 +480,18 @@ public:
|
|||||||
bool IsRadioFilterEnabled(void) const { return mRadioFilterEnabled; }
|
bool IsRadioFilterEnabled(void) const { return mRadioFilterEnabled; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_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:
|
private:
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
void CslInit(void);
|
void CslInit(void);
|
||||||
@@ -492,6 +504,11 @@ private:
|
|||||||
#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
||||||
void LogReceived(RxFrame *aFrame);
|
void LogReceived(RxFrame *aFrame);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
void WedInit(void);
|
||||||
|
static void HandleWedTimer(Timer &aTimer);
|
||||||
|
void HandleWedTimer(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static constexpr uint8_t kCsmaMinBe = 3; // macMinBE (IEEE 802.15.4-2006).
|
static constexpr uint8_t kCsmaMinBe = 3; // macMinBE (IEEE 802.15.4-2006).
|
||||||
@@ -530,16 +547,22 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
// Radio on times needed before and after MHR time for proper frame detection
|
// Radio on times needed before and after MHR time for proper frame detection
|
||||||
static constexpr uint32_t kMinReceiveOnAhead = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD;
|
static constexpr uint32_t kMinReceiveOnAhead = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD;
|
||||||
static constexpr uint32_t kMinReceiveOnAfter = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER;
|
static constexpr uint32_t kMinReceiveOnAfter = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER;
|
||||||
|
|
||||||
// CSL receivers would wake up `kCslReceiveTimeAhead` earlier
|
// CSL/wake-up listening receivers would wake up `kCslReceiveTimeAhead` earlier
|
||||||
// than expected sample window. The value is in usec.
|
// than expected sample window. The value is in usec.
|
||||||
static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
|
static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
// 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 = OPENTHREAD_CONFIG_WED_RECEIVE_TIME_AFTER;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
||||||
// CSL transmitter would schedule delayed transmission `kCslTransmitTimeAhead` earlier
|
// CSL transmitter would schedule delayed transmission `kCslTransmitTimeAhead` earlier
|
||||||
// than expected delayed transmit time. The value is in usec.
|
// than expected delayed transmit time. The value is in usec.
|
||||||
@@ -635,6 +658,15 @@ private:
|
|||||||
CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty).
|
CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty).
|
||||||
TimerMicro mCslTimer;
|
TimerMicro mCslTimer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
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.
|
||||||
|
TimeMicro mWedSampleTime; // The WED sample time of the current interval in local time.
|
||||||
|
uint64_t mWedSampleTimeRadio; // The WED sample time of the current interval in radio time.
|
||||||
|
TimerMicro mWedTimer;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
|
||||||
|
#include "instance/instance.hpp"
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace Mac {
|
||||||
|
|
||||||
|
RegisterLogModule("SubMac");
|
||||||
|
|
||||||
|
void SubMac::WedInit(void)
|
||||||
|
{
|
||||||
|
mWakeupListenInterval = 0;
|
||||||
|
mWedTimer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubMac::UpdateWakeupListening(bool aEnable, uint32_t aInterval, uint32_t aDuration, uint8_t aChannel)
|
||||||
|
{
|
||||||
|
VerifyOrExit(RadioSupportsReceiveTiming());
|
||||||
|
|
||||||
|
mWakeupListenInterval = aInterval;
|
||||||
|
mWakeupListenDuration = aDuration;
|
||||||
|
mWakeupChannel = aChannel;
|
||||||
|
mWedTimer.Stop();
|
||||||
|
|
||||||
|
if (aEnable)
|
||||||
|
{
|
||||||
|
mWedSampleTime = TimerMicro::GetNow() + kCslReceiveTimeAhead - mWakeupListenInterval;
|
||||||
|
mWedSampleTimeRadio = Get<Radio>().GetNow() + kCslReceiveTimeAhead - mWakeupListenInterval;
|
||||||
|
|
||||||
|
HandleWedTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubMac::HandleWedTimer(Timer &aTimer) { aTimer.Get<SubMac>().HandleWedTimer(); }
|
||||||
|
|
||||||
|
void SubMac::HandleWedTimer(void)
|
||||||
|
{
|
||||||
|
mWedSampleTime += mWakeupListenInterval;
|
||||||
|
mWedSampleTimeRadio += mWakeupListenInterval;
|
||||||
|
mWedTimer.FireAt(mWedSampleTime + mWakeupListenDuration + kWedReceiveTimeAfter);
|
||||||
|
|
||||||
|
if (mState != kStateDisabled)
|
||||||
|
{
|
||||||
|
IgnoreError(
|
||||||
|
Get<Radio>().ReceiveAt(mWakeupChannel, static_cast<uint32_t>(mWedSampleTimeRadio), mWakeupListenDuration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Mac
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#endif // OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
+30
-16
@@ -51,6 +51,7 @@ namespace ot {
|
|||||||
static constexpr uint32_t kUsPerTenSymbols = OT_US_PER_TEN_SYMBOLS; ///< Time for 10 symbols in units of microseconds
|
static constexpr uint32_t kUsPerTenSymbols = OT_US_PER_TEN_SYMBOLS; ///< Time for 10 symbols in units of microseconds
|
||||||
static constexpr uint32_t kRadioHeaderShrDuration = 160; ///< Duration of SHR in us
|
static constexpr uint32_t kRadioHeaderShrDuration = 160; ///< Duration of SHR in us
|
||||||
static constexpr uint32_t kRadioHeaderPhrDuration = 32; ///< Duration of PHR in us
|
static constexpr uint32_t kRadioHeaderPhrDuration = 32; ///< Duration of PHR in us
|
||||||
|
static constexpr uint32_t kOctetDuration = 32; ///< Duration of one octet in us
|
||||||
|
|
||||||
static constexpr int8_t kRadioPowerInvalid = OT_RADIO_POWER_INVALID; ///< Invalid TX power value
|
static constexpr int8_t kRadioPowerInvalid = OT_RADIO_POWER_INVALID; ///< Invalid TX power value
|
||||||
|
|
||||||
@@ -62,6 +63,13 @@ static constexpr uint64_t kMinCslPeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD
|
|||||||
static constexpr uint64_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
|
static constexpr uint64_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
/**
|
||||||
|
* Minimum wake-up listen duration supported in microseconds.
|
||||||
|
*/
|
||||||
|
static constexpr uint32_t kMinWakeupListenDuration = 100;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup core-radio
|
* @addtogroup core-radio
|
||||||
*
|
*
|
||||||
@@ -473,14 +481,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
Error Receive(uint8_t aChannel);
|
Error Receive(uint8_t aChannel);
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
/**
|
|
||||||
* Updates the CSL sample time in radio.
|
|
||||||
*
|
|
||||||
* @param[in] aCslSampleTime The CSL sample time.
|
|
||||||
*/
|
|
||||||
void UpdateCslSampleTime(uint32_t aCslSampleTime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a radio reception window at a specific time and duration.
|
* Schedules a radio reception window at a specific time and duration.
|
||||||
*
|
*
|
||||||
@@ -492,6 +493,15 @@ public:
|
|||||||
* @retval kErrorFailed The receive window could not be scheduled.
|
* @retval kErrorFailed The receive window could not be scheduled.
|
||||||
*/
|
*/
|
||||||
Error ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration);
|
Error ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
|
/**
|
||||||
|
* Updates the CSL sample time in radio.
|
||||||
|
*
|
||||||
|
* @param[in] aCslSampleTime The CSL sample time.
|
||||||
|
*/
|
||||||
|
void UpdateCslSampleTime(uint32_t aCslSampleTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables CSL sampling in radio.
|
* Enables CSL sampling in radio.
|
||||||
@@ -902,12 +912,7 @@ inline Error Radio::Receive(uint8_t aChannel)
|
|||||||
return otPlatRadioReceive(GetInstancePtr(), aChannel);
|
return otPlatRadioReceive(GetInstancePtr(), aChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
inline void Radio::UpdateCslSampleTime(uint32_t aCslSampleTime)
|
|
||||||
{
|
|
||||||
otPlatRadioUpdateCslSampleTime(GetInstancePtr(), aCslSampleTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
|
inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
|
||||||
{
|
{
|
||||||
Error error = otPlatRadioReceiveAt(GetInstancePtr(), aChannel, aStart, aDuration);
|
Error error = otPlatRadioReceiveAt(GetInstancePtr(), aChannel, aStart, aDuration);
|
||||||
@@ -919,6 +924,13 @@ inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDurat
|
|||||||
#endif
|
#endif
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
|
inline void Radio::UpdateCslSampleTime(uint32_t aCslSampleTime)
|
||||||
|
{
|
||||||
|
otPlatRadioUpdateCslSampleTime(GetInstancePtr(), aCslSampleTime);
|
||||||
|
}
|
||||||
|
|
||||||
inline Error Radio::EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr)
|
inline Error Radio::EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr)
|
||||||
{
|
{
|
||||||
@@ -1023,11 +1035,13 @@ inline Error Radio::Sleep(void) { return kErrorNone; }
|
|||||||
|
|
||||||
inline Error Radio::Receive(uint8_t) { return kErrorNone; }
|
inline Error Radio::Receive(uint8_t) { return kErrorNone; }
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
inline Error Radio::ReceiveAt(uint8_t, uint32_t, uint32_t) { return kErrorNone; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||||
inline void Radio::UpdateCslSampleTime(uint32_t) {}
|
inline void Radio::UpdateCslSampleTime(uint32_t) {}
|
||||||
|
|
||||||
inline Error Radio::ReceiveAt(uint8_t, uint32_t, uint32_t) { return kErrorNone; }
|
|
||||||
|
|
||||||
inline Error Radio::EnableCsl(uint32_t, otShortAddress aShortAddr, const otExtAddress *)
|
inline Error Radio::EnableCsl(uint32_t, otShortAddress aShortAddr, const otExtAddress *)
|
||||||
{
|
{
|
||||||
return kErrorNotImplemented;
|
return kErrorNotImplemented;
|
||||||
|
|||||||
@@ -400,6 +400,18 @@ const Mle::KeyMaterial &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
|
|||||||
return mTemporaryMleKey;
|
return mTemporaryMleKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
const Mle::KeyMaterial &KeyManager::GetTemporaryMacKey(uint32_t aKeySequence)
|
||||||
|
{
|
||||||
|
HashKeys hashKeys;
|
||||||
|
|
||||||
|
ComputeKeys(aKeySequence, hashKeys);
|
||||||
|
mTemporaryMacKey.SetFrom(hashKeys.GetMacKey());
|
||||||
|
|
||||||
|
return mTemporaryMacKey;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||||
const Mac::KeyMaterial &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
|
const Mac::KeyMaterial &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -358,6 +358,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
const Mle::KeyMaterial &GetTemporaryMleKey(uint32_t aKeySequence);
|
const Mle::KeyMaterial &GetTemporaryMleKey(uint32_t aKeySequence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a temporary MAC key Material computed from the given key sequence.
|
||||||
|
*
|
||||||
|
* @param[in] aKeySequence The key sequence value.
|
||||||
|
*
|
||||||
|
* @returns The temporary MAC key.
|
||||||
|
*/
|
||||||
|
const Mle::KeyMaterial &GetTemporaryMacKey(uint32_t aKeySequence);
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||||
/**
|
/**
|
||||||
* Returns the current MAC Frame Counter value for 15.4 radio link.
|
* Returns the current MAC Frame Counter value for 15.4 radio link.
|
||||||
@@ -598,6 +607,10 @@ private:
|
|||||||
Mle::KeyMaterial mMleKey;
|
Mle::KeyMaterial mMleKey;
|
||||||
Mle::KeyMaterial mTemporaryMleKey;
|
Mle::KeyMaterial mTemporaryMleKey;
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||||
|
Mle::KeyMaterial mTemporaryMacKey;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||||
Mac::KeyMaterial mTrelKey;
|
Mac::KeyMaterial mTrelKey;
|
||||||
Mac::KeyMaterial mTemporaryTrelKey;
|
Mac::KeyMaterial mTemporaryTrelKey;
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the local socket address to RLOC address and the peer socket address to leader RLOC.
|
* Sets the local socket address to RLOC address and the peer socket address to leader RLOC.
|
||||||
q *
|
|
||||||
*/
|
*/
|
||||||
void SetSockAddrToRlocPeerAddrToLeaderRloc(void);
|
void SetSockAddrToRlocPeerAddrToLeaderRloc(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user