Update Address Solicit. (#314)

* Add Status TLV to Address Solicit message.
* Process Status TLV when receiving Address Solicit message.
This commit is contained in:
Jonathan Hui
2016-08-02 09:12:41 -07:00
committed by GitHub
parent ffe6af9bb6
commit 672fe3047f
7 changed files with 73 additions and 30 deletions
+1 -1
View File
@@ -481,7 +481,7 @@ ThreadError otBecomeChild(otMleAttachFilter aFilter)
ThreadError otBecomeRouter(void)
{
return sThreadNetif->GetMle().BecomeRouter();
return sThreadNetif->GetMle().BecomeRouter(ThreadStatusTlv::kTooFewRouters);
}
ThreadError otBecomeLeader(void)
+2 -2
View File
@@ -167,7 +167,7 @@ ThreadError Mle::Start(void)
}
else if (IsActiveRouter(GetRloc16()))
{
mMleRouter.BecomeRouter();
mMleRouter.BecomeRouter(ThreadStatusTlv::kTooFewRouters);
}
else
{
@@ -1783,7 +1783,7 @@ ThreadError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::Messa
if ((mDeviceMode & ModeTlv::kModeFFD) && (numRouters < mMleRouter.GetRouterUpgradeThreshold()))
{
mMleRouter.BecomeRouter();
mMleRouter.BecomeRouter(ThreadStatusTlv::kTooFewRouters);
}
}
+53 -25
View File
@@ -177,7 +177,7 @@ uint32_t MleRouter::GetLeaderAge(void) const
return Timer::MsecToSec(Timer::GetNow() - mRouterIdSequenceLastUpdated);
}
ThreadError MleRouter::BecomeRouter(void)
ThreadError MleRouter::BecomeRouter(ThreadStatusTlv::Status aStatus)
{
ThreadError error = kThreadError_None;
@@ -205,7 +205,7 @@ ThreadError MleRouter::BecomeRouter(void)
break;
case kDeviceStateChild:
SuccessOrExit(error = SendAddressSolicit());
SuccessOrExit(error = SendAddressSolicit(aStatus));
break;
default:
@@ -1173,6 +1173,21 @@ exit:
return rval;
}
uint8_t MleRouter::GetActiveRouterCount(void) const
{
uint8_t rval = 0;
for (int i = 0; i < kMaxRouterId; i++)
{
if (mRouters[i].mAllocated)
{
rval++;
}
}
return rval;
}
ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
@@ -1269,19 +1284,9 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
ExitNow();
case kDeviceStateChild:
routerCount = 0;
for (int i = 0; i < kMaxRouterId; i++)
if ((mDeviceMode & ModeTlv::kModeFFD) && (GetActiveRouterCount() < mRouterUpgradeThreshold))
{
if (mRouters[i].mAllocated)
{
routerCount++;
}
}
if ((mDeviceMode & ModeTlv::kModeFFD) && (routerCount < mRouterUpgradeThreshold))
{
BecomeRouter();
BecomeRouter(ThreadStatusTlv::kTooFewRouters);
ExitNow();
}
@@ -1829,7 +1834,7 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6::
break;
case kDeviceStateChild:
BecomeRouter();
BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
break;
case kDeviceStateRouter:
@@ -2525,12 +2530,13 @@ ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDes
return kThreadError_Drop;
}
ThreadError MleRouter::SendAddressSolicit(void)
ThreadError MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
{
ThreadError error = kThreadError_None;
Coap::Header header;
ThreadExtMacAddressTlv macAddr64Tlv;
ThreadRloc16Tlv rlocTlv;
ThreadStatusTlv statusTlv;
Ip6::MessageInfo messageInfo;
Message *message;
@@ -2563,6 +2569,10 @@ ThreadError MleRouter::SendAddressSolicit(void)
SuccessOrExit(error = message->Append(&rlocTlv, sizeof(rlocTlv)));
}
statusTlv.Init();
statusTlv.SetStatus(aStatus);
SuccessOrExit(error = message->Append(&statusTlv, sizeof(statusTlv)));
memset(&messageInfo, 0, sizeof(messageInfo));
SuccessOrExit(error = GetLeaderAddress(messageInfo.GetPeerAddr()));
messageInfo.mPeerPort = kCoapUdpPort;
@@ -2730,17 +2740,19 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
ThreadError error = kThreadError_None;
ThreadExtMacAddressTlv macAddr64Tlv;
ThreadRloc16Tlv rlocTlv;
int routerId;
ThreadStatusTlv statusTlv;
int routerId = -1;
VerifyOrExit(aHeader.GetType() == Coap::Header::kTypeConfirmable &&
aHeader.GetCode() == Coap::Header::kCodePost, ;);
VerifyOrExit(aHeader.GetType() == Coap::Header::kTypeConfirmable && aHeader.GetCode() == Coap::Header::kCodePost,
error = kThreadError_Parse);
otLogInfoMle("Received address solicit\n");
SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kExtMacAddress, sizeof(macAddr64Tlv), macAddr64Tlv));
VerifyOrExit(macAddr64Tlv.IsValid(), error = kThreadError_Parse);
routerId = -1;
SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kStatus, sizeof(statusTlv), statusTlv));
VerifyOrExit(statusTlv.IsValid(), error = kThreadError_Parse);
// see if allocation already exists
for (int i = 0; i < kMaxRouterId; i++)
@@ -2748,11 +2760,25 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
if (mRouters[i].mAllocated &&
memcmp(&mRouters[i].mMacAddr, macAddr64Tlv.GetMacAddr(), sizeof(mRouters[i].mMacAddr)) == 0)
{
SendAddressSolicitResponse(aHeader, i, aMessageInfo);
ExitNow();
ExitNow(routerId = i);
}
}
// check the request reason
switch (statusTlv.GetStatus())
{
case ThreadStatusTlv::kTooFewRouters:
VerifyOrExit(GetActiveRouterCount() < mRouterUpgradeThreshold, ;);
break;
case ThreadStatusTlv::kHaveChildIdRequest:
break;
default:
ExitNow(error = kThreadError_Parse);
break;
}
if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv) == kThreadError_None)
{
// specific Router ID requested
@@ -2801,10 +2827,12 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
otLogInfoMle("router address unavailable!\n");
}
SendAddressSolicitResponse(aHeader, routerId, aMessageInfo);
exit:
{}
if (error == kThreadError_None)
{
SendAddressSolicitResponse(aHeader, routerId, aMessageInfo);
}
}
void MleRouter::SendAddressSolicitResponse(const Coap::Header &aRequestHeader, int aRouterId,
+13 -2
View File
@@ -42,6 +42,7 @@
#include <net/udp6.hpp>
#include <thread/mle.hpp>
#include <thread/mle_tlvs.hpp>
#include <thread/thread_tlvs.hpp>
#include <thread/topology.hpp>
namespace Thread {
@@ -99,11 +100,13 @@ public:
/**
* This method generates an Address Solicit request for a Router ID.
*
* @param[in] aStatus The reason for requesting a Router ID.
*
* @retval kThreadError_None Successfully generated an Address Solicit message.
* @retval kThreadError_InvalidState Not currently an End Device.
*
*/
ThreadError BecomeRouter(void);
ThreadError BecomeRouter(ThreadStatusTlv::Status aStatus);
/**
* This method causes the Thread interface to become a Leader and start a new partition.
@@ -114,6 +117,14 @@ public:
*/
ThreadError 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 time in seconds since the last Router ID Sequence update.
*
@@ -414,7 +425,7 @@ private:
ThreadError ProcessRouteTlv(const RouteTlv &aRoute);
ThreadError ResetAdvertiseInterval(void);
ThreadError SendAddressSolicit(void);
ThreadError SendAddressSolicit(ThreadStatusTlv::Status aStatus);
ThreadError SendAddressRelease(void);
void SendAddressSolicitResponse(const Coap::Header &aRequest, int aRouterId, const Ip6::MessageInfo &aMessageInfo);
void SendAddressReleaseResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo);
+2
View File
@@ -324,6 +324,8 @@ public:
{
kSuccess = 0, ///< Success.
kNoAddressAvailable = 1, ///< No address available.
kTooFewRouters = 2, ///< Address Solicit due to too few routers.
kHaveChildIdRequest = 3, ///< Address Solicit due to child ID request.
};
/**
@@ -44,6 +44,7 @@ class Cert_5_2_2_LeaderReject1Hop(unittest.TestCase):
self.nodes[LEADER].set_panid(0xface)
self.nodes[LEADER].set_mode('rsdn')
self.nodes[LEADER].enable_whitelist()
self.nodes[LEADER].set_router_upgrade_threshold(32)
for i in range(2,34):
self.nodes[i] = node.Node(i)
@@ -45,6 +45,7 @@ class Cert_5_2_3_LeaderReject2Hops(unittest.TestCase):
self.nodes[LEADER].set_panid(0xface)
self.nodes[LEADER].set_mode('rsdn')
self.nodes[LEADER].enable_whitelist()
self.nodes[LEADER].set_router_upgrade_threshold(32)
for i in range(2,33):
self.nodes[i] = node.Node(i)