mirror of
https://github.com/espressif/openthread.git
synced 2026-09-13 20:50:05 +00:00
[router-table] reduce router allocation from 63 to 32 (#2678)
The existing router table allocated a router entry for every possible router id value (63). Beacuse Thread only allows at most 32 active routers in a given network, allocating 63 router entries is wasteful. This commit allocates only 32 router entries and dynamically manages the pool of router entries.
This commit is contained in:
@@ -141,6 +141,7 @@
|
||||
<ClCompile Include="..\..\src\core\thread\network_data_local.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\network_diagnostic.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\panid_query_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\router_table.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\src_match_controller.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\thread_netif.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\topology.cpp" />
|
||||
@@ -226,6 +227,7 @@
|
||||
<ClInclude Include="..\..\src\core\thread\network_diagnostic.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\network_diagnostic_tlvs.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\panid_query_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\router_table.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\src_match_controller.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\thread_netif.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\thread_tlvs.hpp" />
|
||||
|
||||
@@ -252,6 +252,9 @@
|
||||
<ClCompile Include="..\..\src\core\thread\panid_query_server.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\thread\router_table.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\thread\src_match_controller.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
@@ -503,6 +506,9 @@
|
||||
<ClInclude Include="..\..\src\core\thread\panid_query_server.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\thread\router_table.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\thread\src_match_controller.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
<ClCompile Include="..\..\src\core\thread\network_data_local.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\network_diagnostic.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\panid_query_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\router_table.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\src_match_controller.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\thread_netif.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\topology.cpp" />
|
||||
@@ -260,6 +261,7 @@
|
||||
<ClInclude Include="..\..\src\core\thread\network_diagnostic.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\network_diagnostic_tlvs.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\panid_query_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\router_table.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\src_match_controller.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\thread_netif.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\thread_tlvs.hpp" />
|
||||
|
||||
@@ -255,6 +255,9 @@
|
||||
<ClCompile Include="..\..\src\core\thread\panid_query_server.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\thread\router_table.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\thread\src_match_controller.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
@@ -506,6 +509,9 @@
|
||||
<ClInclude Include="..\..\src\core\thread\panid_query_server.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\thread\router_table.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\thread\src_match_controller.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -266,8 +266,9 @@ OTAPI void OTCALL otThreadSetRouterUpgradeThreshold(otInstance *aInstance, uint8
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aRouterId The Router ID to release. Valid range is [0, 62].
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully released the Router ID specified by aRouterId.
|
||||
* @retval OT_ERROR_INVALID_STATE The Router ID was not allocated.
|
||||
* @retval OT_ERROR_NONE Successfully released the router id.
|
||||
* @retval OT_ERROR_INVALID_STATE The device is not currently operating as a leader.
|
||||
* @retval OT_ERROR_NOT_FOUND The router id is not currently allocated.
|
||||
*
|
||||
*/
|
||||
OTAPI otError OTCALL otThreadReleaseRouterId(otInstance *aInstance, uint8_t aRouterId);
|
||||
|
||||
@@ -188,6 +188,7 @@ SOURCES_COMMON = \
|
||||
thread/network_data_local.cpp \
|
||||
thread/network_diagnostic.cpp \
|
||||
thread/panid_query_server.cpp \
|
||||
thread/router_table.cpp \
|
||||
thread/src_match_controller.cpp \
|
||||
thread/thread_netif.cpp \
|
||||
thread/tmf_proxy.cpp \
|
||||
@@ -313,6 +314,7 @@ HEADERS_COMMON = \
|
||||
thread/panid_query_server.hpp \
|
||||
thread/network_diagnostic.hpp \
|
||||
thread/network_diagnostic_tlvs.hpp \
|
||||
thread/router_table.hpp \
|
||||
thread/src_match_controller.hpp \
|
||||
thread/thread_netif.hpp \
|
||||
thread/thread_tlvs.hpp \
|
||||
|
||||
@@ -364,7 +364,7 @@ otError otThreadGetParentInfo(otInstance *aInstance, otRouterInfo *aParentInfo)
|
||||
aParentInfo->mLinkQualityIn = parent->GetLinkInfo().GetLinkQuality();
|
||||
aParentInfo->mLinkQualityOut = parent->GetLinkQualityOut();
|
||||
aParentInfo->mAge = static_cast<uint8_t>(TimerMilli::MsecToSec(TimerMilli::GetNow() - parent->GetLastHeard()));
|
||||
aParentInfo->mAllocated = parent->IsAllocated();
|
||||
aParentInfo->mAllocated = true;
|
||||
aParentInfo->mLinkEstablished = parent->GetState() == Neighbor::kStateValid;
|
||||
|
||||
exit:
|
||||
|
||||
@@ -168,7 +168,7 @@ otError otThreadReleaseRouterId(otInstance *aInstance, uint8_t aRouterId)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetThreadNetif().GetMle().ReleaseRouterId(aRouterId);
|
||||
return instance.GetThreadNetif().GetMle().GetRouterTable().Release(aRouterId);
|
||||
}
|
||||
|
||||
otError otThreadBecomeRouter(otInstance *aInstance)
|
||||
@@ -283,7 +283,7 @@ uint8_t otThreadGetRouterIdSequence(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetThreadNetif().GetMle().GetRouterIdSequence();
|
||||
return instance.GetThreadNetif().GetMle().GetRouterTable().GetRouterIdSequence();
|
||||
}
|
||||
|
||||
uint8_t otThreadGetMaxRouterId(otInstance *aInstance)
|
||||
@@ -299,7 +299,7 @@ otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRoute
|
||||
|
||||
VerifyOrExit(aRouterInfo != NULL, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = instance.GetThreadNetif().GetMle().GetRouterInfo(aRouterId, *aRouterInfo);
|
||||
error = instance.GetThreadNetif().GetMle().GetRouterTable().GetRouterInfo(aRouterId, *aRouterInfo);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "common/logging.hpp"
|
||||
#include "common/new.hpp"
|
||||
#include "thread/router_table.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -251,6 +252,11 @@ template <> ChildTable &Instance::Get(void)
|
||||
return GetThreadNetif().GetMle().GetChildTable();
|
||||
}
|
||||
|
||||
template <> RouterTable &Instance::Get(void)
|
||||
{
|
||||
return GetThreadNetif().GetMle().GetRouterTable();
|
||||
}
|
||||
|
||||
template <> Ip6::Netif &Instance::Get(void)
|
||||
{
|
||||
return GetThreadNetif();
|
||||
|
||||
@@ -261,6 +261,19 @@
|
||||
#define OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE 1024
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAX_ROUTERS
|
||||
*
|
||||
* The maximum number of routers in a Thread network.
|
||||
*
|
||||
* @note Thread specifies this value to be 32. Changing this value may cause interoperability issues with standard
|
||||
* Thread 1.1 devices.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MAX_ROUTERS
|
||||
#define OPENTHREAD_CONFIG_MAX_ROUTERS 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAX_CHILDREN
|
||||
*
|
||||
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
*
|
||||
* The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
|
||||
* If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
|
||||
* `GetChild()` returns `NULL` and `IsDone()` returns `true`.
|
||||
* `GetChild()` returns `NULL` and `IsDone()` returns `true`).
|
||||
*
|
||||
*/
|
||||
void Advance(void);
|
||||
|
||||
@@ -119,9 +119,9 @@ const otMasterKey &KeyManager::GetMasterKey(void) const
|
||||
|
||||
otError KeyManager::SetMasterKey(const otMasterKey &aKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Router *routers;
|
||||
uint8_t num;
|
||||
Mle::MleRouter &mle = GetNetif().GetMle();
|
||||
otError error = OT_ERROR_NONE;
|
||||
Router * routers;
|
||||
|
||||
VerifyOrExit(memcmp(&mMasterKey, &aKey, sizeof(mMasterKey)) != 0);
|
||||
|
||||
@@ -130,19 +130,17 @@ otError KeyManager::SetMasterKey(const otMasterKey &aKey)
|
||||
ComputeKey(mKeySequence, mKey);
|
||||
|
||||
// reset parent frame counters
|
||||
routers = GetNetif().GetMle().GetParent();
|
||||
routers = mle.GetParent();
|
||||
routers->SetKeySequence(0);
|
||||
routers->SetLinkFrameCounter(0);
|
||||
routers->SetMleFrameCounter(0);
|
||||
|
||||
// reset router frame counters
|
||||
routers = GetNetif().GetMle().GetRouters(&num);
|
||||
|
||||
for (uint8_t i = 0; i < num; i++)
|
||||
for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter.Advance())
|
||||
{
|
||||
routers[i].SetKeySequence(0);
|
||||
routers[i].SetLinkFrameCounter(0);
|
||||
routers[i].SetMleFrameCounter(0);
|
||||
iter.GetRouter()->SetKeySequence(0);
|
||||
iter.GetRouter()->SetLinkFrameCounter(0);
|
||||
iter.GetRouter()->SetMleFrameCounter(0);
|
||||
}
|
||||
|
||||
// reset child frame counters
|
||||
|
||||
@@ -2764,7 +2764,6 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
|
||||
MleFrameCounterTlv mleFrameCounter;
|
||||
ChallengeTlv challenge;
|
||||
Mac::ExtAddress extAddress;
|
||||
int8_t diff;
|
||||
|
||||
// Source Address
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
|
||||
@@ -2808,9 +2807,11 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kConnectivity, sizeof(connectivity), connectivity));
|
||||
VerifyOrExit(connectivity.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
if ((mDeviceMode & ModeTlv::kModeFFD) && (mRole != OT_DEVICE_ROLE_DETACHED))
|
||||
{
|
||||
diff = static_cast<int8_t>(connectivity.GetIdSequence() - netif.GetMle().GetRouterIdSequence());
|
||||
int8_t diff =
|
||||
static_cast<int8_t>(connectivity.GetIdSequence() - netif.GetMle().GetRouterTable().GetRouterIdSequence());
|
||||
|
||||
switch (mParentRequestMode)
|
||||
{
|
||||
@@ -2821,8 +2822,8 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
|
||||
case kAttachSame1:
|
||||
case kAttachSame2:
|
||||
VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId());
|
||||
VerifyOrExit(diff > 0 ||
|
||||
(diff == 0 && netif.GetMle().GetLeaderAge() < netif.GetMle().GetNetworkIdTimeout()));
|
||||
VerifyOrExit(diff > 0 || (diff == 0 && netif.GetMle().GetRouterTable().GetLeaderAge() <
|
||||
netif.GetMle().GetNetworkIdTimeout()));
|
||||
break;
|
||||
|
||||
case kAttachBetter:
|
||||
@@ -2832,6 +2833,7 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// if already have a candidate parent, only seek a better parent
|
||||
if (mParentCandidate.GetState() == Neighbor::kStateParentResponse)
|
||||
|
||||
@@ -86,27 +86,27 @@ enum
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAdvertiseIntervalMin = 1, ///< ADVERTISEMENT_I_MIN (seconds)
|
||||
kAdvertiseIntervalMax = 32, ///< ADVERTISEMENT_I_MAX (seconds)
|
||||
kFailedRouterTransmissions = 4, ///< FAILED_ROUTER_TRANSMISSIONS
|
||||
kRouterIdReuseDelay = 100, ///< ID_REUSE_DELAY (seconds)
|
||||
kRouterIdSequencePeriod = 10, ///< ID_SEQUENCE_PERIOD (seconds)
|
||||
kMaxNeighborAge = 100, ///< MAX_NEIGHBOR_AGE (seconds)
|
||||
kMaxRouteCost = 16, ///< MAX_ROUTE_COST
|
||||
kMaxRouterId = 62, ///< MAX_ROUTER_ID
|
||||
kInvalidRouterId = kMaxRouterId + 1, ///< Value indicating incorrect Router Id
|
||||
kMaxRouters = 32, ///< MAX_ROUTERS
|
||||
kMinDowngradeNeighbors = 7, ///< MIN_DOWNGRADE_NEIGHBORS
|
||||
kNetworkIdTimeout = 120, ///< NETWORK_ID_TIMEOUT (seconds)
|
||||
kParentRouteToLeaderTimeout = 20, ///< PARENT_ROUTE_TO_LEADER_TIMEOUT (seconds)
|
||||
kRouterSelectionJitter = 120, ///< ROUTER_SELECTION_JITTER (seconds)
|
||||
kRouterDowngradeThreshold = 23, ///< ROUTER_DOWNGRADE_THRESHOLD (routers)
|
||||
kRouterUpgradeThreshold = 16, ///< ROUTER_UPGRADE_THRESHOLD (routers)
|
||||
kMaxLeaderToRouterTimeout = 90, ///< INFINITE_COST_TIMEOUT (seconds)
|
||||
kReedAdvertiseInterval = 570, ///< REED_ADVERTISEMENT_INTERVAL (seconds)
|
||||
kReedAdvertiseJitter = 60, ///< REED_ADVERTISEMENT_JITTER (seconds)
|
||||
kLeaderWeight = 64, ///< Default leader weight for the Thread Network Partition
|
||||
kMleEndDeviceTimeout = OPENTHREAD_CONFIG_DEFAULT_CHILD_TIMEOUT, ///< MLE_END_DEVICE_TIMEOUT (seconds)
|
||||
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
|
||||
kMaxRouterId = 62, ///< MAX_ROUTER_ID
|
||||
kInvalidRouterId = kMaxRouterId + 1, ///< Value indicating incorrect Router Id
|
||||
kMaxRouters = OPENTHREAD_CONFIG_MAX_ROUTERS, ///< MAX_ROUTERS
|
||||
kMinDowngradeNeighbors = 7, ///< MIN_DOWNGRADE_NEIGHBORS
|
||||
kNetworkIdTimeout = 120, ///< NETWORK_ID_TIMEOUT (sec)
|
||||
kParentRouteToLeaderTimeout = 20, ///< PARENT_ROUTE_TO_LEADER_TIMEOUT (sec)
|
||||
kRouterSelectionJitter = 120, ///< ROUTER_SELECTION_JITTER (sec)
|
||||
kRouterDowngradeThreshold = 23, ///< ROUTER_DOWNGRADE_THRESHOLD (routers)
|
||||
kRouterUpgradeThreshold = 16, ///< ROUTER_UPGRADE_THRESHOLD (routers)
|
||||
kMaxLeaderToRouterTimeout = 90, ///< INFINITE_COST_TIMEOUT (sec)
|
||||
kReedAdvertiseInterval = 570, ///< REED_ADVERTISEMENT_INTERVAL (sec)
|
||||
kReedAdvertiseJitter = 60, ///< REED_ADVERTISEMENT_JITTER (sec)
|
||||
kLeaderWeight = 64, ///< Default leader weight
|
||||
kMleEndDeviceTimeout = OPENTHREAD_CONFIG_DEFAULT_CHILD_TIMEOUT, ///< MLE_END_DEVICE_TIMEOUT (sec)
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+328
-664
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,7 @@
|
||||
#include "thread/child_table.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/mle_tlvs.hpp"
|
||||
#include "thread/router_table.hpp"
|
||||
#include "thread/thread_tlvs.hpp"
|
||||
#include "thread/topology.hpp"
|
||||
|
||||
@@ -134,30 +135,6 @@ public:
|
||||
*/
|
||||
otError BecomeLeader(void);
|
||||
|
||||
/**
|
||||
* This method returns the number of active routers.
|
||||
*
|
||||
* @returns The number of active routers.
|
||||
*
|
||||
*/
|
||||
uint8_t GetActiveRouterCount(void) const;
|
||||
|
||||
/**
|
||||
* This method returns the number of active neighbor routers.
|
||||
*
|
||||
* @returns The number of active neighbor routers.
|
||||
*
|
||||
*/
|
||||
uint8_t GetActiveNeighborRouterCount(void) const;
|
||||
|
||||
/**
|
||||
* This method returns the time in seconds since the last Router ID Sequence update.
|
||||
*
|
||||
* @returns The time in seconds since the last Router ID Sequence update.
|
||||
*
|
||||
*/
|
||||
uint32_t GetLeaderAge(void) const;
|
||||
|
||||
/**
|
||||
* This method returns the Leader Weighting value for this Thread interface.
|
||||
*
|
||||
@@ -306,14 +283,6 @@ public:
|
||||
*/
|
||||
uint8_t GetRouterSelectionJitterTimeout(void) { return mRouterSelectionJitterTimeout; }
|
||||
|
||||
/**
|
||||
* This method returns the current Router ID Sequence value.
|
||||
*
|
||||
* @returns The current Router ID Sequence value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
|
||||
|
||||
/**
|
||||
* This method returns the ROUTER_UPGRADE_THRESHOLD value.
|
||||
*
|
||||
@@ -346,17 +315,6 @@ public:
|
||||
*/
|
||||
void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; }
|
||||
|
||||
/**
|
||||
* This method release a given Router ID.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID to release.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully released the Router ID.
|
||||
* @retval OT_ERROR_INVALID_STATE The Router ID was not allocated.
|
||||
*
|
||||
*/
|
||||
otError ReleaseRouterId(uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* This method removes a link to a neighbor.
|
||||
*
|
||||
@@ -523,48 +481,6 @@ public:
|
||||
*/
|
||||
otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Router array.
|
||||
*
|
||||
* @param[out] aNumRouters A pointer to output the number of routers.
|
||||
*
|
||||
* @returns A pointer to the Router array.
|
||||
*
|
||||
*/
|
||||
Router *GetRouters(uint8_t *aNumRouters);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Router entry.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
*
|
||||
* @returns A pointer to a Router entry or NULL if @p aRouterId is out-of-range.
|
||||
*
|
||||
*/
|
||||
Router *GetRouter(uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Router entry.
|
||||
*
|
||||
* @param[in] aRouterId The Router ID.
|
||||
*
|
||||
* @returns A pointer to a Router entry or NULL if @p aRouterId is out-of-range.
|
||||
*
|
||||
*/
|
||||
const Router *GetRouter(uint8_t aRouterId) const;
|
||||
|
||||
/**
|
||||
* This method retains diagnostic information for a given router.
|
||||
*
|
||||
* @param[in] aRouterId The router ID or RLOC16 for a given router.
|
||||
* @param[out] aRouterInfo The router information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully retrieved the router info for given id.
|
||||
* @retval OT_ERROR_NOT_FOUND No router entry with the given id.
|
||||
*
|
||||
*/
|
||||
otError GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the given Thread partition attributes are preferred.
|
||||
*
|
||||
@@ -641,6 +557,8 @@ public:
|
||||
*/
|
||||
otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
|
||||
|
||||
otError SendLinkRequest(Neighbor *aNeighbor);
|
||||
|
||||
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
/**
|
||||
* This method sets steering data out of band
|
||||
@@ -729,6 +647,28 @@ public:
|
||||
*/
|
||||
bool IsSleepyChildSubscribed(const Ip6::Address &aAddress, Child &aChild);
|
||||
|
||||
/**
|
||||
* This method resets the MLE Advertisement Trickle timer interval.
|
||||
*
|
||||
*/
|
||||
void ResetAdvertiseInterval(void);
|
||||
|
||||
/**
|
||||
* This method returns a reference to the router table object.
|
||||
*
|
||||
*/
|
||||
RouterTable &GetRouterTable(void) { return mRouterTable; }
|
||||
|
||||
/**
|
||||
* This static method converts link quality to route cost.
|
||||
*
|
||||
* @param[in] aLinkQuality The link quality.
|
||||
*
|
||||
* @returns The link cost corresponding to @p aLinkQuality.
|
||||
*
|
||||
*/
|
||||
static uint8_t LinkQualityToCost(uint8_t aLinkQuality);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -770,14 +710,12 @@ private:
|
||||
|
||||
otError ProcessRouteTlv(const RouteTlv &aRoute);
|
||||
void StopAdvertiseTimer(void);
|
||||
void ResetAdvertiseInterval(void);
|
||||
otError SendAddressSolicit(ThreadStatusTlv::Status aStatus);
|
||||
otError SendAddressRelease(void);
|
||||
void SendAddressSolicitResponse(const Coap::Header & aRequest,
|
||||
uint8_t aRouterId,
|
||||
const Router * aRouter,
|
||||
const Ip6::MessageInfo &aMessageInfo);
|
||||
otError SendAdvertisement(void);
|
||||
otError SendLinkRequest(Neighbor *aNeighbor);
|
||||
otError SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
|
||||
Neighbor * aNeighbor,
|
||||
const TlvRequestTlv & aTlvRequest,
|
||||
@@ -823,23 +761,16 @@ private:
|
||||
const otMessageInfo *aMessageInfo);
|
||||
void HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static uint8_t LinkQualityToCost(uint8_t aLinkQuality);
|
||||
|
||||
static bool IsSingleton(const RouteTlv &aRouteTlv);
|
||||
|
||||
void HandlePartitionChange(void);
|
||||
|
||||
void SetChildStateToValid(Child &aChild);
|
||||
bool HasChildren(void);
|
||||
void RemoveChildren(void);
|
||||
bool HasMinDowngradeNeighborRouters(void);
|
||||
bool HasOneNeighborwithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
|
||||
bool HasSmallNumberOfChildren(void);
|
||||
uint8_t GetMinDowngradeNeighborRouters(void);
|
||||
|
||||
uint8_t AllocateRouterId(void);
|
||||
uint8_t AllocateRouterId(uint8_t aRouterId);
|
||||
bool InRouterIdMask(uint8_t aRouterId);
|
||||
void SetChildStateToValid(Child &aChild);
|
||||
bool HasChildren(void);
|
||||
void RemoveChildren(void);
|
||||
bool HasMinDowngradeNeighborRouters(void);
|
||||
bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
|
||||
bool HasSmallNumberOfChildren(void);
|
||||
|
||||
static bool HandleAdvertiseTimer(TrickleTimer &aTimer);
|
||||
bool HandleAdvertiseTimer(void);
|
||||
@@ -854,11 +785,8 @@ private:
|
||||
Coap::Resource mAddressSolicit;
|
||||
Coap::Resource mAddressRelease;
|
||||
|
||||
uint8_t mRouterIdSequence;
|
||||
uint32_t mRouterIdSequenceLastUpdated;
|
||||
Router mRouters[kMaxRouterId + 1];
|
||||
|
||||
ChildTable mChildTable;
|
||||
ChildTable mChildTable;
|
||||
RouterTable mRouterTable;
|
||||
|
||||
otThreadChildTableCallback mChildTableChangedCallback;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "thread/child_table.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/mle_tlvs.hpp"
|
||||
#include "thread/router_table.hpp"
|
||||
#include "thread/thread_tlvs.hpp"
|
||||
|
||||
namespace ot {
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
explicit MleRouter(Instance &aInstance)
|
||||
: Mle(aInstance)
|
||||
, mChildTable(aInstance)
|
||||
, mRouterTable(aInstance)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,12 +64,8 @@ public:
|
||||
otError BecomeRouter(ThreadStatusTlv::Status) { return OT_ERROR_NOT_CAPABLE; }
|
||||
otError BecomeLeader(void) { return OT_ERROR_NOT_CAPABLE; }
|
||||
|
||||
uint8_t GetActiveRouterCount(void) const { return 0; }
|
||||
uint8_t GetActiveNeighborRouterCount(void) const { return 0; }
|
||||
uint8_t GetRouterSelectionJitterTimeout(void) { return 0; }
|
||||
|
||||
uint32_t GetLeaderAge(void) const { return 0; }
|
||||
|
||||
uint32_t GetPreviousPartitionId(void) const { return 0; }
|
||||
void SetPreviousPartitionId(uint32_t) {}
|
||||
void SetRouterId(uint8_t) {}
|
||||
@@ -80,12 +78,11 @@ public:
|
||||
uint8_t GetLinkCost(uint16_t) { return 0; }
|
||||
uint8_t GetCost(uint16_t) { return 0; }
|
||||
|
||||
uint8_t GetRouterIdSequence(void) const { return 0; }
|
||||
|
||||
otError RemoveNeighbor(const Mac::Address &) { return BecomeDetached(); }
|
||||
otError RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
|
||||
|
||||
ChildTable &GetChildTable(void) { return mChildTable; }
|
||||
ChildTable & GetChildTable(void) { return mChildTable; }
|
||||
RouterTable &GetRouterTable(void) { return mRouterTable; }
|
||||
|
||||
bool IsMinimalChild(uint16_t) { return false; }
|
||||
|
||||
@@ -105,16 +102,6 @@ public:
|
||||
|
||||
otError GetNextNeighborInfo(otNeighborInfoIterator &, otNeighborInfo &) { return OT_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
Router *GetRouters(uint8_t *aNumRouters)
|
||||
{
|
||||
if (aNumRouters != NULL)
|
||||
{
|
||||
*aNumRouters = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ComparePartitions(bool, const LeaderDataTlv &, bool, const LeaderDataTlv &) { return 0; }
|
||||
|
||||
void ResolveRoutingLoops(uint16_t, uint16_t) {}
|
||||
@@ -127,7 +114,6 @@ public:
|
||||
static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
|
||||
|
||||
void FillConnectivityTlv(ConnectivityTlv &) {}
|
||||
void FillRouteTlv(RouteTlv &) {}
|
||||
|
||||
otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
|
||||
|
||||
@@ -157,15 +143,11 @@ private:
|
||||
otError HandleNetworkDataUpdateRouter(void) { return OT_ERROR_NONE; }
|
||||
otError HandleDiscoveryRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
|
||||
void HandlePartitionChange(void) {}
|
||||
|
||||
void StopAdvertiseTimer(void) {}
|
||||
otError ProcessRouteTlv(const RouteTlv &aRoute)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aRoute);
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
otError ProcessRouteTlv(const RouteTlv &) { return OT_ERROR_NONE; }
|
||||
|
||||
ChildTable mChildTable;
|
||||
ChildTable mChildTable;
|
||||
RouterTable mRouterTable;
|
||||
};
|
||||
|
||||
} // namespace Mle
|
||||
|
||||
@@ -346,7 +346,8 @@ otError Local::SendServerDataNotification(void)
|
||||
|
||||
// Don't send this Server Data Notification if the device is going to upgrade to Router
|
||||
if ((mle.GetDeviceMode() & Mle::ModeTlv::kModeFFD) != 0 && (mle.IsRouterRoleEnabled()) &&
|
||||
(mle.GetRole() < OT_DEVICE_ROLE_ROUTER) && (mle.GetActiveRouterCount() < mle.GetRouterUpgradeThreshold()))
|
||||
(mle.GetRole() < OT_DEVICE_ROLE_ROUTER) &&
|
||||
(mle.GetRouterTable().GetActiveRouterCount() < mle.GetRouterUpgradeThreshold()))
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_STATE);
|
||||
}
|
||||
|
||||
@@ -338,6 +338,7 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message & aRequest,
|
||||
break;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
case NetworkDiagnosticTlv::kRoute:
|
||||
{
|
||||
RouteTlv tlv;
|
||||
@@ -346,6 +347,7 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message & aRequest,
|
||||
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NetworkDiagnosticTlv::kLeaderData:
|
||||
{
|
||||
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
#define WPP_NAME "router_table.tmh"
|
||||
|
||||
#include "router_table.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/mle_router.hpp"
|
||||
#include "thread/network_data_leader.hpp"
|
||||
#include "thread/thread_netif.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
RouterTable::Iterator::Iterator(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mRouter(NULL)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void RouterTable::Iterator::Reset(void)
|
||||
{
|
||||
RouterTable &routerTable = GetInstance().Get<RouterTable>();
|
||||
|
||||
mRouter = &routerTable.mRouters[0];
|
||||
|
||||
if (mRouter->GetRloc16() == 0xffff)
|
||||
{
|
||||
mRouter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RouterTable::Iterator::Advance(void)
|
||||
{
|
||||
RouterTable &routerTable = GetInstance().Get<RouterTable>();
|
||||
Router * listEnd = &routerTable.mRouters[Mle::kMaxRouters];
|
||||
|
||||
VerifyOrExit(mRouter != NULL);
|
||||
|
||||
mRouter++;
|
||||
|
||||
VerifyOrExit(mRouter < listEnd && mRouter->GetRloc16() != 0xffff, mRouter = NULL);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
RouterTable::RouterTable(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mRouterIdSequenceLastUpdated(0)
|
||||
, mRouterIdSequence(Random::GetUint8())
|
||||
, mActiveRouterCount(0)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void RouterTable::Clear(void)
|
||||
{
|
||||
memset(mAllocatedRouterIds, 0, sizeof(mAllocatedRouterIds));
|
||||
memset(mRouterIdReuseDelay, 0, sizeof(mRouterIdReuseDelay));
|
||||
UpdateAllocation();
|
||||
}
|
||||
|
||||
void RouterTable::ClearNeighbors(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
mRouters[i].SetState(Neighbor::kStateInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
bool RouterTable::IsAllocated(uint8_t aRouterId) const
|
||||
{
|
||||
return (mAllocatedRouterIds[aRouterId / 8] & (1 << (aRouterId % 8))) != 0;
|
||||
}
|
||||
|
||||
void RouterTable::UpdateAllocation(void)
|
||||
{
|
||||
uint8_t indexMap[Mle::kMaxRouterId + 1];
|
||||
|
||||
mActiveRouterCount = 0;
|
||||
|
||||
// build index map
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (IsAllocated(i))
|
||||
{
|
||||
indexMap[i] = mActiveRouterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexMap[i] = Mle::kInvalidRouterId;
|
||||
}
|
||||
}
|
||||
|
||||
// shift entries forward
|
||||
for (int i = Mle::kMaxRouters - 2; i >= 0; i--)
|
||||
{
|
||||
uint8_t routerId = mRouters[i].GetRouterId();
|
||||
uint8_t newIndex;
|
||||
|
||||
if (routerId > Mle::kMaxRouterId || indexMap[routerId] == Mle::kInvalidRouterId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newIndex = indexMap[routerId];
|
||||
|
||||
if (newIndex > i)
|
||||
{
|
||||
mRouters[newIndex] = mRouters[i];
|
||||
}
|
||||
}
|
||||
|
||||
// shift entries backward
|
||||
for (uint8_t i = 1; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
uint8_t routerId = mRouters[i].GetRouterId();
|
||||
uint8_t newIndex;
|
||||
|
||||
if (routerId > Mle::kMaxRouterId || indexMap[routerId] == Mle::kInvalidRouterId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newIndex = indexMap[routerId];
|
||||
|
||||
if (newIndex < i)
|
||||
{
|
||||
mRouters[newIndex] = mRouters[i];
|
||||
}
|
||||
}
|
||||
|
||||
// fix replaced entries
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
uint8_t index = indexMap[i];
|
||||
Router &router = mRouters[index];
|
||||
|
||||
if (index == Mle::kInvalidRouterId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (router.GetRouterId() != i)
|
||||
{
|
||||
memset(&router, 0, sizeof(router));
|
||||
router.SetRloc16(Mle::Mle::GetRloc16(i));
|
||||
router.SetNextHop(Mle::kInvalidRouterId);
|
||||
}
|
||||
}
|
||||
|
||||
// clear unused entries
|
||||
for (uint8_t i = mActiveRouterCount; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
Router &router = mRouters[i];
|
||||
memset(&router, 0, sizeof(router));
|
||||
router.SetRloc16(0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
Router *RouterTable::Allocate(void)
|
||||
{
|
||||
Router *rval = NULL;
|
||||
uint8_t numAllocated = 0;
|
||||
uint8_t numAvailable = 0;
|
||||
uint8_t freeBit;
|
||||
|
||||
// count available router ids
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (IsAllocated(i))
|
||||
{
|
||||
numAllocated++;
|
||||
}
|
||||
else if (mRouterIdReuseDelay[i] == 0)
|
||||
{
|
||||
numAvailable++;
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(numAllocated < Mle::kMaxRouters && numAvailable > 0);
|
||||
|
||||
// choose available router id at random
|
||||
freeBit = Random::GetUint8InRange(0, numAvailable);
|
||||
|
||||
// allocate router
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (IsAllocated(i) || mRouterIdReuseDelay[i] > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (freeBit == 0)
|
||||
{
|
||||
rval = Allocate(i);
|
||||
assert(rval != NULL);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
freeBit--;
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
Router *RouterTable::Allocate(uint8_t aRouterId)
|
||||
{
|
||||
Router *rval = NULL;
|
||||
|
||||
VerifyOrExit(!IsAllocated(aRouterId) && mRouterIdReuseDelay[aRouterId] == 0);
|
||||
|
||||
mAllocatedRouterIds[aRouterId / 8] |= 1 << (aRouterId % 8);
|
||||
UpdateAllocation();
|
||||
|
||||
rval = GetRouter(aRouterId);
|
||||
rval->SetLastHeard(TimerMilli::GetNow());
|
||||
|
||||
mRouterIdSequence++;
|
||||
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
|
||||
GetNetif().GetMle().ResetAdvertiseInterval();
|
||||
|
||||
otLogInfoMle(GetInstance(), "Allocate router id %d", aRouterId);
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
otError RouterTable::Release(uint8_t aRouterId)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
ThreadNetif &netif = GetNetif();
|
||||
uint16_t rloc16 = Mle::Mle::GetRloc16(aRouterId);
|
||||
|
||||
VerifyOrExit(netif.GetMle().GetRole() == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE);
|
||||
VerifyOrExit(IsAllocated(aRouterId), error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
mAllocatedRouterIds[aRouterId / 8] &= ~(1 << (aRouterId % 8));
|
||||
UpdateAllocation();
|
||||
|
||||
mRouterIdReuseDelay[aRouterId] = Mle::kRouterIdReuseDelay;
|
||||
|
||||
for (int i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
Router &router = mRouters[i];
|
||||
|
||||
if (router.GetRloc16() == 0xffff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (router.GetNextHop() == rloc16)
|
||||
{
|
||||
router.SetNextHop(Mle::kInvalidRouterId);
|
||||
router.SetCost(0);
|
||||
}
|
||||
}
|
||||
|
||||
mRouterIdSequence++;
|
||||
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
|
||||
|
||||
netif.GetAddressResolver().Remove(aRouterId);
|
||||
netif.GetNetworkDataLeader().RemoveBorderRouter(rloc16);
|
||||
netif.GetMle().ResetAdvertiseInterval();
|
||||
|
||||
otLogInfoMle(GetInstance(), "Release router id %d", aRouterId);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RouterTable::RemoveNeighbor(Router &aRouter)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
|
||||
aRouter.SetLinkQualityOut(0);
|
||||
aRouter.SetLastHeard(TimerMilli::GetNow());
|
||||
|
||||
for (uint8_t i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
Router &cur = mRouters[i];
|
||||
|
||||
if (cur.GetRloc16() == 0xffff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (cur.GetNextHop() == aRouter.GetRouterId())
|
||||
{
|
||||
cur.SetNextHop(Mle::kInvalidRouterId);
|
||||
cur.SetCost(0);
|
||||
|
||||
if (GetLinkCost(cur) >= Mle::kMaxRouteCost)
|
||||
{
|
||||
netif.GetMle().ResetAdvertiseInterval();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aRouter.GetNextHop() == Mle::kInvalidRouterId)
|
||||
{
|
||||
netif.GetMle().ResetAdvertiseInterval();
|
||||
|
||||
// Clear all EID-to-RLOC entries assossiated with the router.
|
||||
netif.GetAddressResolver().Remove(aRouter.GetRouterId());
|
||||
}
|
||||
}
|
||||
|
||||
Router *RouterTable::GetNeighbor(uint16_t aRloc16)
|
||||
{
|
||||
Router *router = NULL;
|
||||
|
||||
VerifyOrExit(aRloc16 != GetNetif().GetMle().GetRloc16());
|
||||
|
||||
for (int i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetState() == Neighbor::kStateValid && mRouters[i].GetRloc16() == aRloc16)
|
||||
{
|
||||
router = &mRouters[i];
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return router;
|
||||
}
|
||||
|
||||
Router *RouterTable::GetNeighbor(const Mac::ExtAddress &aExtAddress)
|
||||
{
|
||||
Router *router = NULL;
|
||||
|
||||
VerifyOrExit(aExtAddress != GetNetif().GetMac().GetExtAddress());
|
||||
|
||||
for (int i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetState() == Neighbor::kStateValid && mRouters[i].GetExtAddress() == aExtAddress)
|
||||
{
|
||||
router = &mRouters[i];
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return router;
|
||||
}
|
||||
|
||||
Router *RouterTable::GetRouter(uint8_t aRouterId)
|
||||
{
|
||||
Router * rval = NULL;
|
||||
uint16_t rloc16 = Mle::Mle::GetRloc16(aRouterId);
|
||||
|
||||
for (uint8_t i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetRloc16() == rloc16)
|
||||
{
|
||||
rval = &mRouters[i];
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
const Router *RouterTable::GetRouter(uint8_t aRouterId) const
|
||||
{
|
||||
const Router *rval = NULL;
|
||||
uint16_t rloc16 = Mle::Mle::GetRloc16(aRouterId);
|
||||
|
||||
for (uint8_t i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetRloc16() == rloc16)
|
||||
{
|
||||
rval = &mRouters[i];
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
Router *RouterTable::GetRouter(const Mac::ExtAddress &aExtAddress)
|
||||
{
|
||||
Router *router = NULL;
|
||||
|
||||
for (int i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetRloc16() == 0xffff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (mRouters[i].GetExtAddress() == aExtAddress)
|
||||
{
|
||||
router = &mRouters[i];
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return router;
|
||||
}
|
||||
|
||||
otError RouterTable::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Router *router;
|
||||
uint8_t routerId;
|
||||
|
||||
if (aRouterId <= Mle::kMaxRouterId)
|
||||
{
|
||||
routerId = static_cast<uint8_t>(aRouterId);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(Mle::Mle::IsActiveRouter(aRouterId), error = OT_ERROR_INVALID_ARGS);
|
||||
routerId = Mle::Mle::GetRouterId(aRouterId);
|
||||
VerifyOrExit(routerId <= Mle::kMaxRouterId, error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
router = GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
memset(&aRouterInfo, 0, sizeof(aRouterInfo));
|
||||
aRouterInfo.mRouterId = routerId;
|
||||
aRouterInfo.mRloc16 = Mle::Mle::GetRloc16(routerId);
|
||||
aRouterInfo.mExtAddress = router->GetExtAddress();
|
||||
aRouterInfo.mAllocated = true;
|
||||
aRouterInfo.mNextHop = router->GetNextHop();
|
||||
aRouterInfo.mLinkEstablished = router->GetState() == Neighbor::kStateValid;
|
||||
aRouterInfo.mPathCost = router->GetCost();
|
||||
aRouterInfo.mLinkQualityIn = router->GetLinkInfo().GetLinkQuality();
|
||||
aRouterInfo.mLinkQualityOut = router->GetLinkQualityOut();
|
||||
aRouterInfo.mAge = static_cast<uint8_t>(TimerMilli::MsecToSec(TimerMilli::GetNow() - router->GetLastHeard()));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Router *RouterTable::GetLeader(void)
|
||||
{
|
||||
return GetRouter(GetNetif().GetMle().GetLeaderId());
|
||||
}
|
||||
|
||||
uint32_t RouterTable::GetLeaderAge(void) const
|
||||
{
|
||||
return TimerMilli::MsecToSec(TimerMilli::GetNow() - mRouterIdSequenceLastUpdated);
|
||||
}
|
||||
|
||||
uint8_t RouterTable::GetNeighborCount(void) const
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
for (int i = 0; i < Mle::kMaxRouters; i++)
|
||||
{
|
||||
if (mRouters[i].GetState() == Neighbor::kStateValid)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t RouterTable::GetLinkCost(Router &aRouter)
|
||||
{
|
||||
uint8_t rval = Mle::kMaxRouteCost;
|
||||
|
||||
VerifyOrExit(aRouter.GetRloc16() != GetNetif().GetMle().GetRloc16() && aRouter.GetState() == Neighbor::kStateValid);
|
||||
|
||||
rval = aRouter.GetLinkInfo().GetLinkQuality();
|
||||
|
||||
if (rval > aRouter.GetLinkQualityOut())
|
||||
{
|
||||
rval = aRouter.GetLinkQualityOut();
|
||||
}
|
||||
|
||||
rval = Mle::MleRouter::LinkQualityToCost(rval);
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
void RouterTable::ProcessTlv(const Mle::RouteTlv &aTlv)
|
||||
{
|
||||
bool allocationChanged = false;
|
||||
|
||||
mRouterIdSequence = aTlv.GetRouterIdSequence();
|
||||
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
|
||||
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (aTlv.IsRouterIdSet(i) == IsAllocated(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
allocationChanged = true;
|
||||
|
||||
if (aTlv.IsRouterIdSet(i))
|
||||
{
|
||||
mAllocatedRouterIds[i / 8] |= 1 << (i % 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsAllocated(i))
|
||||
{
|
||||
Router *router = GetRouter(i);
|
||||
|
||||
assert(router != NULL);
|
||||
router->SetNextHop(Mle::kInvalidRouterId);
|
||||
RemoveNeighbor(*router);
|
||||
}
|
||||
|
||||
mAllocatedRouterIds[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
}
|
||||
|
||||
if (allocationChanged)
|
||||
{
|
||||
UpdateAllocation();
|
||||
GetNetif().GetMle().ResetAdvertiseInterval();
|
||||
}
|
||||
}
|
||||
|
||||
void RouterTable::ProcessTlv(const ThreadRouterMaskTlv &aTlv)
|
||||
{
|
||||
bool allocationChanged = false;
|
||||
|
||||
mRouterIdSequence = aTlv.GetIdSequence();
|
||||
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
|
||||
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (aTlv.IsAssignedRouterIdSet(i) == IsAllocated(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
allocationChanged = true;
|
||||
|
||||
if (aTlv.IsAssignedRouterIdSet(i))
|
||||
{
|
||||
mAllocatedRouterIds[i / 8] |= 1 << (i % 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
mAllocatedRouterIds[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
}
|
||||
|
||||
if (allocationChanged)
|
||||
{
|
||||
UpdateAllocation();
|
||||
GetNetif().GetMle().ResetAdvertiseInterval();
|
||||
}
|
||||
}
|
||||
|
||||
void RouterTable::ProcessTimerTick(void)
|
||||
{
|
||||
Mle::MleRouter &mle = GetNetif().GetMle();
|
||||
|
||||
if (mle.GetRole() == OT_DEVICE_ROLE_LEADER)
|
||||
{
|
||||
// update router id sequence
|
||||
if (GetLeaderAge() >= Mle::kRouterIdSequencePeriod)
|
||||
{
|
||||
mRouterIdSequence++;
|
||||
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i <= Mle::kMaxRouterId; i++)
|
||||
{
|
||||
if (mRouterIdReuseDelay[i] > 0)
|
||||
{
|
||||
mRouterIdReuseDelay[i]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
#ifndef ROUTER_TABLE_HPP_
|
||||
#define ROUTER_TABLE_HPP_
|
||||
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "mac/mac_frame.hpp"
|
||||
#include "thread/mle_constants.hpp"
|
||||
#include "thread/thread_tlvs.hpp"
|
||||
#include "thread/topology.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
|
||||
class RouterTable : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This class represents an iterator for iterating through entries in the router table.
|
||||
*
|
||||
*/
|
||||
class Iterator : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes an `Iterator` instance to start from beginning of the router table.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
Iterator(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method resets the iterator to start over.
|
||||
*
|
||||
*/
|
||||
void Reset(void);
|
||||
|
||||
/**
|
||||
* This method indicates if the iterator has reached the end of the list.
|
||||
*
|
||||
* @retval TRUE The iterator has reached the end of the list.
|
||||
* @retval FALSE The iterator currently points to a valid entry.
|
||||
*
|
||||
*/
|
||||
bool IsDone(void) const { return (mRouter == NULL); }
|
||||
|
||||
/**
|
||||
* This method advances the iterator.
|
||||
*
|
||||
* The iterator is moved to point to the next entry. If there are no more entries matching the iterator
|
||||
* becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
|
||||
*
|
||||
*/
|
||||
void Advance(void);
|
||||
|
||||
/**
|
||||
* This method gets the entry to which the iterator is currently pointing.
|
||||
*
|
||||
* @returns A pointer to the current entry, or `NULL` if the iterator is done/empty.
|
||||
*
|
||||
*/
|
||||
Router *GetRouter(void) { return mRouter; }
|
||||
|
||||
private:
|
||||
Router *mRouter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
RouterTable(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method clears the router table.
|
||||
*
|
||||
*/
|
||||
void Clear(void);
|
||||
|
||||
/**
|
||||
* This method removes all neighbor links to routers.
|
||||
*
|
||||
*/
|
||||
void ClearNeighbors(void);
|
||||
|
||||
/**
|
||||
* This method allocates a router with a random router id.
|
||||
*
|
||||
* @returns A pointer to the allocated router or NULL if a router ID is not available.
|
||||
*
|
||||
*/
|
||||
Router *Allocate(void);
|
||||
|
||||
/**
|
||||
* This method allocates a router with a specified router id.
|
||||
*
|
||||
* @returns A pointer to the allocated router or NULL if the router id could not be allocated.
|
||||
*
|
||||
*/
|
||||
Router *Allocate(uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* This method releases a router id.
|
||||
*
|
||||
* @param[in] aRouterId The router id.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully released the router id.
|
||||
* @retval OT_ERROR_INVALID_STATE The device is not currently operating as a leader.
|
||||
* @retval OT_ERROR_NOT_FOUND The router id is not currently allocated.
|
||||
*
|
||||
*/
|
||||
otError Release(uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* This method removes a neighboring router link.
|
||||
*
|
||||
* @param[in] aRouter A reference to the router.
|
||||
*
|
||||
*/
|
||||
void RemoveNeighbor(Router &aRouter);
|
||||
|
||||
/**
|
||||
* This method returns the number of active routers in the Thread network.
|
||||
*
|
||||
* @returns The number of active routers in the Thread network.
|
||||
*
|
||||
*/
|
||||
uint8_t GetActiveRouterCount(void) const { return mActiveRouterCount; }
|
||||
|
||||
/**
|
||||
* This method returns the leader in the Thread network.
|
||||
*
|
||||
* @returns A pointer to the Leader in the Thread network.
|
||||
*
|
||||
*/
|
||||
Router *GetLeader(void);
|
||||
|
||||
/**
|
||||
* This method returns the time in seconds since the last Router ID Sequence update.
|
||||
*
|
||||
* @returns The time in seconds since the last Router ID Sequence update.
|
||||
*
|
||||
*/
|
||||
uint32_t GetLeaderAge(void) const;
|
||||
|
||||
/**
|
||||
* This method returns the link cost for a neighboring router.
|
||||
*
|
||||
* @param[in] aRouter A reference to the router.
|
||||
*
|
||||
* @returns The link cost.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLinkCost(Router &aRouter);
|
||||
|
||||
/**
|
||||
* This method returns the neighbor for a given RLOC16.
|
||||
*
|
||||
* @param[in] aRloc16 The RLOC16 value.
|
||||
*
|
||||
* @returns A pointer to the router or NULL if the router could not be found.
|
||||
*
|
||||
*/
|
||||
Router *GetNeighbor(uint16_t aRloc16);
|
||||
|
||||
/**
|
||||
* This method returns the neighbor for a given IEEE Extended Address.
|
||||
*
|
||||
* @param[in] aExtAddress A reference to the IEEE Extended Address.
|
||||
*
|
||||
* @returns A pointer to the router or NULL if the router could not be found.
|
||||
*
|
||||
*/
|
||||
Router *GetNeighbor(const Mac::ExtAddress &aExtAddress);
|
||||
|
||||
/**
|
||||
* This method returns the router for a given router id.
|
||||
*
|
||||
* @parma[in] aRouterId The router id.
|
||||
*
|
||||
* @returns A pointer to the router or NULL if the router could not be found.
|
||||
*
|
||||
*/
|
||||
Router *GetRouter(uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* This method returns the router for a given router id.
|
||||
*
|
||||
* @parma[in] aRouterId The router id.
|
||||
*
|
||||
* @returns A pointer to the router or NULL if the router could not be found.
|
||||
*
|
||||
*/
|
||||
const Router *GetRouter(uint8_t aRouterId) const;
|
||||
|
||||
/**
|
||||
* This method returns the router for a given IEEE Extended Address.
|
||||
*
|
||||
* @param[in] aExtAddress A reference to the IEEE Extended Address.
|
||||
*
|
||||
* @returns A pointer to the router or NULL if the router could not be found.
|
||||
*
|
||||
*/
|
||||
Router *GetRouter(const Mac::ExtAddress &aExtAddress);
|
||||
|
||||
/**
|
||||
* This method retains diagnostic information for a given router.
|
||||
*
|
||||
* @param[in] aRouterId The router ID or RLOC16 for a given router.
|
||||
* @param[out] aRouterInfo The router information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully retrieved the router info for given id.
|
||||
* @retval OT_ERROR_INVALID_ARGS @p aRouterId is not a valid value for a router.
|
||||
* @retval OT_ERROR_NOT_FOUND No router entry with the given id.
|
||||
*
|
||||
*/
|
||||
otError GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo);
|
||||
|
||||
/**
|
||||
* This method returns the Router ID Sequence.
|
||||
*
|
||||
* @returns The Router ID Sequence.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
|
||||
|
||||
/**
|
||||
* This method returns the local time when the Router ID Sequence was last updated.
|
||||
*
|
||||
* @returns The local time when the Router ID Sequence was last updated.
|
||||
*
|
||||
*/
|
||||
uint32_t GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; }
|
||||
|
||||
/**
|
||||
* This method returns the number of neighbor links.
|
||||
*
|
||||
* @returns The number of neighbor links.
|
||||
*
|
||||
*/
|
||||
uint8_t GetNeighborCount(void) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not @p aRouterId is allocated.
|
||||
*
|
||||
* @retval TRUE if @p aRouterId is allocated.
|
||||
* @retval FALSE if @p aRouterId is not allocated.
|
||||
*
|
||||
*/
|
||||
bool IsAllocated(uint8_t aRouterId) const;
|
||||
|
||||
/**
|
||||
* This method updates the router table with a received Route TLV.
|
||||
*
|
||||
* @param[in] aRoute A reference to the Route TLV.
|
||||
*
|
||||
*/
|
||||
void ProcessTlv(const Mle::RouteTlv &aRoute);
|
||||
|
||||
/**
|
||||
* This method updates the router table with a received Router Mask TLV.
|
||||
*
|
||||
* @param[in] aTlv A reference to the Router Mask TLV.
|
||||
*
|
||||
*/
|
||||
void ProcessTlv(const ThreadRouterMaskTlv &Tlv);
|
||||
|
||||
/**
|
||||
* This method updates the router table and must be called with a one second period.
|
||||
*
|
||||
*/
|
||||
void ProcessTimerTick(void);
|
||||
|
||||
private:
|
||||
void UpdateAllocation(void);
|
||||
|
||||
Router mRouters[Mle::kMaxRouters];
|
||||
uint8_t mAllocatedRouterIds[BitVectorBytes(Mle::kMaxRouterId)];
|
||||
uint8_t mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
|
||||
uint32_t mRouterIdSequenceLastUpdated;
|
||||
uint8_t mRouterIdSequence;
|
||||
uint8_t mActiveRouterCount;
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_MTD
|
||||
|
||||
class RouterTable
|
||||
{
|
||||
public:
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
Iterator(Instance &) {}
|
||||
void Reset(void) {}
|
||||
bool IsDone(void) const { return true; }
|
||||
void Advance(void) {}
|
||||
Router *GetRouter(void) { return NULL; }
|
||||
};
|
||||
|
||||
explicit RouterTable(Instance &) {}
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_MTD
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // ROUTER_TABLE_HPP_
|
||||
@@ -254,6 +254,14 @@ public:
|
||||
*/
|
||||
uint16_t GetRloc16(void) const { return mRloc16; }
|
||||
|
||||
/**
|
||||
* This method gets the Router ID value.
|
||||
*
|
||||
* @returns The Router ID value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; }
|
||||
|
||||
/**
|
||||
* This method sets the RLOC16 value.
|
||||
*
|
||||
@@ -877,44 +885,10 @@ public:
|
||||
*/
|
||||
void SetCost(uint8_t aCost) { mCost = aCost; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not this router ID has been allocated.
|
||||
*
|
||||
* @returns TRUE if this router ID has been allocated, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsAllocated(void) const { return mAllocated; }
|
||||
|
||||
/**
|
||||
* This method sets whether or not this router ID has been allocated.
|
||||
*
|
||||
* @param[in] aAllocated TRUE if this router ID has been allocated, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void SetAllocated(bool aAllocated) { mAllocated = aAllocated; }
|
||||
|
||||
/**
|
||||
* This method indicates whether the reclaim delay is in effect for this router ID.
|
||||
*
|
||||
* @returns TRUE if the reclaim delay is in effect, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsReclaimDelay(void) const { return mReclaimDelay; }
|
||||
|
||||
/**
|
||||
* This method sets whether the reclaim delay is in effect for this router ID.
|
||||
*
|
||||
* @param[in] aReclaimDelay TRUE if the reclaim delay is in effect, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void SetReclaimDelay(bool aReclaimDelay) { mReclaimDelay = aReclaimDelay; }
|
||||
|
||||
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
|
||||
bool mAllocated : 1; ///< Indicates whether or not this entry is allocated
|
||||
bool mReclaimDelay : 1; ///< Indicates whether or not this entry is waiting to be reclaimed
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
|
||||
Reference in New Issue
Block a user