mirror of
https://github.com/espressif/openthread.git
synced 2026-07-31 08:07:47 +00:00
[mle] support for long routes (#2775)
This commit introduces changes necessary to support long routes (i.e. route cost >= 16). This is an experimental feature that requires changes to the route information communicated in MLE messages. As a result, it is not compatible with the Thread 1.1 specification. This feature is disabled by default.
This commit is contained in:
committed by
Jonathan Hui
parent
bb064cd074
commit
c7e62553e5
@@ -85,6 +85,9 @@
|
||||
/* Define to 1 to enable Service feature. */
|
||||
#define OPENTHREAD_ENABLE_SERVICE 0
|
||||
|
||||
/* Define to 1 to enable long routes support. */
|
||||
#define OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES 0
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "openthread"
|
||||
|
||||
|
||||
@@ -1749,4 +1749,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
*
|
||||
* Enable experimental mode for 'deep' networks, allowing packet routes up to 32 nodes.
|
||||
* This mode is incompatible with Thread 1.1.1 and older.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
#define OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES 0
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
|
||||
|
||||
@@ -91,13 +91,21 @@ enum
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAdvertiseIntervalMin = 1, ///< ADVERTISEMENT_I_MIN (sec)
|
||||
kAdvertiseIntervalMax = 32, ///< ADVERTISEMENT_I_MAX (sec)
|
||||
kFailedRouterTransmissions = 4, ///< FAILED_ROUTER_TRANSMISSIONS
|
||||
kRouterIdReuseDelay = 100, ///< ID_REUSE_DELAY (sec)
|
||||
kRouterIdSequencePeriod = 10, ///< ID_SEQUENCE_PERIOD (sec)
|
||||
kMaxNeighborAge = 100, ///< MAX_NEIGHBOR_AGE (sec)
|
||||
kMaxRouteCost = 16, ///< MAX_ROUTE_COST
|
||||
kAdvertiseIntervalMin = 1, ///< ADVERTISEMENT_I_MIN (sec)
|
||||
#if OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
kAdvertiseIntervalMax = 5, ///< ADVERTISEMENT_I_MAX (sec) proposal
|
||||
#else
|
||||
kAdvertiseIntervalMax = 32, ///< ADVERTISEMENT_I_MAX (sec)
|
||||
#endif
|
||||
kFailedRouterTransmissions = 4, ///< FAILED_ROUTER_TRANSMISSIONS
|
||||
kRouterIdReuseDelay = 100, ///< ID_REUSE_DELAY (sec)
|
||||
kRouterIdSequencePeriod = 10, ///< ID_SEQUENCE_PERIOD (sec)
|
||||
kMaxNeighborAge = 100, ///< MAX_NEIGHBOR_AGE (sec)
|
||||
#if OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
kMaxRouteCost = 127, ///< MAX_ROUTE_COST proposal
|
||||
#else
|
||||
kMaxRouteCost = 16, ///< MAX_ROUTE_COST
|
||||
#endif
|
||||
kMaxRouterId = 62, ///< MAX_ROUTER_ID
|
||||
kInvalidRouterId = kMaxRouterId + 1, ///< Value indicating incorrect Router Id
|
||||
kMaxRouters = OPENTHREAD_CONFIG_MAX_ROUTERS, ///< MAX_ROUTERS
|
||||
@@ -128,10 +136,10 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
kLinkQuality3LinkCost = 1, ///< Link Cost for Link Quality 3
|
||||
kLinkQuality2LinkCost = 2, ///< Link Cost for Link Quality 2
|
||||
kLinkQuality1LinkCost = 4, ///< Link Cost for Link Quality 1
|
||||
kLinkQuality0LinkCost = 16, ///< Link Cost for Link Quality 0
|
||||
kLinkQuality3LinkCost = 1, ///< Link Cost for Link Quality 3
|
||||
kLinkQuality2LinkCost = 2, ///< Link Cost for Link Quality 2
|
||||
kLinkQuality1LinkCost = 4, ///< Link Cost for Link Quality 1
|
||||
kLinkQuality0LinkCost = kMaxRouteCost, ///< Link Cost for Link Quality 0
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -473,6 +473,8 @@ private:
|
||||
uint32_t mFrameCounter;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
#if !OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
|
||||
/**
|
||||
* This class implements Source Address TLV generation and parsing.
|
||||
*
|
||||
@@ -647,6 +649,222 @@ private:
|
||||
uint8_t mRouteData[kMaxRouterId + 1];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
#else // OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
|
||||
/**
|
||||
* This class implements Source Address TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouteTlv : public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(kRoute);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const
|
||||
{
|
||||
return GetLength() >= sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) &&
|
||||
GetLength() <= sizeof(*this) - sizeof(Tlv);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Router ID Sequence value.
|
||||
*
|
||||
* @returns The Router ID Sequence value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
|
||||
|
||||
/**
|
||||
* This method sets the Router ID Sequence value.
|
||||
*
|
||||
* @param[in] aSequence The Router ID Sequence value.
|
||||
*
|
||||
*/
|
||||
void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
|
||||
|
||||
/**
|
||||
* This method clears the Router ID Mask.
|
||||
*
|
||||
*/
|
||||
void ClearRouterIdMask(void) { memset(mRouterIdMask, 0, sizeof(mRouterIdMask)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not a Router ID bit is set.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
*
|
||||
* @retval TRUE If the Router ID bit is set.
|
||||
* @retval FALSE If the Router ID bit is not set.
|
||||
*
|
||||
*/
|
||||
bool IsRouterIdSet(uint8_t aRouterId) const
|
||||
{
|
||||
return (mRouterIdMask[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Router ID bit.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID bit to set.
|
||||
*
|
||||
*/
|
||||
void SetRouterId(uint8_t aRouterId) { mRouterIdMask[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
|
||||
|
||||
/**
|
||||
* This method returns the Route Data Length value.
|
||||
*
|
||||
* @returns The Route Data Length value in bytes
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); }
|
||||
|
||||
/**
|
||||
* This method sets the Route Data Length value.
|
||||
*
|
||||
* @param[in] aLength The Route Data Length value in number of router entries
|
||||
*
|
||||
*/
|
||||
void SetRouteDataLength(uint8_t aLength)
|
||||
{
|
||||
SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength + (aLength + 1) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Route Cost value for a given Router ID.
|
||||
*
|
||||
* @returns The Route Cost value for a given Router ID.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouteCost(uint8_t aRouterId) const
|
||||
{
|
||||
if (aRouterId & 1)
|
||||
{
|
||||
return mRouteData[aRouterId + aRouterId / 2 + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<uint8_t>((mRouteData[aRouterId + aRouterId / 2] & kRouteCostMask) << kOddEntryOffset) |
|
||||
((mRouteData[aRouterId + aRouterId / 2 + 1] &
|
||||
static_cast<uint8_t>(kRouteCostMask << kOddEntryOffset)) >>
|
||||
kOddEntryOffset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Route Cost value for a given Router ID.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
* @param[in] aRouteCost The Route Cost value.
|
||||
*
|
||||
*/
|
||||
void SetRouteCost(uint8_t aRouterId, uint8_t aRouteCost)
|
||||
{
|
||||
if (aRouterId & 1)
|
||||
{
|
||||
mRouteData[aRouterId + aRouterId / 2 + 1] = aRouteCost;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRouteData[aRouterId + aRouterId / 2] = (mRouteData[aRouterId + aRouterId / 2] & ~kRouteCostMask) |
|
||||
((aRouteCost >> kOddEntryOffset) & kRouteCostMask);
|
||||
mRouteData[aRouterId + aRouterId / 2 + 1] = static_cast<uint8_t>(
|
||||
(mRouteData[aRouterId + aRouterId / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) |
|
||||
((aRouteCost & kRouteCostMask) << kOddEntryOffset));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Link Quality In value for a given Router ID.
|
||||
*
|
||||
* @returns The Link Quality In value for a given Router ID.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLinkQualityIn(uint8_t aRouterId) const
|
||||
{
|
||||
int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
|
||||
return (mRouteData[aRouterId + aRouterId / 2] & (kLinkQualityInMask >> offset)) >>
|
||||
(kLinkQualityInOffset - offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Link Quality In value for a given Router ID.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
* @param[in] aLinkQuality The Link Quality In value for a given Router ID.
|
||||
*
|
||||
*/
|
||||
void SetLinkQualityIn(uint8_t aRouterId, uint8_t aLinkQuality)
|
||||
{
|
||||
int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
|
||||
mRouteData[aRouterId + aRouterId / 2] =
|
||||
(mRouteData[aRouterId + aRouterId / 2] & ~(kLinkQualityInMask >> offset)) |
|
||||
((aLinkQuality << (kLinkQualityInOffset - offset)) & (kLinkQualityInMask >> offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Link Quality Out value for a given Router ID.
|
||||
*
|
||||
* @returns The Link Quality Out value for a given Router ID.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLinkQualityOut(uint8_t aRouterId) const
|
||||
{
|
||||
int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
|
||||
return (mRouteData[aRouterId + aRouterId / 2] & (kLinkQualityOutMask >> offset)) >>
|
||||
(kLinkQualityOutOffset - offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Link Quality Out value for a given Router ID.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
* @param[in] aLinkQuality The Link Quality Out value for a given Router ID.
|
||||
*
|
||||
*/
|
||||
void SetLinkQualityOut(uint8_t aRouterId, uint8_t aLinkQuality)
|
||||
{
|
||||
int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
|
||||
mRouteData[aRouterId + aRouterId / 2] =
|
||||
(mRouteData[aRouterId + aRouterId / 2] & ~(kLinkQualityOutMask >> offset)) |
|
||||
((aLinkQuality << (kLinkQualityOutOffset - offset)) & (kLinkQualityOutMask >> offset));
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kLinkQualityOutOffset = 6,
|
||||
kLinkQualityOutMask = 3 << kLinkQualityOutOffset,
|
||||
kLinkQualityInOffset = 4,
|
||||
kLinkQualityInMask = 3 << kLinkQualityInOffset,
|
||||
kRouteCostOffset = 0,
|
||||
kRouteCostMask = 0xf << kRouteCostOffset,
|
||||
kOddEntryOffset = 4,
|
||||
};
|
||||
uint8_t mRouterIdSequence;
|
||||
uint8_t mRouterIdMask[BitVectorBytes(kMaxRouterId + 1)];
|
||||
// Since we do hold 12 (compressable to 11) bits of data per router, each entry occupies 1.5 bytes, consecutively.
|
||||
// First 4 bits are link qualities, remaining 8 bits are route cost.
|
||||
uint8_t mRouteData[kMaxRouterId + 1 + kMaxRouterId / 2 + 1];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
|
||||
/**
|
||||
* This class implements Source Address TLV generation and parsing.
|
||||
*
|
||||
|
||||
@@ -911,7 +911,12 @@ public:
|
||||
private:
|
||||
uint8_t mNextHop; ///< The next hop towards this router
|
||||
uint8_t mLinkQualityOut : 2; ///< The link quality out for this router
|
||||
uint8_t mCost : 4; ///< The cost to this router via neighbor router
|
||||
|
||||
#if OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
|
||||
uint8_t mCost; ///< The cost to this router via neighbor router
|
||||
#else
|
||||
uint8_t mCost : 4; ///< The cost to this router via neighbor router
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
|
||||
Reference in New Issue
Block a user