mirror of
https://github.com/espressif/openthread.git
synced 2026-10-03 14:27:38 +00:00
Add Leader ALOC feature support (#797)
* Add Leader ALOC feature support * Avoid using leader aloc magic number
This commit is contained in:
@@ -313,7 +313,7 @@ ThreadError Commissioner::SendMgmtCommissionerGetRequest(const uint8_t *aTlvs,
|
||||
}
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(messageInfo.GetPeerAddr());
|
||||
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
@@ -395,7 +395,7 @@ ThreadError Commissioner::SendMgmtCommissionerSetRequest(const otCommissioningDa
|
||||
}
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(messageInfo.GetPeerAddr());
|
||||
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
@@ -451,7 +451,7 @@ ThreadError Commissioner::SendPetition(void)
|
||||
SuccessOrExit(error = message->Append(&commissionerId, sizeof(Tlv) + commissionerId.GetLength()));
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
mNetif.GetMle().GetLeaderAloc(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
@@ -510,7 +510,7 @@ ThreadError Commissioner::SendKeepAlive(void)
|
||||
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
mNetif.GetMle().GetLeaderAloc(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
|
||||
@@ -588,6 +588,7 @@ ThreadError MeshForwarder::UpdateIp6Route(Message &aMessage)
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::Header ip6Header;
|
||||
uint16_t rloc16;
|
||||
uint16_t aloc16;
|
||||
Neighbor *neighbor;
|
||||
|
||||
mAddMeshHeader = false;
|
||||
@@ -653,6 +654,21 @@ ThreadError MeshForwarder::UpdateIp6Route(Message &aMessage)
|
||||
VerifyOrExit(mMle.IsRouterIdValid(mMle.GetRouterId(rloc16)), error = kThreadError_Drop);
|
||||
mMeshDest = rloc16;
|
||||
}
|
||||
else if (mMle.IsAnycastLocator(ip6Header.GetDestination()))
|
||||
{
|
||||
// only support Leader ALOC for now
|
||||
aloc16 = HostSwap16(ip6Header.GetDestination().mFields.m16[7]);
|
||||
|
||||
if (aloc16 == Mle::kAloc16Leader)
|
||||
{
|
||||
mMeshDest = mMle.GetRloc16(mMle.GetLeaderId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: support ALOC for DHCPv6 Agent, Service, Commissioner, Neighbor Discovery Agent
|
||||
ExitNow(error = kThreadError_Drop);
|
||||
}
|
||||
}
|
||||
else if ((neighbor = mMle.GetNeighbor(ip6Header.GetDestination())) != NULL)
|
||||
{
|
||||
mMeshDest = neighbor->mValid.mRloc16;
|
||||
|
||||
+59
-1
@@ -229,6 +229,12 @@ ThreadError Mle::Stop(void)
|
||||
SetStateDetached();
|
||||
mNetif.RemoveUnicastAddress(mLinkLocal16);
|
||||
mNetif.RemoveUnicastAddress(mMeshLocal16);
|
||||
|
||||
if (mDeviceState == kDeviceStateLeader)
|
||||
{
|
||||
mNetif.RemoveUnicastAddress(mLeaderAloc);
|
||||
}
|
||||
|
||||
mDeviceState = kDeviceStateDisabled;
|
||||
return kThreadError_None;
|
||||
}
|
||||
@@ -354,6 +360,11 @@ ThreadError Mle::SetStateDetached(void)
|
||||
mNetif.SetStateChangedFlags(OT_NET_ROLE);
|
||||
}
|
||||
|
||||
if (mDeviceState == kDeviceStateLeader)
|
||||
{
|
||||
mNetif.RemoveUnicastAddress(mLeaderAloc);
|
||||
}
|
||||
|
||||
mAddressResolver.Clear();
|
||||
mDeviceState = kDeviceStateDetached;
|
||||
mParentRequestState = kParentIdle;
|
||||
@@ -373,6 +384,11 @@ ThreadError Mle::SetStateChild(uint16_t aRloc16)
|
||||
mNetif.SetStateChangedFlags(OT_NET_ROLE);
|
||||
}
|
||||
|
||||
if (mDeviceState == kDeviceStateLeader)
|
||||
{
|
||||
mNetif.RemoveUnicastAddress(mLeaderAloc);
|
||||
}
|
||||
|
||||
SetRloc16(aRloc16);
|
||||
mDeviceState = kDeviceStateChild;
|
||||
mParentRequestState = kParentIdle;
|
||||
@@ -506,6 +522,13 @@ ThreadError Mle::SetMeshLocalPrefix(const uint8_t *aMeshLocalPrefix)
|
||||
mNetif.AddUnicastAddress(mMeshLocal16);
|
||||
}
|
||||
|
||||
// update Leader ALOC
|
||||
if (mDeviceState == kDeviceStateLeader)
|
||||
{
|
||||
mNetif.RemoveUnicastAddress(mLeaderAloc);
|
||||
AddLeaderAloc();
|
||||
}
|
||||
|
||||
// Changing the prefix also causes the mesh local address to be different.
|
||||
mNetif.SetStateChangedFlags(OT_IP6_ML_ADDR_CHANGED);
|
||||
|
||||
@@ -596,6 +619,36 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Mle::GetLeaderAloc(Ip6::Address &aAddress) const
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = kThreadError_Detached);
|
||||
|
||||
memcpy(&aAddress, &mMeshLocal16.GetAddress(), 8);
|
||||
aAddress.mFields.m16[4] = HostSwap16(0x0000);
|
||||
aAddress.mFields.m16[5] = HostSwap16(0x00ff);
|
||||
aAddress.mFields.m16[6] = HostSwap16(0xfe00);
|
||||
aAddress.mFields.m16[7] = HostSwap16(kAloc16Leader);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Mle::AddLeaderAloc(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(mDeviceState == kDeviceStateLeader, error = kThreadError_InvalidState);
|
||||
|
||||
SuccessOrExit(error = GetLeaderAloc(mLeaderAloc.GetAddress()));
|
||||
|
||||
error = mNetif.AddUnicastAddress(mLeaderAloc);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const LeaderDataTlv &Mle::GetLeaderDataTlv(void)
|
||||
{
|
||||
mLeaderData.SetDataVersion(mNetworkData.GetVersion());
|
||||
@@ -2677,7 +2730,12 @@ uint16_t Mle::GetNextHop(uint16_t aDestination) const
|
||||
|
||||
bool Mle::IsRoutingLocator(const Ip6::Address &aAddress) const
|
||||
{
|
||||
return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0;
|
||||
return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && aAddress.mFields.m8[14] != kAloc16Mask;
|
||||
}
|
||||
|
||||
bool Mle::IsAnycastLocator(const Ip6::Address &aAddress) const
|
||||
{
|
||||
return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && aAddress.mFields.m8[14] == kAloc16Mask;
|
||||
}
|
||||
|
||||
Router *Mle::GetParent()
|
||||
|
||||
@@ -103,6 +103,24 @@ enum DeviceState
|
||||
kDeviceStateLeader = 4, ///< Thread interface participating as a Leader.
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration represents the allocation of the ALOC Space
|
||||
*
|
||||
*/
|
||||
enum AlocAllocation
|
||||
{
|
||||
kAloc16Mask = 0xfc,
|
||||
kAloc16Leader = 0xfc00,
|
||||
kAloc16DHCPv6AgentStart = 0xfc01,
|
||||
kAloc16DHCPv6AgentEnd = 0xfc0f,
|
||||
kAloc16ServiceStart = 0xfc10,
|
||||
kAloc16ServiceEnd = 0xfc2f,
|
||||
kAloc16CommissionerStart = 0xfc30,
|
||||
kAloc16CommissionerEnd = 0xfc37,
|
||||
kAloc16NeighborDiscoveryAgentStart = 0xfc40,
|
||||
kAloc16NeighborDiscoveryAgentEnd = 0xfc4e,
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements MLE Header generation and parsing.
|
||||
*
|
||||
@@ -536,6 +554,15 @@ public:
|
||||
*/
|
||||
bool IsRoutingLocator(const Ip6::Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not an IPv6 address is an ALOC.
|
||||
*
|
||||
* @retval TRUE If @p aAddress is an ALOC.
|
||||
* @retval FALSE If @p aAddress is not an ALOC.
|
||||
*
|
||||
*/
|
||||
bool IsAnycastLocator(const Ip6::Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* This method returns the MLE Timeout value.
|
||||
*
|
||||
@@ -593,6 +620,27 @@ public:
|
||||
*/
|
||||
ThreadError GetLeaderAddress(Ip6::Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* This method retrieves the Leader's ALOC.
|
||||
*
|
||||
* @param[out] aAddress A reference to the Leader's ALOC.
|
||||
*
|
||||
* @retval kThreadError_None Successfully retrieved the Leader's ALOC.
|
||||
* @retval kThreadError_Error The Thread interface is not currently attached to a Thread Partition.
|
||||
*
|
||||
*/
|
||||
ThreadError GetLeaderAloc(Ip6::Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* This method adds Leader's ALOC to its Thread interface.
|
||||
*
|
||||
* @retval kThreadError_None Successfully added the Leader's ALOC.
|
||||
* @retval kThreadError_Busy The Leader's ALOC address was already added.
|
||||
* @retval kThreadError_InvalidState The device's role is not Leader.
|
||||
*
|
||||
*/
|
||||
ThreadError AddLeaderAloc(void);
|
||||
|
||||
/**
|
||||
* This method returns the most recently received Leader Data TLV.
|
||||
*
|
||||
@@ -1176,6 +1224,8 @@ private:
|
||||
uint8_t mPreviousChannel;
|
||||
uint16_t mPreviousPanId;
|
||||
|
||||
Ip6::NetifUnicastAddress mLeaderAloc;
|
||||
|
||||
Ip6::NetifUnicastAddress mLinkLocal16;
|
||||
Ip6::NetifUnicastAddress mLinkLocal64;
|
||||
Ip6::NetifUnicastAddress mMeshLocal64;
|
||||
|
||||
@@ -279,6 +279,8 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
|
||||
SuccessOrExit(error = SetStateLeader(GetRloc16(mRouterId)));
|
||||
|
||||
SuccessOrExit(error = AddLeaderAloc());
|
||||
|
||||
ResetAdvertiseInterval();
|
||||
|
||||
exit:
|
||||
|
||||
Reference in New Issue
Block a user