Skip to content

Commit

Permalink
[mle] implement periodic parent search mechanism on FED/REED (openthr…
Browse files Browse the repository at this point in the history
…ead#10722)

This commit implements "Periodic Parent Search" mechanism for FED/REED
devices (FTD children). This enhances and builds upon
the existing parent search feature, which is mainly intended for
MTD children.

An FTD child receives and processes MLE Advertisements from
neighboring routers. The child uses this information to track the
one-way link quality to each router, which is later used to compare
and select potential new parents.

Every "parent search check interval", the FTD child checks to see if
it can select a better parent by evaluating all neighboring routers
based on their link quality information. A router is considered a
suitable parent candidate only if its average RSS exceeds the current
parent's RSS by a margin (`PARENT_SEARCH_RSS_MARGIN`).

Once a candidate is selected, the FTD child sends unicast MLE Parent
Requests to both the candidate and its current parent. This ensures
updated connectivity information is obtained from both before making
a decision. The same set of criteria used to compare candidates
during initial attach are applied during parent switch.

If the attach attempt to the selected candidate fails (e.g., the
router already has the maximum number of children it can support),
the FTD child ensures not to select the same router again until
a "reselect timeout" expires.

This commit also adds the `test-025-fed-parent-search.py test`, which
validates the newly added FTD parent search behavior, including the
mechanisms to attach to a selected router and the reselect timeout.
  • Loading branch information
abtink authored Nov 11, 2024
1 parent 6e1292d commit c13fcc6
Show file tree
Hide file tree
Showing 13 changed files with 496 additions and 32 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 (462)
#define OPENTHREAD_API_VERSION (463)

/**
* @addtogroup api-instance
Expand Down
1 change: 1 addition & 0 deletions include/openthread/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ typedef struct otMleCounters
uint16_t mAttachAttempts; ///< Number of attach attempts while device was detached.
uint16_t mPartitionIdChanges; ///< Number of changes to partition ID.
uint16_t mBetterPartitionAttachAttempts; ///< Number of attempts to attach to a better partition.
uint16_t mBetterParentAttachAttempts; ///< Number of attempts to attach to find a better parent (parent search).

/**
* Role time tracking.
Expand Down
1 change: 1 addition & 0 deletions src/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,7 @@ Role Leader: 1
Attach Attempts: 1
Partition Id Changes: 1
Better Partition Attach Attempts: 0
Better Parent Attach Attempts: 0
Parent Changes: 0
Time Disabled Milli: 10026
Time Detached Milli: 6852
Expand Down
2 changes: 2 additions & 0 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2308,6 +2308,7 @@ template <> otError Interpreter::Process<Cmd("counters")>(Arg aArgs[])
* Attach Attempts: 1
* Partition Id Changes: 1
* Better Partition Attach Attempts: 0
* Better Parent Attach Attempts: 0
* Parent Changes: 0
* Done
* @endcode
Expand All @@ -2334,6 +2335,7 @@ template <> otError Interpreter::Process<Cmd("counters")>(Arg aArgs[])
{&otMleCounters::mAttachAttempts, "Attach Attempts"},
{&otMleCounters::mPartitionIdChanges, "Partition Id Changes"},
{&otMleCounters::mBetterPartitionAttachAttempts, "Better Partition Attach Attempts"},
{&otMleCounters::mBetterParentAttachAttempts, "Better Parent Attach Attempts"},
{&otMleCounters::mParentChanges, "Parent Changes"},
};

Expand Down
73 changes: 62 additions & 11 deletions src/core/config/parent_search.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,46 @@
/**
* @def OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
*
* Define as 1 to enable periodic parent search feature.
* Define as 1 to enable the periodic parent search feature.
*
* When this feature is enabled an end-device/child (while staying attached) will periodically search for a possible
* better parent and will switch parent if a better one is found.
*
* The child will periodically check the average RSS value for the current parent, and only if it is below a specific
* threshold, a parent search is performed. The `OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL` specifies the
* check interval (in seconds) and `OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD` gives the RSS threshold.
* When this feature is enabled, an end device/child (while staying attached) periodically searches for a potentially
* better parent and switches parents if a better one is found.
*
* Since the parent search process can be power consuming (child needs to stays in RX mode to collect parent response)
* and to limit its impact on battery-powered devices, after a parent search is triggered, the child will not trigger
* another one before a specified backoff interval specified by `OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL`.
* The parent search mechanism depends on whether the device is an FTD child or an MTD child.
*
* FTD Child
*
* - An FTD child receives and processes MLE Advertisements from neighboring routers. It uses this information to track
* the one-way link quality to each, which is later used to compare and select potential new parents.
* - Every `OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL` seconds, an FTD child tries to select a better parent.
* The FTD child checks the list of neighboring routers and the tracked link quality information. A new parent is
* selected only if its average RSS exceeds the current parent's RSS by a margin specified by the configuration
* `OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_MARGIN` configuration.
* - If the attach attempt to the selected router fails (e.g., the router already has the maximum number of children it
* can support), the FTD child ensures that the same router cannot be selected again until a "reselect timeout"
* expires. This avoids repeated attempts to the same router. This timeout is specified by the configuration
* `OPENTHREAD_CONFIG_PARENT_SEARCH_RESELECT_TIMEOUT`.
*
* MTD Child
*
* - Every `OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL` seconds, an MTD child checks its average RSS to its
* current parent. The child starts a parent search process only if the average RSS is below
* `OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD`.
* - This ensures that an MTD child already attached to a parent with good link quality does not waste energy
* searching for better parents.
* - The MTD child sends an MLE Parent Request to discover possible new parents. Because this process can be
* power-consuming (the child needs to stay in RX mode to collect parent responses), and to limit its impact on
* battery-powered devices, after a parent search is triggered on an MTD, the MTD child does not trigger another
* one before the specified backoff interval (`OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL`) expires.
*
* This feature is enabled by default on FTD builds. It is recommended that it also be enabled on MTD builds. This may
* require the platform integrator (device vendor) to select appropriate configuration values for this feature,
* particularly `OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL`, which can impact how often a (battery-powered)
* sleepy child may search for a parent, taking into account its impact on the device's battery life.
*/
#ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 0
#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE OPENTHREAD_FTD
#endif

/**
Expand All @@ -77,7 +102,8 @@
/**
* @def OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL
*
* Specifies the backoff interval in seconds for a child to not perform a parent search after triggering one.
* Specifies the backoff interval in seconds for a child to not perform a parent search after triggering one. This is
* used when device is an MTD child.
*
* Applicable only if periodic parent search feature is enabled (see `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE`).
*/
Expand All @@ -97,6 +123,31 @@
#endif

/**
* @def OPENTHREAD_CONFIG_PARENT_SEARCH_RESELECT_TIMEOUT
*
* Specifies parent reselect timeout duration in seconds used on FTD child devices. When an attach attempt to a
* neighboring router selected as a potential new parent fails, the same router cannot be selected again until this
* timeout expires.
*
* Applicable only if periodic parent search feature is enabled (see `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE`).
*
*/
#ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_RESELECT_TIMEOUT
#define OPENTHREAD_CONFIG_PARENT_SEARCH_RESELECT_TIMEOUT (90 * 60)
#endif

/**
* @def OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_MARGIN
*
* Specifies the RSS margin over the current parent RSS for allowing selection of a neighboring router as a potential
* new parent to attach to. Used on FTD child devices.
*
*/
#ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_MARGIN
#define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_MARGIN 7
#endif

/*
* @}
*/

Expand Down
Loading

0 comments on commit c13fcc6

Please sign in to comment.