Skip to content

Commit

Permalink
[mac] enable wake-up frame periodic sniffing (openthread#10762)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
edmont authored Oct 14, 2024
1 parent 072e537 commit ef8f170
Show file tree
Hide file tree
Showing 18 changed files with 687 additions and 50 deletions.
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (454)
#define OPENTHREAD_API_VERSION (455)

/**
* @addtogroup api-instance
Expand Down
54 changes: 54 additions & 0 deletions include/openthread/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,60 @@ uint8_t otLinkGetWakeupChannel(otInstance *aInstance);
*/
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);

/**
* @}
*/
Expand Down
57 changes: 52 additions & 5 deletions src/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Done
- [vendor](#vendor-name)
- [verhoeff](#verhoeff-calculate)
- [version](#version)
- [wakeupchannel](#wakeupchannel)
- [wakeup](#wakeup-channel)

## OpenThread Command Details

Expand Down Expand Up @@ -4402,25 +4402,72 @@ Factory Diagnostics module is enabled only when building OpenThread with `OPENTH
[diag]: ../../src/core/diags/README.md
### wakeupchannel
### wakeup channel
Get the wake-up channel.
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
```bash
> wakeupchannel
> wakeup channel
12
Done
```
### wakeupchannel \<channel\>
### wakeup channel \<channel\>
Set the wake-up channel.
Requires `OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE` or `OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE`.
```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
```
119 changes: 101 additions & 18 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8213,25 +8213,103 @@ template <> otError Interpreter::Process<Cmd("verhoeff")>(Arg aArgs[])
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE

#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
/**
* @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[])
template <> otError Interpreter::Process<Cmd("wakeup")>(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

Expand Down Expand Up @@ -8544,6 +8622,11 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
#endif
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
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
Expand Down
3 changes: 3 additions & 0 deletions src/core/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ openthread_core_files = [
"mac/sub_mac.hpp",
"mac/sub_mac_callbacks.cpp",
"mac/sub_mac_csl_receiver.cpp",
"mac/sub_mac_wed.cpp",
"meshcop/announce_begin_client.cpp",
"meshcop/announce_begin_client.hpp",
"meshcop/border_agent.cpp",
Expand Down Expand Up @@ -777,6 +778,8 @@ openthread_radio_sources = [
"mac/mac_types.cpp",
"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_platform.cpp",
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ set(COMMON_SOURCES
mac/sub_mac.cpp
mac/sub_mac_callbacks.cpp
mac/sub_mac_csl_receiver.cpp
mac/sub_mac_wed.cpp
meshcop/announce_begin_client.cpp
meshcop/border_agent.cpp
meshcop/commissioner.cpp
Expand Down Expand Up @@ -295,6 +296,7 @@ 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_platform.cpp
Expand Down
22 changes: 22 additions & 0 deletions src/core/api/link_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,25 @@ otError otLinkGetRegion(otInstance *aInstance, uint16_t *aRegionCode)

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
28 changes: 28 additions & 0 deletions src/core/config/wakeup.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,34 @@
#define OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE 0
#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

/**
* @}
*/
Expand Down
Loading

0 comments on commit ef8f170

Please sign in to comment.