mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 10:49:51 +00:00
Update Address Solicit. (#314)
* Add Status TLV to Address Solicit message. * Process Status TLV when receiving Address Solicit message.
This commit is contained in:
@@ -481,7 +481,7 @@ ThreadError otBecomeChild(otMleAttachFilter aFilter)
|
||||
|
||||
ThreadError otBecomeRouter(void)
|
||||
{
|
||||
return sThreadNetif->GetMle().BecomeRouter();
|
||||
return sThreadNetif->GetMle().BecomeRouter(ThreadStatusTlv::kTooFewRouters);
|
||||
}
|
||||
|
||||
ThreadError otBecomeLeader(void)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user