mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[mle] implement alternate RLOC16 usage during role transition (#10006)
This commit introduces a mechanism for a device transitioning from child to router role to keep receiving frames addressed to its previous short address for a brief period. A new radio platform API, `otPlatRadioSetAlternateShortAddress()`, is introduced. This allows the OT stack to configure an alternate short address. Radio platform support for this function is indicated by the `OT_RADIO_CAPS_ALT_SHORT_ADDR` capability in `otPlatRadioGetCaps()` The same function can be used with `OT_RADIO_INVALID_SHORT_ADDR` (`0xfffe`) to clear a previously set alternate short address. Support for the new API is implemented in RCP and `RadioSpinel`, ensuring backward compatibility by dynamically checking supported radio capabilities. MLE code is updated to instruct the radio to use the old child RLOC16 as an alternate address upon role transition. The MLE layer will automatically clear the alternate address after eight seconds, or if other state/mode changes occur. This eight-second window ensures the new router can transmit four MLE Advertisement messages.
This commit is contained in:
committed by
GitHub
parent
a5e1c91055
commit
444d1dd6bc
@@ -382,6 +382,15 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddr
|
||||
sRadioContext.mShortAddress = aShortAddress;
|
||||
}
|
||||
|
||||
void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
assert(aInstance != NULL);
|
||||
|
||||
sRadioContext.mAlternateShortAddress = aShortAddress;
|
||||
}
|
||||
|
||||
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
@@ -849,9 +858,9 @@ void radioProcessFrame(otInstance *aInstance)
|
||||
|
||||
otEXPECT(sPromiscuous == false);
|
||||
|
||||
otEXPECT_ACTION(
|
||||
otMacFrameDoesAddrMatch(&sReceiveFrame, sPanid, sRadioContext.mShortAddress, &sRadioContext.mExtAddress),
|
||||
error = OT_ERROR_ABORT);
|
||||
otEXPECT_ACTION(otMacFrameDoesAddrMatchAny(&sReceiveFrame, sPanid, sRadioContext.mShortAddress,
|
||||
sRadioContext.mAlternateShortAddress, &sRadioContext.mExtAddress),
|
||||
error = OT_ERROR_ABORT);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
otEXPECT_ACTION(otMacFrameGetSrcAddr(&sReceiveFrame, &macAddress) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
|
||||
@@ -41,6 +41,15 @@ bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
|
||||
otPanId aPanId,
|
||||
otShortAddress aShortAddress,
|
||||
const otExtAddress *aExtAddress)
|
||||
{
|
||||
return otMacFrameDoesAddrMatchAny(aFrame, aPanId, aShortAddress, Mac::kShortAddrInvalid, aExtAddress);
|
||||
}
|
||||
|
||||
bool otMacFrameDoesAddrMatchAny(const otRadioFrame *aFrame,
|
||||
otPanId aPanId,
|
||||
otShortAddress aShortAddress,
|
||||
otShortAddress aAltShortAddress,
|
||||
const otExtAddress *aExtAddress)
|
||||
{
|
||||
const Mac::Frame &frame = *static_cast<const Mac::Frame *>(aFrame);
|
||||
bool rval = true;
|
||||
@@ -52,7 +61,9 @@ bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
|
||||
switch (dst.GetType())
|
||||
{
|
||||
case Mac::Address::kTypeShort:
|
||||
VerifyOrExit(dst.GetShort() == Mac::kShortAddrBroadcast || dst.GetShort() == aShortAddress, rval = false);
|
||||
VerifyOrExit(dst.GetShort() == Mac::kShortAddrBroadcast || dst.GetShort() == aShortAddress ||
|
||||
(aAltShortAddress != Mac::kShortAddrInvalid && dst.GetShort() == aAltShortAddress),
|
||||
rval = false);
|
||||
break;
|
||||
|
||||
case Mac::Address::kTypeExtended:
|
||||
|
||||
@@ -132,6 +132,25 @@ bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
|
||||
otShortAddress aShortAddress,
|
||||
const otExtAddress *aExtAddress);
|
||||
|
||||
/**
|
||||
* Check if @p aFrame matches the @p aPandId and @p aShortAddress, or @p aAltShortAddress or @p aExtAddress.
|
||||
*
|
||||
* @param[in] aFrame A pointer to the frame.
|
||||
* @param[in] aPanId The PAN id to match with.
|
||||
* @param[in] aShortAddress The short address to match with.
|
||||
* @param[in] aAltShortAddress The alternate short address to match with. Can be `OT_RADIO_INVALID_SHORT_ADDR` if
|
||||
* there is no alternate address.
|
||||
* @param[in] aExtAddress The extended address to match with.
|
||||
*
|
||||
* @retval true It is a broadcast or matches with the PAN id and one of the addresses.
|
||||
* @retval false It doesn't match.
|
||||
*/
|
||||
bool otMacFrameDoesAddrMatchAny(const otRadioFrame *aFrame,
|
||||
otPanId aPanId,
|
||||
otShortAddress aShortAddress,
|
||||
otShortAddress aAltShortAddress,
|
||||
const otExtAddress *aExtAddress);
|
||||
|
||||
/**
|
||||
* Get source MAC address.
|
||||
*
|
||||
@@ -319,6 +338,7 @@ typedef struct otRadioContext
|
||||
uint32_t mCslSampleTime; ///< The sample time based on the microsecond timer.
|
||||
uint16_t mCslPeriod; ///< In unit of 10 symbols.
|
||||
otShortAddress mShortAddress;
|
||||
otShortAddress mAlternateShortAddress;
|
||||
otRadioKeyType mKeyType;
|
||||
uint8_t mKeyId;
|
||||
otMacKeyMaterial mPrevKey;
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (460)
|
||||
#define OPENTHREAD_API_VERSION (461)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -588,10 +588,19 @@ otError otLinkSetPollPeriod(otInstance *aInstance, uint32_t aPollPeriod);
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to the IEEE 802.15.4 Short Address.
|
||||
* @returns The IEEE 802.15.4 Short Address.
|
||||
*/
|
||||
otShortAddress otLinkGetShortAddress(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Get the IEEE 802.15.4 alternate short address.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The alternate short address, or `OT_RADIO_INVALID_SHORT_ADDR` (0xfffe) if there is no alternate address.
|
||||
*/
|
||||
otShortAddress otLinkGetAlternateShortAddress(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of frame retries during direct transmission.
|
||||
*
|
||||
|
||||
@@ -115,6 +115,26 @@ otError otLinkRawSetPromiscuous(otInstance *aInstance, bool aEnable);
|
||||
*/
|
||||
otError otLinkRawSetShortAddress(otInstance *aInstance, uint16_t aShortAddress);
|
||||
|
||||
/**
|
||||
* Set the alternate short address.
|
||||
*
|
||||
* This is an optional API. Support for this is indicated by including the capability `OT_RADIO_CAPS_ALT_SHORT_ADDR` in
|
||||
* `otLinkRawGetCaps()`.
|
||||
*
|
||||
* When supported, the radio will accept received frames destined to the specified alternate short address in addition
|
||||
* to the short address provided in `otLinkRawSetShortAddress()`.
|
||||
*
|
||||
* The @p aShortAddress can be set to `OT_RADIO_INVALID_SHORT_ADDR` (0xfffe) to clear any previously set alternate
|
||||
* short address.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aShortAddress The alternate short address. `OT_RADIO_INVALID_SHORT_ADDR` to clear.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the alternate short address.
|
||||
* @retval OT_ERROR_INVALID_STATE The raw link-layer is not enabled.
|
||||
*/
|
||||
otError otLinkRawSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Transition the radio from Receive to Sleep.
|
||||
* Turn off the radio.
|
||||
|
||||
@@ -82,6 +82,9 @@ enum
|
||||
OT_RADIO_LQI_NONE = 0, ///< LQI measurement not supported
|
||||
OT_RADIO_RSSI_INVALID = 127, ///< Invalid or unknown RSSI value
|
||||
OT_RADIO_POWER_INVALID = 127, ///< Invalid or unknown power value
|
||||
|
||||
OT_RADIO_INVALID_SHORT_ADDR = 0xfffe, ///< Invalid short address.
|
||||
OT_RADIO_BROADCAST_SHORT_ADDR = 0xffff, ///< Broadcast short address.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,17 +123,18 @@ typedef uint16_t otRadioCaps;
|
||||
*/
|
||||
enum
|
||||
{
|
||||
OT_RADIO_CAPS_NONE = 0, ///< Radio supports no capability.
|
||||
OT_RADIO_CAPS_ACK_TIMEOUT = 1 << 0, ///< Radio supports AckTime event.
|
||||
OT_RADIO_CAPS_ENERGY_SCAN = 1 << 1, ///< Radio supports Energy Scans.
|
||||
OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA).
|
||||
OT_RADIO_CAPS_CSMA_BACKOFF = 1 << 3, ///< Radio supports CSMA backoff for frame transmission (but no retry).
|
||||
OT_RADIO_CAPS_SLEEP_TO_TX = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA.
|
||||
OT_RADIO_CAPS_TRANSMIT_SEC = 1 << 5, ///< Radio supports tx security.
|
||||
OT_RADIO_CAPS_TRANSMIT_TIMING = 1 << 6, ///< Radio supports tx at specific time.
|
||||
OT_RADIO_CAPS_RECEIVE_TIMING = 1 << 7, ///< Radio supports rx at specific time.
|
||||
OT_RADIO_CAPS_RX_ON_WHEN_IDLE = 1 << 8, ///< Radio supports RxOnWhenIdle handling.
|
||||
OT_RADIO_CAPS_TRANSMIT_FRAME_POWER = 1 << 9, ///< Radio supports setting per-frame transmit power.
|
||||
OT_RADIO_CAPS_NONE = 0, ///< Radio supports no capability.
|
||||
OT_RADIO_CAPS_ACK_TIMEOUT = 1 << 0, ///< Radio supports AckTime event.
|
||||
OT_RADIO_CAPS_ENERGY_SCAN = 1 << 1, ///< Radio supports Energy Scans.
|
||||
OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA).
|
||||
OT_RADIO_CAPS_CSMA_BACKOFF = 1 << 3, ///< Radio supports CSMA backoff for frame tx (but no retry).
|
||||
OT_RADIO_CAPS_SLEEP_TO_TX = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA.
|
||||
OT_RADIO_CAPS_TRANSMIT_SEC = 1 << 5, ///< Radio supports tx security.
|
||||
OT_RADIO_CAPS_TRANSMIT_TIMING = 1 << 6, ///< Radio supports tx at specific time.
|
||||
OT_RADIO_CAPS_RECEIVE_TIMING = 1 << 7, ///< Radio supports rx at specific time.
|
||||
OT_RADIO_CAPS_RX_ON_WHEN_IDLE = 1 << 8, ///< Radio supports RxOnWhenIdle handling.
|
||||
OT_RADIO_CAPS_TRANSMIT_FRAME_POWER = 1 << 9, ///< Radio supports setting per-frame transmit power.
|
||||
OT_RADIO_CAPS_ALT_SHORT_ADDR = 1 << 10, ///< Radio supports setting alternate short address.
|
||||
};
|
||||
|
||||
#define OT_PANID_BROADCAST 0xffff ///< IEEE 802.15.4 Broadcast PAN ID
|
||||
@@ -517,6 +521,26 @@ void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aE
|
||||
*/
|
||||
void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Set the alternate short address.
|
||||
*
|
||||
* This is an optional radio platform API. The radio platform MUST indicate support for this API by including the
|
||||
* capability `OT_RADIO_CAPS_ALT_SHORT_ADDR` in `otPlatRadioGetCaps()`.
|
||||
*
|
||||
* When supported, the radio should accept received frames destined to the specified alternate short address in
|
||||
* addition to the short address provided in `otPlatRadioSetShortAddress()`.
|
||||
*
|
||||
* The @p aShortAddress can be set to `OT_RADIO_INVALID_SHORT_ADDR` (0xfffe) to clear any previously set alternate
|
||||
* short address.
|
||||
*
|
||||
* This function is used by OpenThread stack during child-to-router role transitions, allowing the device to continue
|
||||
* receiving frames addressed to its previous short address for a short period.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aShortAddress The alternate IEEE 802.15.4 short address. `OT_RADIO_INVALID_SHORT_ADDR` to clear.
|
||||
*/
|
||||
void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Get the radio's transmit power in dBm.
|
||||
*
|
||||
|
||||
+11
-1
@@ -70,7 +70,7 @@ Done
|
||||
- [linkmetricsmgr](#linkmetricsmgr-disable)
|
||||
- [locate](#locate)
|
||||
- [log](#log-filename-filename)
|
||||
- [mac](#mac-retries-direct)
|
||||
- [mac](#mac-altshortaddr)
|
||||
- [macfilter](#macfilter)
|
||||
- [meshdiag](#meshdiag-topology-ip6-addrs-children)
|
||||
- [mliid](#mliid-iid)
|
||||
@@ -4196,6 +4196,16 @@ Print API version number.
|
||||
Done
|
||||
```
|
||||
|
||||
### mac altshortaddr
|
||||
|
||||
Get the alternate short address used by MAC layer. Can be `0xfffe` if not set.
|
||||
|
||||
```bash
|
||||
> mac altshortaddr
|
||||
0x4801
|
||||
Done
|
||||
```
|
||||
|
||||
### mac retries direct
|
||||
|
||||
Get the number of direct TX retries on the MAC layer.
|
||||
|
||||
+15
-1
@@ -7306,7 +7306,21 @@ template <> otError Interpreter::Process<Cmd("mac")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArgs[0] == "retries")
|
||||
/**
|
||||
* @cli mac altshortaddr
|
||||
* @code
|
||||
* mac altshortaddr
|
||||
* 0x4802
|
||||
* Done
|
||||
* @endcode
|
||||
* @par api_copy
|
||||
* otLinkGetAlternateShortAddress
|
||||
*/
|
||||
if (aArgs[0] == "altshortaddr")
|
||||
{
|
||||
OutputLine("0x%04x", otLinkGetAlternateShortAddress(GetInstancePtr()));
|
||||
}
|
||||
else if (aArgs[0] == "retries")
|
||||
{
|
||||
/**
|
||||
* @cli mac retries direct (get,set)
|
||||
|
||||
@@ -182,6 +182,11 @@ otShortAddress otLinkGetShortAddress(otInstance *aInstance)
|
||||
return AsCoreType(aInstance).Get<Mac::Mac>().GetShortAddress();
|
||||
}
|
||||
|
||||
otShortAddress otLinkGetAlternateShortAddress(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mac::Mac>().GetAlternateShortAddress();
|
||||
}
|
||||
|
||||
uint8_t otLinkGetMaxFrameRetriesDirect(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mac::Mac>().GetMaxFrameRetriesDirect();
|
||||
|
||||
@@ -53,6 +53,11 @@ otError otLinkRawSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
|
||||
return AsCoreType(aInstance).Get<Mac::LinkRaw>().SetShortAddress(aShortAddress);
|
||||
}
|
||||
|
||||
otError otLinkRawSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mac::LinkRaw>().SetAlternateShortAddress(aShortAddress);
|
||||
}
|
||||
|
||||
bool otLinkRawGetPromiscuous(otInstance *aInstance) { return AsCoreType(aInstance).Get<Radio>().GetPromiscuous(); }
|
||||
|
||||
otError otLinkRawSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
|
||||
@@ -161,6 +161,17 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkRaw::SetAlternateShortAddress(ShortAddress aShortAddress)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
|
||||
mSubMac.SetAlternateShortAddress(aShortAddress);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkRaw::Receive(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
@@ -183,6 +183,16 @@ public:
|
||||
*/
|
||||
Error SetShortAddress(ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Sets the alternate short address.
|
||||
*
|
||||
* @param[in] aShortAddress The short address. Use `kShortAddrInvalid` to clear it.
|
||||
*
|
||||
* @retval kErrorNone If successful.
|
||||
* @retval kErrorInvalidState If the raw link-layer isn't enabled.
|
||||
*/
|
||||
Error SetAlternateShortAddress(ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Returns PANID.
|
||||
*
|
||||
|
||||
+31
-2
@@ -118,6 +118,9 @@ Mac::Mac(Instance &aInstance)
|
||||
SetPanId(mPanId);
|
||||
SetExtAddress(randomExtAddress);
|
||||
SetShortAddress(GetShortAddress());
|
||||
#if OPENTHREAD_FTD
|
||||
SetAlternateShortAddress(kShortAddrInvalid);
|
||||
#endif
|
||||
|
||||
mMode2KeyMaterial.SetFrom(AsCoreType(&sMode2Key));
|
||||
}
|
||||
@@ -1766,6 +1769,33 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
|
||||
Error Mac::FilterDestShortAddress(ShortAddress aDestAddress) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
if (aDestAddress == GetShortAddress())
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
if ((GetAlternateShortAddress() != kShortAddrInvalid) && (aDestAddress == GetAlternateShortAddress()))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mRxOnWhenIdle && (aDestAddress == kShortAddrBroadcast))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
error = kErrorDestinationAddressFiltered;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
|
||||
{
|
||||
Address srcaddr;
|
||||
@@ -1795,8 +1825,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
|
||||
break;
|
||||
|
||||
case Address::kTypeShort:
|
||||
VerifyOrExit((mRxOnWhenIdle && dstaddr.IsBroadcast()) || dstaddr.GetShort() == GetShortAddress(),
|
||||
error = kErrorDestinationAddressFiltered);
|
||||
SuccessOrExit(error = FilterDestShortAddress(dstaddr.GetShort()));
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
// Allow multicasts from neighbor routers if FTD
|
||||
|
||||
@@ -251,6 +251,20 @@ public:
|
||||
*/
|
||||
void SetShortAddress(ShortAddress aShortAddress) { mLinks.SetShortAddress(aShortAddress); }
|
||||
|
||||
/**
|
||||
* Gets the alternate short address.
|
||||
*
|
||||
* @returns The alternate short address, or `kShortAddrInvalid` if there is no alternate address.
|
||||
*/
|
||||
ShortAddress GetAlternateShortAddress(void) const { return mLinks.GetAlternateShortAddress(); }
|
||||
|
||||
/**
|
||||
* Sets the alternate short address.
|
||||
*
|
||||
* @param[in] aShortAddress The alternate short address. Use `kShortAddrInvalid` to clear the alternate address.
|
||||
*/
|
||||
void SetAlternateShortAddress(ShortAddress aShortAddress) { mLinks.SetAlternateShortAddress(aShortAddress); }
|
||||
|
||||
/**
|
||||
* Returns the IEEE 802.15.4 PAN Channel.
|
||||
*
|
||||
@@ -807,6 +821,7 @@ private:
|
||||
bool ShouldSendBeacon(void) const;
|
||||
bool IsJoinable(void) const;
|
||||
void BeginTransmit(void);
|
||||
Error FilterDestShortAddress(ShortAddress aDestAddress) const;
|
||||
void UpdateNeighborLinkInfo(Neighbor &aNeighbor, const RxFrame &aRxFrame);
|
||||
bool HandleMacCommand(RxFrame &aFrame);
|
||||
void HandleTimer(void);
|
||||
|
||||
@@ -127,6 +127,7 @@ Links::Links(Instance &aInstance)
|
||||
, mTxFrames(aInstance)
|
||||
#if !OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
, mShortAddress(kShortAddrInvalid)
|
||||
, mAlternateShortAddress(kShortAddrInvalid)
|
||||
#endif
|
||||
{
|
||||
#if !OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
|
||||
@@ -330,6 +330,35 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the alternate MAC short address.
|
||||
*
|
||||
* @returns The alternate MAC short address, or `kShortAddrInvalid` if there is no alternate address.
|
||||
*/
|
||||
ShortAddress GetAlternateShortAddress(void) const
|
||||
{
|
||||
return
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
mSubMac.GetAlternateShortAddress();
|
||||
#else
|
||||
mAlternateShortAddress;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the alternate MAC short address.
|
||||
*
|
||||
* @param[in] aShortAddress The alternate short address. Use `kShortAddrInvalid` to clear it.
|
||||
*/
|
||||
void SetAlternateShortAddress(ShortAddress aShortAddress)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
mSubMac.SetAlternateShortAddress(aShortAddress);
|
||||
#else
|
||||
mAlternateShortAddress = aShortAddress;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MAC Extended Address.
|
||||
*
|
||||
@@ -677,6 +706,7 @@ private:
|
||||
|
||||
#if !OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
ShortAddress mShortAddress;
|
||||
ShortAddress mAlternateShortAddress;
|
||||
ExtAddress mExtAddress;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -70,8 +70,8 @@ constexpr PanId kPanIdBroadcast = 0xffff; ///< Broadcast PAN ID.
|
||||
*/
|
||||
typedef otShortAddress ShortAddress;
|
||||
|
||||
constexpr ShortAddress kShortAddrBroadcast = 0xffff; ///< Broadcast Short Address.
|
||||
constexpr ShortAddress kShortAddrInvalid = 0xfffe; ///< Invalid Short Address.
|
||||
constexpr ShortAddress kShortAddrBroadcast = OT_RADIO_BROADCAST_SHORT_ADDR; ///< Broadcast Short Address.
|
||||
constexpr ShortAddress kShortAddrInvalid = OT_RADIO_INVALID_SHORT_ADDR; ///< Invalid Short Address.
|
||||
|
||||
/**
|
||||
* Generates a random IEEE 802.15.4 PAN ID.
|
||||
|
||||
@@ -68,10 +68,11 @@ SubMac::SubMac(Instance &aInstance)
|
||||
|
||||
void SubMac::Init(void)
|
||||
{
|
||||
mState = kStateDisabled;
|
||||
mCsmaBackoffs = 0;
|
||||
mTransmitRetries = 0;
|
||||
mShortAddress = kShortAddrInvalid;
|
||||
mState = kStateDisabled;
|
||||
mCsmaBackoffs = 0;
|
||||
mTransmitRetries = 0;
|
||||
mShortAddress = kShortAddrInvalid;
|
||||
mAlternateShortAddress = kShortAddrInvalid;
|
||||
mExtAddress.Clear();
|
||||
mRxOnWhenIdle = true;
|
||||
mEnergyScanMaxRssi = Radio::kInvalidRssi;
|
||||
@@ -165,6 +166,18 @@ void SubMac::SetShortAddress(ShortAddress aShortAddress)
|
||||
LogDebg("RadioShortAddress: 0x%04x", mShortAddress);
|
||||
}
|
||||
|
||||
void SubMac::SetAlternateShortAddress(ShortAddress aShortAddress)
|
||||
{
|
||||
VerifyOrExit(mAlternateShortAddress != aShortAddress);
|
||||
|
||||
mAlternateShortAddress = aShortAddress;
|
||||
Get<Radio>().SetAlternateShortAddress(mAlternateShortAddress);
|
||||
LogDebg("RadioAlternateShortAddress: 0x%04x", mAlternateShortAddress);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void SubMac::SetExtAddress(const ExtAddress &aExtAddress)
|
||||
{
|
||||
ExtAddress address;
|
||||
|
||||
@@ -232,6 +232,20 @@ public:
|
||||
*/
|
||||
void SetShortAddress(ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Gets the alternate short address.
|
||||
*
|
||||
* @returns The alternate short address, or `kShortAddrInvalid` if there is no alternate address.
|
||||
*/
|
||||
ShortAddress GetAlternateShortAddress(void) const { return mAlternateShortAddress; }
|
||||
|
||||
/**
|
||||
* Sets the alternate short address.
|
||||
*
|
||||
* @param[in] aShortAddress The short address. Use `kShortAddrInvalid` to clear it.
|
||||
*/
|
||||
void SetAlternateShortAddress(ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Gets the extended address.
|
||||
*
|
||||
@@ -627,6 +641,7 @@ private:
|
||||
uint8_t mCsmaBackoffs;
|
||||
uint8_t mTransmitRetries;
|
||||
ShortAddress mShortAddress;
|
||||
ShortAddress mAlternateShortAddress;
|
||||
ExtAddress mExtAddress;
|
||||
bool mRxOnWhenIdle : 1;
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
|
||||
@@ -330,6 +330,13 @@ public:
|
||||
*/
|
||||
void SetShortAddress(Mac::ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Set the altrnate short address.
|
||||
*
|
||||
* @param[in] aShortAddress The alternate short address.
|
||||
*/
|
||||
void SetAlternateShortAddress(Mac::ShortAddress aShortAddress);
|
||||
|
||||
/**
|
||||
* Sets MAC key and key ID.
|
||||
*
|
||||
@@ -840,6 +847,11 @@ inline int8_t Radio::GetReceiveSensitivity(void) const { return otPlatRadioGetRe
|
||||
|
||||
inline void Radio::SetPanId(Mac::PanId aPanId) { otPlatRadioSetPanId(GetInstancePtr(), aPanId); }
|
||||
|
||||
inline void Radio::SetAlternateShortAddress(Mac::ShortAddress aShortAddress)
|
||||
{
|
||||
otPlatRadioSetAlternateShortAddress(GetInstancePtr(), aShortAddress);
|
||||
}
|
||||
|
||||
inline void Radio::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const Mac::KeyMaterial &aPrevKey,
|
||||
@@ -1003,6 +1015,8 @@ inline void Radio::SetExtendedAddress(const Mac::ExtAddress &) {}
|
||||
|
||||
inline void Radio::SetShortAddress(Mac::ShortAddress) {}
|
||||
|
||||
inline void Radio::SetAlternateShortAddress(Mac::ShortAddress) {}
|
||||
|
||||
inline void Radio::SetMacKey(uint8_t,
|
||||
uint8_t,
|
||||
const Mac::KeyMaterial &,
|
||||
|
||||
@@ -183,6 +183,12 @@ extern "C" void otPlatDiagRadioTransmitDone(otInstance *, otRadioFrame *, otErro
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Default/weak implementation of radio platform APIs
|
||||
|
||||
extern "C" OT_TOOL_WEAK void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aShortAddress);
|
||||
}
|
||||
|
||||
extern "C" OT_TOOL_WEAK uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
@@ -693,6 +693,7 @@ void Mle::SetStateDetached(void)
|
||||
Get<MeshForwarder>().SetRxOnWhenIdle(true);
|
||||
Get<Mac::Mac>().SetBeaconEnabled(false);
|
||||
#if OPENTHREAD_FTD
|
||||
Get<MleRouter>().ClearAlternateRloc16();
|
||||
Get<MleRouter>().HandleDetachStart();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
@@ -816,6 +817,13 @@ Error Mle::SetDeviceMode(DeviceMode aDeviceMode)
|
||||
|
||||
IgnoreError(Store());
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
if (!aDeviceMode.IsFullThreadDevice())
|
||||
{
|
||||
Get<MleRouter>().ClearAlternateRloc16();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsAttached())
|
||||
{
|
||||
bool shouldReattach = false;
|
||||
@@ -953,6 +961,12 @@ void Mle::SetRloc16(uint16_t aRloc16)
|
||||
Get<ThreadNetif>().AddUnicastAddress(mMeshLocalRloc);
|
||||
#if OPENTHREAD_FTD
|
||||
Get<AddressResolver>().RestartAddressQueries();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if OPENTHREAD_FTD
|
||||
Get<MleRouter>().ClearAlternateRloc16();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
, mPreviousPartitionRouterIdSequence(0)
|
||||
, mPreviousPartitionIdTimeout(0)
|
||||
, mChildRouterLinks(kChildRouterLinks)
|
||||
, mAlternateRloc16Timeout(0)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
, mMaxChildIpAddresses(0)
|
||||
#endif
|
||||
@@ -88,6 +89,30 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
#endif
|
||||
}
|
||||
|
||||
void MleRouter::SetAlternateRloc16(uint16_t aRloc16)
|
||||
{
|
||||
VerifyOrExit(aRloc16 != Mac::kShortAddrInvalid);
|
||||
|
||||
LogInfo("Setting alternate RLOC16 0x%04x", aRloc16);
|
||||
|
||||
Get<Mac::Mac>().SetAlternateShortAddress(aRloc16);
|
||||
mAlternateRloc16Timeout = kAlternateRloc16Timeout;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void MleRouter::ClearAlternateRloc16(void)
|
||||
{
|
||||
VerifyOrExit(Get<Mac::Mac>().GetAlternateShortAddress() != Mac::kShortAddrInvalid);
|
||||
|
||||
LogInfo("Clearing alternate RLOC16");
|
||||
Get<Mac::Mac>().SetAlternateShortAddress(Mac::kShortAddrInvalid);
|
||||
|
||||
exit:
|
||||
mAlternateRloc16Timeout = 0;
|
||||
}
|
||||
|
||||
void MleRouter::HandlePartitionChange(void)
|
||||
{
|
||||
mPreviousPartitionId = mLeaderData.GetPartitionId();
|
||||
@@ -1474,6 +1499,16 @@ void MleRouter::HandleTimeTick(void)
|
||||
mPreviousPartitionIdTimeout--;
|
||||
}
|
||||
|
||||
if (mAlternateRloc16Timeout > 0)
|
||||
{
|
||||
mAlternateRloc16Timeout--;
|
||||
|
||||
if (mAlternateRloc16Timeout == 0)
|
||||
{
|
||||
ClearAlternateRloc16();
|
||||
}
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Role transitions
|
||||
|
||||
@@ -3278,6 +3313,8 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage,
|
||||
SuccessOrExit(Tlv::FindTlv(*aMessage, routerMaskTlv));
|
||||
VerifyOrExit(routerMaskTlv.IsValid());
|
||||
|
||||
SetAlternateRloc16(GetRloc16());
|
||||
|
||||
SetRouterId(routerId);
|
||||
|
||||
SetStateRouter(Rloc16FromRouterId(mRouterId));
|
||||
|
||||
@@ -515,6 +515,7 @@ private:
|
||||
static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec).
|
||||
static constexpr uint8_t kLeaderDowngradeExtraDelay = 10; // Extra delay to downgrade leader (in sec).
|
||||
static constexpr uint8_t kDefaultLeaderWeight = 64;
|
||||
static constexpr uint8_t kAlternateRloc16Timeout = 8; // Time to use alternate RLOC16 (in sec).
|
||||
|
||||
// Threshold to accept a router upgrade request with reason
|
||||
// `kBorderRouterRequest` (number of BRs acting as router in
|
||||
@@ -587,6 +588,8 @@ private:
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Methods
|
||||
|
||||
void SetAlternateRloc16(uint16_t aRloc16);
|
||||
void ClearAlternateRloc16(void);
|
||||
void HandleDetachStart(void);
|
||||
void HandleChildStart(AttachMode aMode);
|
||||
void HandleSecurityPolicyChanged(void);
|
||||
@@ -680,6 +683,7 @@ private:
|
||||
uint8_t mPreviousPartitionRouterIdSequence;
|
||||
uint8_t mPreviousPartitionIdTimeout;
|
||||
uint8_t mChildRouterLinks;
|
||||
uint8_t mAlternateRloc16Timeout;
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
uint8_t mMaxChildIpAddresses;
|
||||
#endif
|
||||
|
||||
@@ -846,6 +846,17 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError RadioSpinel::SetAlternateShortAddress(uint16_t aAddress)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(sRadioCaps & OT_RADIO_CAPS_ALT_SHORT_ADDR);
|
||||
error = Set(SPINEL_PROP_MAC_15_4_ALT_SADDR, SPINEL_DATATYPE_UINT16_S, aAddress);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
otError RadioSpinel::ReadMacKey(const otMacKeyMaterial &aKeyMaterial, otMacKey &aKey)
|
||||
|
||||
@@ -223,6 +223,17 @@ public:
|
||||
*/
|
||||
otError SetShortAddress(uint16_t aAddress);
|
||||
|
||||
/**
|
||||
* Sets the alternate short address.
|
||||
*
|
||||
* @param[in] aShortAddress The alternate short address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Succeeded.
|
||||
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
|
||||
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
|
||||
*/
|
||||
otError SetAlternateShortAddress(uint16_t aAddress);
|
||||
|
||||
/**
|
||||
* Gets the factory-assigned IEEE EUI-64 for this transceiver.
|
||||
*
|
||||
|
||||
@@ -1263,6 +1263,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_MAC_ENERGY_SCAN_RESULT, "MAC_ENERGY_SCAN_RESULT"},
|
||||
{SPINEL_PROP_MAC_DATA_POLL_PERIOD, "MAC_DATA_POLL_PERIOD"},
|
||||
{SPINEL_PROP_MAC_RX_ON_WHEN_IDLE_MODE, "MAC_RX_ON_WHEN_IDLE_MODE"},
|
||||
{SPINEL_PROP_MAC_15_4_ALT_SADDR, "SPINEL_PROP_MAC_15_4_ALT_SADDR"},
|
||||
{SPINEL_PROP_MAC_ALLOWLIST, "MAC_ALLOWLIST"},
|
||||
{SPINEL_PROP_MAC_ALLOWLIST_ENABLED, "MAC_ALLOWLIST_ENABLED"},
|
||||
{SPINEL_PROP_MAC_EXTENDED_ADDR, "MAC_EXTENDED_ADDR"},
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
*
|
||||
* Please see section "Spinel definition compatibility guideline" for more details.
|
||||
*/
|
||||
#define SPINEL_RCP_API_VERSION 10
|
||||
#define SPINEL_RCP_API_VERSION 11
|
||||
|
||||
/**
|
||||
* @def SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION
|
||||
@@ -2093,6 +2093,14 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_MAC_RX_ON_WHEN_IDLE_MODE = SPINEL_PROP_MAC__BEGIN + 11,
|
||||
|
||||
/// MAC Alternate Short Address
|
||||
/** Format: `S`
|
||||
*
|
||||
* The 802.15.4 alternate short address.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_MAC_15_4_ALT_SADDR = SPINEL_PROP_MAC__BEGIN + 12,
|
||||
|
||||
SPINEL_PROP_MAC__END = 0x40,
|
||||
|
||||
SPINEL_PROP_MAC_EXT__BEGIN = 0x1300,
|
||||
|
||||
@@ -448,6 +448,9 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_DATA_POLL_PERIOD),
|
||||
#endif
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_RX_ON_WHEN_IDLE_MODE),
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_ALT_SADDR),
|
||||
#endif
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_IF_UP),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_STACK_UP),
|
||||
|
||||
@@ -407,6 +407,19 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_15_4_ALT_SADDR>(void)
|
||||
{
|
||||
uint16_t shortAddress;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
|
||||
|
||||
error = otLinkRawSetAlternateShortAddress(mInstance, shortAddress);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MULTIPAN_ACTIVE_INTERFACE>(void)
|
||||
{
|
||||
|
||||
@@ -256,6 +256,12 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
|
||||
SuccessOrDie(GetRadioSpinel().SetShortAddress(aAddress));
|
||||
}
|
||||
|
||||
void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, uint16_t aAddress)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
SuccessOrDie(GetRadioSpinel().SetAlternateShortAddress(aAddress));
|
||||
}
|
||||
|
||||
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
@@ -312,6 +312,9 @@ class Node(object):
|
||||
def get_rloc16(self):
|
||||
return self._cli_single_output('rloc16')
|
||||
|
||||
def get_mac_alt_short_addr(self):
|
||||
return self._cli_single_output('mac altshortaddr')
|
||||
|
||||
def get_ip_addrs(self, verbose=None):
|
||||
return self.cli('ipaddr', verbose)
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cli import verify
|
||||
from cli import verify_within
|
||||
import cli
|
||||
import time
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test description:
|
||||
#
|
||||
# Validate the use alternate short address after role transition from child to router.
|
||||
#
|
||||
|
||||
test_name = __file__[:-3] if __file__.endswith('.py') else __file__
|
||||
print('-' * 120)
|
||||
print('Starting \'{}\''.format(test_name))
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Creating `cli.Nodes` instances
|
||||
|
||||
speedup = 10
|
||||
cli.Node.set_time_speedup_factor(speedup)
|
||||
|
||||
leader = cli.Node()
|
||||
node = cli.Node()
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test implementation
|
||||
|
||||
INVALID_SHORT_ADDR = '0xfffe'
|
||||
ALT_SHORT_ADDR_TIMEOUT = 10
|
||||
|
||||
verify(leader.get_mac_alt_short_addr() == INVALID_SHORT_ADDR)
|
||||
|
||||
# Form topology
|
||||
|
||||
leader.form('alt-shrt-addr')
|
||||
node.join(leader, cli.JOIN_TYPE_REED)
|
||||
|
||||
verify(leader.get_state() == 'leader')
|
||||
verify(node.get_state() == 'child')
|
||||
|
||||
verify(len(leader.get_child_table()) == 1)
|
||||
|
||||
# Check the short address and alternate short address
|
||||
|
||||
node_rloc16_as_child = '0x' + node.get_rloc16()
|
||||
|
||||
verify(node.get_mac_alt_short_addr() == INVALID_SHORT_ADDR)
|
||||
|
||||
# Allow `node` to transition from child to router role
|
||||
|
||||
node.set_router_selection_jitter(1)
|
||||
node.set_router_eligible('enable')
|
||||
|
||||
|
||||
def check_node_become_router():
|
||||
verify(node.get_state() == 'router')
|
||||
|
||||
|
||||
verify_within(check_node_become_router, 10)
|
||||
|
||||
# Make sure the old short address is now being used as
|
||||
# the alternate short address.
|
||||
|
||||
node_rloc16_as_router = '0x' + node.get_rloc16()
|
||||
verify(node_rloc16_as_router != node_rloc16_as_child)
|
||||
verify(node.get_mac_alt_short_addr() == node_rloc16_as_child)
|
||||
|
||||
# Make sure the old short address is removed after the
|
||||
# timeout
|
||||
|
||||
time.sleep(ALT_SHORT_ADDR_TIMEOUT / speedup)
|
||||
|
||||
verify(node.get_mac_alt_short_addr() == INVALID_SHORT_ADDR)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test finished
|
||||
|
||||
cli.Node.finalize_all_nodes()
|
||||
|
||||
print('\'{}\' passed.'.format(test_name))
|
||||
@@ -197,6 +197,7 @@ if [ "$TORANJ_CLI" = 1 ]; then
|
||||
run cli/test-030-anycast-forwarding.py
|
||||
run cli/test-031-service-aloc-route-lookup.py
|
||||
run cli/test-032-leader-take-over.py
|
||||
run cli/test-033-alt-short-addr-role-transition.py
|
||||
run cli/test-035-context-id-change-addr-reg.py
|
||||
run cli/test-400-srp-client-server.py
|
||||
run cli/test-401-srp-server-address-cache-snoop.py
|
||||
|
||||
Reference in New Issue
Block a user