mirror of
https://github.com/espressif/openthread.git
synced 2026-08-31 22:39:54 +00:00
Clean up access to router state. (#930)
This commit is contained in:
+149
-130
@@ -143,13 +143,17 @@ exit:
|
||||
uint8_t MleRouter::AllocateRouterId(uint8_t aRouterId)
|
||||
{
|
||||
uint8_t rval = kInvalidRouterId;
|
||||
Router *router;
|
||||
|
||||
VerifyOrExit(!mRouters[aRouterId].mAllocated, rval = kInvalidRouterId);
|
||||
router = GetRouter(aRouterId);
|
||||
assert(router != NULL);
|
||||
|
||||
VerifyOrExit(!router->mAllocated, rval = kInvalidRouterId);
|
||||
|
||||
// init router state
|
||||
mRouters[aRouterId].mAllocated = true;
|
||||
mRouters[aRouterId].mLastHeard = Timer::GetNow();
|
||||
memset(&mRouters[aRouterId].mMacAddr, 0, sizeof(mRouters[aRouterId].mMacAddr));
|
||||
router->mAllocated = true;
|
||||
router->mLastHeard = Timer::GetNow();
|
||||
memset(&router->mMacAddr, 0, sizeof(router->mMacAddr));
|
||||
|
||||
// bump sequence number
|
||||
mRouterIdSequence++;
|
||||
@@ -164,11 +168,15 @@ exit:
|
||||
|
||||
ThreadError MleRouter::ReleaseRouterId(uint8_t aRouterId)
|
||||
{
|
||||
Router *router = GetRouter(aRouterId);
|
||||
|
||||
assert(router != NULL);
|
||||
|
||||
otLogInfoMle("delete router id %d", aRouterId);
|
||||
mRouters[aRouterId].mAllocated = false;
|
||||
mRouters[aRouterId].mReclaimDelay = true;
|
||||
mRouters[aRouterId].mState = Neighbor::kStateInvalid;
|
||||
mRouters[aRouterId].mNextHop = kInvalidRouterId;
|
||||
router->mAllocated = false;
|
||||
router->mReclaimDelay = true;
|
||||
router->mState = Neighbor::kStateInvalid;
|
||||
router->mNextHop = kInvalidRouterId;
|
||||
|
||||
for (uint8_t i = 0; i <= kMaxRouterId; i++)
|
||||
{
|
||||
@@ -235,6 +243,7 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t routerId;
|
||||
Router *router;
|
||||
|
||||
VerifyOrExit(mDeviceState != kDeviceStateDisabled, error = kThreadError_InvalidState);
|
||||
VerifyOrExit(mDeviceState != kDeviceStateLeader, error = kThreadError_None);
|
||||
@@ -253,12 +262,13 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
mAddressResolver.Clear();
|
||||
|
||||
routerId = IsRouterIdValid(mPreviousRouterId) ? AllocateRouterId(mPreviousRouterId) : AllocateRouterId();
|
||||
VerifyOrExit(IsRouterIdValid(routerId), error = kThreadError_NoBufs);
|
||||
router = GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
mRouterId = routerId;
|
||||
mPreviousRouterId = mRouterId;
|
||||
|
||||
memcpy(&mRouters[mRouterId].mMacAddr, mMac.GetExtAddress(), sizeof(mRouters[mRouterId].mMacAddr));
|
||||
memcpy(&router->mMacAddr, mMac.GetExtAddress(), sizeof(router->mMacAddr));
|
||||
|
||||
if (mFixedLeaderPartitionId != 0)
|
||||
{
|
||||
@@ -634,7 +644,8 @@ ThreadError MleRouter::HandleLinkRequest(const Message &aMessage, const Ip6::Mes
|
||||
if (IsActiveRouter(rloc16))
|
||||
{
|
||||
// source is a router
|
||||
neighbor = &mRouters[GetRouterId(rloc16)];
|
||||
neighbor = GetRouter(GetRouterId(rloc16));
|
||||
VerifyOrExit(neighbor != NULL, error = kThreadError_Parse);
|
||||
|
||||
if (neighbor->mState != Neighbor::kStateValid)
|
||||
{
|
||||
@@ -791,7 +802,8 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
const ThreadMessageInfo *threadMessageInfo = static_cast<const ThreadMessageInfo *>(aMessageInfo.GetLinkInfo());
|
||||
Neighbor *neighbor = NULL;
|
||||
Router *router;
|
||||
Neighbor *neighbor;
|
||||
Mac::ExtAddress macAddr;
|
||||
VersionTlv version;
|
||||
ResponseTlv response;
|
||||
@@ -825,7 +837,6 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
neighbor->mValid.mRloc16 != sourceAddress.GetRloc16())
|
||||
{
|
||||
RemoveNeighbor(*neighbor);
|
||||
neighbor = NULL;
|
||||
}
|
||||
|
||||
// Link-Layer Frame Counter
|
||||
@@ -844,23 +855,18 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
mleFrameCounter.SetFrameCounter(linkFrameCounter.GetFrameCounter());
|
||||
}
|
||||
|
||||
routerId = GetRouterId(sourceAddress.GetRloc16());
|
||||
VerifyOrExit(IsRouterIdValid(routerId), error = kThreadError_Parse);
|
||||
VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()), error = kThreadError_Parse);
|
||||
|
||||
if (routerId != mRouterId)
|
||||
{
|
||||
neighbor = &mRouters[routerId];
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit((neighbor = FindChild(macAddr)) != NULL, error = kThreadError_Error);
|
||||
}
|
||||
routerId = GetRouterId(sourceAddress.GetRloc16());
|
||||
router = GetRouter(routerId);
|
||||
|
||||
VerifyOrExit(router != NULL, error = kThreadError_Parse);
|
||||
|
||||
// verify response
|
||||
switch (neighbor->mState)
|
||||
switch (router->mState)
|
||||
{
|
||||
case Neighbor::kStateLinkRequest:
|
||||
VerifyOrExit(memcmp(neighbor->mPending.mChallenge, response.GetResponse(), sizeof(neighbor->mPending.mChallenge)) == 0,
|
||||
VerifyOrExit(memcmp(router->mPending.mChallenge, response.GetResponse(), sizeof(router->mPending.mChallenge)) == 0,
|
||||
error = kThreadError_Error);
|
||||
break;
|
||||
|
||||
@@ -912,8 +918,7 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
case kDeviceStateChild:
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkMargin, sizeof(linkMargin), linkMargin));
|
||||
VerifyOrExit(linkMargin.IsValid(), error = kThreadError_Parse);
|
||||
mRouters[routerId].mLinkQualityOut =
|
||||
LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin());
|
||||
router->mLinkQualityOut = LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin());
|
||||
break;
|
||||
|
||||
case kDeviceStateRouter:
|
||||
@@ -926,13 +931,12 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
// Link Margin
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkMargin, sizeof(linkMargin), linkMargin));
|
||||
VerifyOrExit(linkMargin.IsValid(), error = kThreadError_Parse);
|
||||
mRouters[routerId].mLinkQualityOut =
|
||||
LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin());
|
||||
router->mLinkQualityOut = LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin());
|
||||
|
||||
// update routing table
|
||||
if (routerId != mRouterId && !IsRouterIdValid(mRouters[routerId].mNextHop))
|
||||
if (routerId != mRouterId && !IsRouterIdValid(router->mNextHop))
|
||||
{
|
||||
mRouters[routerId].mNextHop = routerId;
|
||||
router->mNextHop = routerId;
|
||||
ResetAdvertiseInterval();
|
||||
}
|
||||
|
||||
@@ -940,17 +944,17 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
}
|
||||
|
||||
// finish link synchronization
|
||||
memcpy(&neighbor->mMacAddr, &macAddr, sizeof(neighbor->mMacAddr));
|
||||
neighbor->mValid.mRloc16 = sourceAddress.GetRloc16();
|
||||
neighbor->mValid.mLinkFrameCounter = linkFrameCounter.GetFrameCounter();
|
||||
neighbor->mValid.mMleFrameCounter = mleFrameCounter.GetFrameCounter();
|
||||
neighbor->mLastHeard = Timer::GetNow();
|
||||
neighbor->mMode = ModeTlv::kModeFFD | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData;
|
||||
neighbor->mLinkInfo.Clear();
|
||||
neighbor->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
neighbor->mLinkFailures = 0;
|
||||
neighbor->mState = Neighbor::kStateValid;
|
||||
neighbor->mKeySequence = aKeySequence;
|
||||
memcpy(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr));
|
||||
router->mValid.mRloc16 = sourceAddress.GetRloc16();
|
||||
router->mValid.mLinkFrameCounter = linkFrameCounter.GetFrameCounter();
|
||||
router->mValid.mMleFrameCounter = mleFrameCounter.GetFrameCounter();
|
||||
router->mLastHeard = Timer::GetNow();
|
||||
router->mMode = ModeTlv::kModeFFD | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData;
|
||||
router->mLinkInfo.Clear();
|
||||
router->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
router->mLinkFailures = 0;
|
||||
router->mState = Neighbor::kStateValid;
|
||||
router->mKeySequence = aKeySequence;
|
||||
|
||||
if (aRequest)
|
||||
{
|
||||
@@ -968,7 +972,7 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
tlvRequest.SetLength(0);
|
||||
}
|
||||
|
||||
SuccessOrExit(error = SendLinkAccept(aMessageInfo, neighbor, tlvRequest, challenge));
|
||||
SuccessOrExit(error = SendLinkAccept(aMessageInfo, router, tlvRequest, challenge));
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -1042,26 +1046,23 @@ uint8_t MleRouter::LqiToCost(uint8_t aLqi)
|
||||
|
||||
uint8_t MleRouter::GetLinkCost(uint8_t aRouterId)
|
||||
{
|
||||
uint8_t rval;
|
||||
uint8_t rval = kMaxRouteCost;
|
||||
Router *router;
|
||||
|
||||
// kInvalidRouterId indicates non-existing next hop, hence return kMaxRouteCost for it.
|
||||
assert(aRouterId <= kInvalidRouterId);
|
||||
router = GetRouter(aRouterId);
|
||||
|
||||
VerifyOrExit(aRouterId != mRouterId &&
|
||||
IsRouterIdValid(aRouterId) &&
|
||||
mRouters[aRouterId].mState == Neighbor::kStateValid,
|
||||
rval = kMaxRouteCost);
|
||||
// NULL aRouterId indicates non-existing next hop, hence return kMaxRouteCost for it.
|
||||
VerifyOrExit(aRouterId != mRouterId && router != NULL && router->mState == Neighbor::kStateValid,);
|
||||
|
||||
rval = mRouters[aRouterId].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
rval = router->mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
|
||||
if (rval > mRouters[aRouterId].mLinkQualityOut)
|
||||
if (rval > router->mLinkQualityOut)
|
||||
{
|
||||
rval = mRouters[aRouterId].mLinkQualityOut;
|
||||
rval = router->mLinkQualityOut;
|
||||
}
|
||||
|
||||
// add for certification testing
|
||||
if (isAssignLinkQuality &&
|
||||
(memcmp(mRouters[aRouterId].mMacAddr.m8, mAddr64.m8, OT_EXT_ADDRESS_SIZE) == 0))
|
||||
if (isAssignLinkQuality && (memcmp(router->mMacAddr.m8, mAddr64.m8, OT_EXT_ADDRESS_SIZE) == 0))
|
||||
{
|
||||
rval = mAssignLinkQuality;
|
||||
}
|
||||
@@ -1266,7 +1267,8 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
|
||||
VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()), ;);
|
||||
routerId = GetRouterId(sourceAddress.GetRloc16());
|
||||
VerifyOrExit(IsRouterIdValid(routerId), error = kThreadError_Parse);
|
||||
router = GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL, error = kThreadError_Parse);
|
||||
|
||||
if ((mDeviceMode & ModeTlv::kModeFFD) &&
|
||||
static_cast<int8_t>(route.GetRouterIdSequence() - mRouterIdSequence) > 0)
|
||||
@@ -1295,8 +1297,6 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
}
|
||||
}
|
||||
|
||||
router = NULL;
|
||||
|
||||
switch (GetDeviceState())
|
||||
{
|
||||
case kDeviceStateDisabled:
|
||||
@@ -1312,17 +1312,17 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
router = &mParent;
|
||||
|
||||
if (memcmp(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr)) == 0)
|
||||
if (memcmp(&mParent.mMacAddr, &macAddr, sizeof(mParent.mMacAddr)) == 0)
|
||||
{
|
||||
if (router->mValid.mRloc16 != sourceAddress.GetRloc16())
|
||||
router = &mParent;
|
||||
|
||||
if (mParent.mValid.mRloc16 != sourceAddress.GetRloc16())
|
||||
{
|
||||
SetStateDetached();
|
||||
ExitNow(error = kThreadError_NoRoute);
|
||||
}
|
||||
|
||||
if ((mDeviceMode & ModeTlv::kModeFFD))
|
||||
if (mDeviceMode & ModeTlv::kModeFFD)
|
||||
{
|
||||
for (uint8_t i = 0, routeCount = 0; i <= kMaxRouterId; i++)
|
||||
{
|
||||
@@ -1350,20 +1350,15 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (router->mState != Neighbor::kStateValid)
|
||||
{
|
||||
router = &mRouters[routerId];
|
||||
|
||||
if (router->mState != Neighbor::kStateValid)
|
||||
{
|
||||
memcpy(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr));
|
||||
router->mLinkInfo.Clear();
|
||||
router->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
router->mLinkFailures = 0;
|
||||
router->mState = Neighbor::kStateLinkRequest;
|
||||
SendLinkRequest(router);
|
||||
ExitNow(error = kThreadError_NoRoute);
|
||||
}
|
||||
memcpy(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr));
|
||||
router->mLinkInfo.Clear();
|
||||
router->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
router->mLinkFailures = 0;
|
||||
router->mState = Neighbor::kStateLinkRequest;
|
||||
SendLinkRequest(router);
|
||||
ExitNow(error = kThreadError_NoRoute);
|
||||
}
|
||||
|
||||
router->mLastHeard = Timer::GetNow();
|
||||
@@ -1394,7 +1389,6 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
// fall through
|
||||
|
||||
case kDeviceStateLeader:
|
||||
router = &mRouters[routerId];
|
||||
|
||||
// router is not in list, reject
|
||||
if (!router->mAllocated)
|
||||
@@ -2813,36 +2807,35 @@ exit:
|
||||
|
||||
uint16_t MleRouter::GetNextHop(uint16_t aDestination) const
|
||||
{
|
||||
uint16_t nextHopRloc16 = Mac::kShortAddrInvalid;
|
||||
uint8_t nextHopRouterId;
|
||||
uint8_t routerId;
|
||||
uint16_t rval = Mac::kShortAddrInvalid;
|
||||
const Router *router;
|
||||
|
||||
if (mDeviceState == kDeviceStateChild)
|
||||
{
|
||||
ExitNow(nextHopRloc16 = Mle::GetNextHop(aDestination));
|
||||
ExitNow(rval = Mle::GetNextHop(aDestination));
|
||||
}
|
||||
|
||||
routerId = GetRouterId(aDestination);
|
||||
router = GetRouter(GetRouterId(aDestination));
|
||||
VerifyOrExit(router != NULL,);
|
||||
|
||||
if (IsRouterIdValid(routerId))
|
||||
{
|
||||
nextHopRouterId = mRouters[routerId].mNextHop;
|
||||
VerifyOrExit(IsRouterIdValid(nextHopRouterId) && mRouters[nextHopRouterId].mState != Neighbor::kStateInvalid, ;);
|
||||
nextHopRloc16 = GetRloc16(mRouters[nextHopRouterId].mNextHop);
|
||||
}
|
||||
router = GetRouter(router->mNextHop);
|
||||
VerifyOrExit(router != NULL && router->mState != Neighbor::kStateInvalid,);
|
||||
|
||||
rval = GetRloc16(router->mNextHop);
|
||||
|
||||
exit:
|
||||
return nextHopRloc16;
|
||||
return rval;
|
||||
}
|
||||
|
||||
uint8_t MleRouter::GetRouteCost(uint16_t aRloc16) const
|
||||
{
|
||||
uint8_t routerId = GetRouterId(aRloc16);
|
||||
uint8_t rval;
|
||||
uint8_t rval = kMaxRouteCost;
|
||||
const Router *router;
|
||||
|
||||
VerifyOrExit(IsRouterIdValid(routerId) && IsRouterIdValid(mRouters[routerId].mNextHop), rval = kMaxRouteCost);
|
||||
router = GetRouter(GetRouterId(aRloc16));
|
||||
VerifyOrExit(router != NULL && GetRouter(router->mNextHop) != NULL,);
|
||||
|
||||
rval = mRouters[routerId].mCost;
|
||||
rval = router->mCost;
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
@@ -2898,6 +2891,30 @@ Router *MleRouter::GetRouters(uint8_t *aNumRouters)
|
||||
return mRouters;
|
||||
}
|
||||
|
||||
Router *MleRouter::GetRouter(uint8_t aRouterId)
|
||||
{
|
||||
Router *rval = NULL;
|
||||
|
||||
VerifyOrExit(aRouterId <= kMaxRouterId,);
|
||||
|
||||
rval = &mRouters[aRouterId];
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
const Router *MleRouter::GetRouter(uint8_t aRouterId) const
|
||||
{
|
||||
const Router *rval = NULL;
|
||||
|
||||
VerifyOrExit(aRouterId <= kMaxRouterId,);
|
||||
|
||||
rval = &mRouters[aRouterId];
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
@@ -2951,6 +2968,7 @@ void MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo)
|
||||
ThreadError MleRouter::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Router *router;
|
||||
uint8_t routerId;
|
||||
|
||||
if (aRouterId > kMaxRouterId && IsActiveRouter(aRouterId))
|
||||
@@ -2962,18 +2980,19 @@ ThreadError MleRouter::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterIn
|
||||
routerId = static_cast<uint8_t>(aRouterId);
|
||||
}
|
||||
|
||||
VerifyOrExit(IsRouterIdValid(routerId), error = kThreadError_InvalidArgs);
|
||||
router = GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL, error = kThreadError_InvalidArgs);
|
||||
|
||||
memcpy(&aRouterInfo.mExtAddress, &mRouters[routerId].mMacAddr, sizeof(aRouterInfo.mExtAddress));
|
||||
aRouterInfo.mAllocated = mRouters[routerId].mAllocated;
|
||||
memcpy(&aRouterInfo.mExtAddress, &router->mMacAddr, sizeof(aRouterInfo.mExtAddress));
|
||||
aRouterInfo.mAllocated = router->mAllocated;
|
||||
aRouterInfo.mRouterId = routerId;
|
||||
aRouterInfo.mRloc16 = GetRloc16(routerId);
|
||||
aRouterInfo.mNextHop = mRouters[routerId].mNextHop;
|
||||
aRouterInfo.mLinkEstablished = mRouters[routerId].mState == Neighbor::kStateValid;
|
||||
aRouterInfo.mPathCost = mRouters[routerId].mCost;
|
||||
aRouterInfo.mLinkQualityIn = mRouters[routerId].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
aRouterInfo.mLinkQualityOut = mRouters[routerId].mLinkQualityOut;
|
||||
aRouterInfo.mAge = static_cast<uint8_t>(Timer::MsecToSec(Timer::GetNow() - mRouters[routerId].mLastHeard));
|
||||
aRouterInfo.mNextHop = router->mNextHop;
|
||||
aRouterInfo.mLinkEstablished = router->mState == Neighbor::kStateValid;
|
||||
aRouterInfo.mPathCost = router->mCost;
|
||||
aRouterInfo.mLinkQualityIn = router->mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
aRouterInfo.mLinkQualityOut = router->mLinkQualityOut;
|
||||
aRouterInfo.mAge = static_cast<uint8_t>(Timer::MsecToSec(Timer::GetNow() - router->mLastHeard));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -3281,6 +3300,7 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
|
||||
ThreadRloc16Tlv rlocTlv;
|
||||
ThreadStatusTlv statusTlv;
|
||||
uint8_t routerId = kInvalidRouterId;
|
||||
Router *router = NULL;
|
||||
|
||||
VerifyOrExit(aHeader.GetType() == kCoapTypeConfirmable && aHeader.GetCode() == kCoapRequestPost,
|
||||
error = kThreadError_Parse);
|
||||
@@ -3323,27 +3343,24 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
|
||||
// specific Router ID requested
|
||||
VerifyOrExit(rlocTlv.IsValid(), error = kThreadError_Parse);
|
||||
routerId = GetRouterId(rlocTlv.GetRloc16());
|
||||
router = GetRouter(routerId);
|
||||
|
||||
if (!IsRouterIdValid(routerId))
|
||||
if (router != NULL)
|
||||
{
|
||||
// requested Router ID is out of range
|
||||
routerId = kInvalidRouterId;
|
||||
}
|
||||
else if (mRouters[routerId].mAllocated &&
|
||||
memcmp(&mRouters[routerId].mMacAddr, macAddr64Tlv.GetMacAddr(),
|
||||
sizeof(mRouters[routerId].mMacAddr)))
|
||||
{
|
||||
// requested Router ID is allocated to another device
|
||||
routerId = kInvalidRouterId;
|
||||
}
|
||||
else if (!mRouters[routerId].mAllocated && mRouters[routerId].mReclaimDelay)
|
||||
{
|
||||
// requested Router ID is deallocated but within ID_REUSE_DELAY period
|
||||
routerId = kInvalidRouterId;
|
||||
}
|
||||
else
|
||||
{
|
||||
routerId = AllocateRouterId(routerId);
|
||||
if (router->mAllocated && memcmp(&router->mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(router->mMacAddr)))
|
||||
{
|
||||
// requested Router ID is allocated to another device
|
||||
routerId = kInvalidRouterId;
|
||||
}
|
||||
else if (!router->mAllocated && router->mReclaimDelay)
|
||||
{
|
||||
// requested Router ID is deallocated but within ID_REUSE_DELAY period
|
||||
routerId = kInvalidRouterId;
|
||||
}
|
||||
else
|
||||
{
|
||||
routerId = AllocateRouterId(routerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3357,9 +3374,11 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
|
||||
otLogInfoMle("router id requested and provided!");
|
||||
}
|
||||
|
||||
if (IsRouterIdValid(routerId))
|
||||
router = GetRouter(routerId);
|
||||
|
||||
if (router != NULL)
|
||||
{
|
||||
memcpy(&mRouters[routerId].mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(mRouters[routerId].mMacAddr));
|
||||
memcpy(&router->mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(router->mMacAddr));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3437,7 +3456,6 @@ void MleRouter::HandleAddressRelease(void *aContext, Coap::Header &aHeader, Mess
|
||||
void MleRouter::HandleAddressRelease(Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
ThreadRloc16Tlv rlocTlv;
|
||||
ThreadExtMacAddressTlv macAddr64Tlv;
|
||||
uint8_t routerId;
|
||||
@@ -3449,15 +3467,16 @@ void MleRouter::HandleAddressRelease(Coap::Header &aHeader, Message &aMessage,
|
||||
otLogInfoMle("Received address release");
|
||||
|
||||
SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv));
|
||||
VerifyOrExit(rlocTlv.IsValid(), ;);
|
||||
VerifyOrExit(rlocTlv.IsValid(),);
|
||||
|
||||
SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kExtMacAddress, sizeof(macAddr64Tlv), macAddr64Tlv));
|
||||
VerifyOrExit(macAddr64Tlv.IsValid(), error = kThreadError_Parse);
|
||||
SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kExtMacAddress, sizeof(macAddr64Tlv), macAddr64Tlv));
|
||||
VerifyOrExit(macAddr64Tlv.IsValid(),);
|
||||
|
||||
VerifyOrExit(IsRouterIdValid(routerId = GetRouterId(rlocTlv.GetRloc16())), error = kThreadError_Parse);
|
||||
routerId = GetRouterId(rlocTlv.GetRloc16());
|
||||
router = GetRouter(routerId);
|
||||
|
||||
router = &mRouters[routerId];
|
||||
VerifyOrExit(memcmp(&router->mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(router->mMacAddr)) == 0, ;);
|
||||
VerifyOrExit(router != NULL &&
|
||||
memcmp(&router->mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(router->mMacAddr)) == 0,);
|
||||
|
||||
ReleaseRouterId(routerId);
|
||||
SendAddressReleaseResponse(aHeader, aMessageInfo);
|
||||
|
||||
@@ -550,6 +550,26 @@ public:
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user