mirror of
https://github.com/espressif/openthread.git
synced 2026-10-02 05:47:40 +00:00
[qos] forward messages based on the priority of the message (#3317)
This commit is contained in:
committed by
Jonathan Hui
parent
f4f92ab3a8
commit
4ed2c8c222
@@ -576,6 +576,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetTimeout(uint8_t aTimeout) { mBuffer.mHead.mInfo.mTimeout = aTimeout; }
|
void SetTimeout(uint8_t aTimeout) { mBuffer.mHead.mInfo.mTimeout = aTimeout; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method decrements the timeout.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void DecrementTimeout(void) { mBuffer.mHead.mInfo.mTimeout--; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the interface ID.
|
* This method returns the interface ID.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -392,11 +392,11 @@
|
|||||||
/**
|
/**
|
||||||
* @def OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT
|
* @def OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT
|
||||||
*
|
*
|
||||||
* The 6LoWPAN fragment reassembly timeout in seconds.
|
* The reassembly timeout between 6LoWPAN fragments in seconds.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT
|
#ifndef OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT
|
||||||
#define OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT 5
|
#define OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1919,4 +1919,15 @@
|
|||||||
#ifndef OPENTHREAD_CONFIG_TIME_SYNC_JUMP_NOTIF_MIN_US
|
#ifndef OPENTHREAD_CONFIG_TIME_SYNC_JUMP_NOTIF_MIN_US
|
||||||
#define OPENTHREAD_CONFIG_TIME_SYNC_JUMP_NOTIF_MIN_US 10000
|
#define OPENTHREAD_CONFIG_TIME_SYNC_JUMP_NOTIF_MIN_US 10000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES
|
||||||
|
*
|
||||||
|
* The number of fragment priority entries.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES
|
||||||
|
#define OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES 8
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
|
#endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace ot {
|
|||||||
MeshForwarder::MeshForwarder(Instance &aInstance)
|
MeshForwarder::MeshForwarder(Instance &aInstance)
|
||||||
: InstanceLocator(aInstance)
|
: InstanceLocator(aInstance)
|
||||||
, mDiscoverTimer(aInstance, &MeshForwarder::HandleDiscoverTimer, this)
|
, mDiscoverTimer(aInstance, &MeshForwarder::HandleDiscoverTimer, this)
|
||||||
, mReassemblyTimer(aInstance, &MeshForwarder::HandleReassemblyTimer, this)
|
, mUpdateTimer(aInstance, &MeshForwarder::HandleUpdateTimer, this)
|
||||||
, mMessageNextOffset(0)
|
, mMessageNextOffset(0)
|
||||||
, mSendMessage(NULL)
|
, mSendMessage(NULL)
|
||||||
, mSendMessageIsARetransmission(false)
|
, mSendMessageIsARetransmission(false)
|
||||||
@@ -91,6 +91,10 @@ MeshForwarder::MeshForwarder(Instance &aInstance)
|
|||||||
mIpCounters.mRxSuccess = 0;
|
mIpCounters.mRxSuccess = 0;
|
||||||
mIpCounters.mTxFailure = 0;
|
mIpCounters.mTxFailure = 0;
|
||||||
mIpCounters.mRxFailure = 0;
|
mIpCounters.mRxFailure = 0;
|
||||||
|
|
||||||
|
#if OPENTHREAD_FTD
|
||||||
|
memset(mFragmentEntries, 0, sizeof(mFragmentEntries));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
otError MeshForwarder::Start(void)
|
otError MeshForwarder::Start(void)
|
||||||
@@ -115,7 +119,7 @@ otError MeshForwarder::Stop(void)
|
|||||||
VerifyOrExit(mEnabled == true);
|
VerifyOrExit(mEnabled == true);
|
||||||
|
|
||||||
mDataPollManager.StopPolling();
|
mDataPollManager.StopPolling();
|
||||||
mReassemblyTimer.Stop();
|
mUpdateTimer.Stop();
|
||||||
|
|
||||||
if (mScanning)
|
if (mScanning)
|
||||||
{
|
{
|
||||||
@@ -134,6 +138,10 @@ otError MeshForwarder::Stop(void)
|
|||||||
message->Free();
|
message->Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_FTD
|
||||||
|
memset(mFragmentEntries, 0, sizeof(mFragmentEntries));
|
||||||
|
#endif
|
||||||
|
|
||||||
mEnabled = false;
|
mEnabled = false;
|
||||||
mSendMessage = NULL;
|
mSendMessage = NULL;
|
||||||
netif.GetMac().SetRxOnWhenIdle(false);
|
netif.GetMac().SetRxOnWhenIdle(false);
|
||||||
@@ -447,6 +455,18 @@ otError MeshForwarder::GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Ma
|
|||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otError MeshForwarder::GetMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength, Lowpan::MeshHeader &aMeshHeader)
|
||||||
|
{
|
||||||
|
otError error;
|
||||||
|
|
||||||
|
VerifyOrExit(aFrameLength >= 1 && reinterpret_cast<const Lowpan::MeshHeader *>(aFrame)->IsMeshHeader(),
|
||||||
|
error = OT_ERROR_NOT_FOUND);
|
||||||
|
SuccessOrExit(error = aMeshHeader.Init(aFrame, aFrameLength));
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
otError MeshForwarder::SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength)
|
otError MeshForwarder::SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength)
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
@@ -462,6 +482,21 @@ exit:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otError MeshForwarder::GetFragmentHeader(const uint8_t * aFrame,
|
||||||
|
uint8_t aFrameLength,
|
||||||
|
Lowpan::FragmentHeader &aFragmentHeader)
|
||||||
|
{
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
|
||||||
|
VerifyOrExit(aFrameLength >= 1 && reinterpret_cast<const Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader(),
|
||||||
|
error = OT_ERROR_NOT_FOUND);
|
||||||
|
|
||||||
|
SuccessOrExit(error = aFragmentHeader.Init(aFrame, aFrameLength));
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
||||||
uint8_t aFrameLength,
|
uint8_t aFrameLength,
|
||||||
const Mac::Address &aMacSource,
|
const Mac::Address &aMacSource,
|
||||||
@@ -478,13 +513,10 @@ otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
|||||||
|
|
||||||
SuccessOrExit(error = SkipMeshHeader(aFrame, aFrameLength));
|
SuccessOrExit(error = SkipMeshHeader(aFrame, aFrameLength));
|
||||||
|
|
||||||
if (aFrameLength >= 1 && reinterpret_cast<const Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
if (GetFragmentHeader(aFrame, aFrameLength, fragmentHeader) == OT_ERROR_NONE)
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = fragmentHeader.Init(aFrame, aFrameLength));
|
|
||||||
|
|
||||||
// only the first fragment header is followed by a LOWPAN_IPHC header
|
// only the first fragment header is followed by a LOWPAN_IPHC header
|
||||||
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
|
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
|
||||||
|
|
||||||
aFrame += fragmentHeader.GetHeaderLength();
|
aFrame += fragmentHeader.GetHeaderLength();
|
||||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||||
}
|
}
|
||||||
@@ -1351,9 +1383,9 @@ void MeshForwarder::HandleFragment(uint8_t * aFrame,
|
|||||||
|
|
||||||
mReassemblyList.Enqueue(*message);
|
mReassemblyList.Enqueue(*message);
|
||||||
|
|
||||||
if (!mReassemblyTimer.IsRunning())
|
if (!mUpdateTimer.IsRunning())
|
||||||
{
|
{
|
||||||
mReassemblyTimer.Start(kStateUpdatePeriod);
|
mUpdateTimer.Start(kStateUpdatePeriod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1391,6 +1423,7 @@ void MeshForwarder::HandleFragment(uint8_t * aFrame,
|
|||||||
message->Write(message->GetOffset(), aFrameLength, aFrame);
|
message->Write(message->GetOffset(), aFrameLength, aFrame);
|
||||||
message->MoveOffset(aFrameLength);
|
message->MoveOffset(aFrameLength);
|
||||||
message->AddRss(aLinkInfo.mRss);
|
message->AddRss(aLinkInfo.mRss);
|
||||||
|
message->SetTimeout(kReassemblyTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -1435,31 +1468,42 @@ void MeshForwarder::ClearReassemblyList(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshForwarder::HandleReassemblyTimer(Timer &aTimer)
|
void MeshForwarder::HandleUpdateTimer(Timer &aTimer)
|
||||||
{
|
{
|
||||||
aTimer.GetOwner<MeshForwarder>().HandleReassemblyTimer();
|
aTimer.GetOwner<MeshForwarder>().HandleUpdateTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshForwarder::HandleReassemblyTimer(void)
|
void MeshForwarder::HandleUpdateTimer(void)
|
||||||
|
{
|
||||||
|
bool shouldRun = false;
|
||||||
|
|
||||||
|
#if OPENTHREAD_FTD
|
||||||
|
shouldRun = UpdateFragmentLifetime();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (UpdateReassemblyList() || shouldRun)
|
||||||
|
{
|
||||||
|
mUpdateTimer.Start(kStateUpdatePeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshForwarder::UpdateReassemblyList(void)
|
||||||
{
|
{
|
||||||
Message *next = NULL;
|
Message *next = NULL;
|
||||||
uint8_t timeout;
|
|
||||||
|
|
||||||
for (Message *message = mReassemblyList.GetHead(); message; message = next)
|
for (Message *message = mReassemblyList.GetHead(); message; message = next)
|
||||||
{
|
{
|
||||||
next = message->GetNext();
|
next = message->GetNext();
|
||||||
timeout = message->GetTimeout();
|
|
||||||
|
|
||||||
if (timeout > 0)
|
if (message->GetTimeout() > 0)
|
||||||
{
|
{
|
||||||
message->SetTimeout(timeout - 1);
|
message->DecrementTimeout();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mReassemblyList.Dequeue(*message);
|
mReassemblyList.Dequeue(*message);
|
||||||
|
|
||||||
LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_REASSEMBLY_TIMEOUT);
|
LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_REASSEMBLY_TIMEOUT);
|
||||||
|
|
||||||
if (message->GetType() == Message::kTypeIp6)
|
if (message->GetType() == Message::kTypeIp6)
|
||||||
{
|
{
|
||||||
mIpCounters.mRxFailure++;
|
mIpCounters.mRxFailure++;
|
||||||
@@ -1469,10 +1513,7 @@ void MeshForwarder::HandleReassemblyTimer(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mReassemblyList.GetHead() != NULL)
|
return mReassemblyList.GetHead() != NULL;
|
||||||
{
|
|
||||||
mReassemblyTimer.Start(kStateUpdatePeriod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshForwarder::HandleLowpanHC(uint8_t * aFrame,
|
void MeshForwarder::HandleLowpanHC(uint8_t * aFrame,
|
||||||
@@ -1547,7 +1588,7 @@ otError MeshForwarder::HandleDatagram(Message & aMessage,
|
|||||||
return netif.GetIp6().HandleDatagram(aMessage, &netif, netif.GetInterfaceId(), &aLinkInfo, false);
|
return netif.GetIp6().HandleDatagram(aMessage, &netif, netif.GetInterfaceId(), &aLinkInfo, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
otError MeshForwarder::GetFramePriority(uint8_t * aFrame,
|
otError MeshForwarder::GetFramePriority(const uint8_t * aFrame,
|
||||||
uint8_t aFrameLength,
|
uint8_t aFrameLength,
|
||||||
const Mac::Address &aMacSource,
|
const Mac::Address &aMacSource,
|
||||||
const Mac::Address &aMacDest,
|
const Mac::Address &aMacDest,
|
||||||
|
|||||||
@@ -64,6 +64,103 @@ enum
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class reprents an IPv6 fragment priority entry
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class FragmentPriorityEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This method returns the fragment datagram tag value.
|
||||||
|
*
|
||||||
|
* @returns The fragment datagram tag value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetDatagramTag(void) const { return mDatagramTag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the fragment datagram tag value.
|
||||||
|
*
|
||||||
|
* @param[in] aDatagramTag The fragment datagram tag value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetDatagramTag(uint16_t aDatagramTag) { mDatagramTag = aDatagramTag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the source Rloc16 of the fragment.
|
||||||
|
*
|
||||||
|
* @returns The source Rloc16 value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetSrcRloc16(void) const { return mSrcRloc16; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the source Rloc16 value of the fragment.
|
||||||
|
*
|
||||||
|
* @param[in] aSrcRloc16 The source Rloc16 value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetSrcRloc16(uint16_t aSrcRloc16) { mSrcRloc16 = aSrcRloc16; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the fragment priority value.
|
||||||
|
*
|
||||||
|
* @returns The fragment priority value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t GetPriority(void) const { return mPriority; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the fragment priotity value.
|
||||||
|
*
|
||||||
|
* @param[in] aPriority The fragment priority value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetPriority(uint8_t aPriority) { mPriority = aPriority; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the fragment priority entry's remaining lifetime.
|
||||||
|
*
|
||||||
|
* @returns The fragment priority entry's remaining lifetime.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t GetLifetime(void) const { return mLifetime; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the remaining lifetime of the fragment priority entry.
|
||||||
|
*
|
||||||
|
* @param[in] aLifetime The remaining lifetime of the fragment priority entry (in seconds).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetLifetime(uint8_t aLifetime)
|
||||||
|
{
|
||||||
|
if (aLifetime > kMaxLifeTime)
|
||||||
|
{
|
||||||
|
aLifetime = kMaxLifeTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLifetime = aLifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method decrements the entry lifetime.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void DecrementLifetime(void) { mLifetime--; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kMaxLifeTime = 5, ///< The maximum lifetime of the fragment entry (in seconds).
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t mSrcRloc16; ///< The source Rloc16 of the datagram.
|
||||||
|
uint16_t mDatagramTag; ///< The datagram tag of the fragment header.
|
||||||
|
uint8_t mPriority : 3; ///< The priority level of the first fragment.
|
||||||
|
uint8_t mLifetime : 3; ///< The lifetime of the entry (in seconds). 0 means the entry is invalid.
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements mesh forwarding within Thread.
|
* This class implements mesh forwarding within Thread.
|
||||||
*
|
*
|
||||||
@@ -238,11 +335,18 @@ public:
|
|||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kStateUpdatePeriod = 1000, ///< State update period in milliseconds.
|
kStateUpdatePeriod = 1000, ///< State update period in milliseconds.
|
||||||
|
kDefaultMsgPriority = Message::kPriorityNormal, ///< Default message priority.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The number of fragment priority entries.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
kNumFragmentPriorityEntries = OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of tx attempts by `MeshForwarder` for an outbound indirect frame (for a sleepy child). The
|
* Maximum number of tx attempts by `MeshForwarder` for an outbound indirect frame (for a sleepy child). The
|
||||||
* `MeshForwader` attempts occur following the reception of a new data request command (a new data poll) from
|
* `MeshForwader` attempts occur following the reception of a new data request command (a new data poll) from
|
||||||
@@ -277,6 +381,7 @@ private:
|
|||||||
const Mac::Address &aMeshSource,
|
const Mac::Address &aMeshSource,
|
||||||
const Mac::Address &aMeshDest);
|
const Mac::Address &aMeshDest);
|
||||||
|
|
||||||
|
otError GetMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength, Lowpan::MeshHeader &aMeshHeader);
|
||||||
otError SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength);
|
otError SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength);
|
||||||
otError DecompressIp6Header(const uint8_t * aFrame,
|
otError DecompressIp6Header(const uint8_t * aFrame,
|
||||||
uint8_t aFrameLength,
|
uint8_t aFrameLength,
|
||||||
@@ -313,18 +418,29 @@ private:
|
|||||||
const Mac::Address & aMacDest,
|
const Mac::Address & aMacDest,
|
||||||
const otThreadLinkInfo &aLinkInfo);
|
const otThreadLinkInfo &aLinkInfo);
|
||||||
void HandleDataRequest(const Mac::Address &aMacSource, const otThreadLinkInfo &aLinkInfo);
|
void HandleDataRequest(const Mac::Address &aMacSource, const otThreadLinkInfo &aLinkInfo);
|
||||||
otError SendPoll(Message &aMessage, Mac::Frame &aFrame);
|
|
||||||
otError SendMesh(Message &aMessage, Mac::Frame &aFrame);
|
static otError GetFragmentHeader(const uint8_t * aFrame,
|
||||||
otError SendFragment(Message &aMessage, Mac::Frame &aFrame);
|
uint8_t aFrameLength,
|
||||||
otError SendEmptyFrame(Mac::Frame &aFrame, bool aAckRequest);
|
Lowpan::FragmentHeader &aFragmentHeader);
|
||||||
otError UpdateIp6Route(Message &aMessage);
|
|
||||||
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header);
|
otError SendPoll(Message &aMessage, Mac::Frame &aFrame);
|
||||||
otError UpdateMeshRoute(Message &aMessage);
|
otError SendMesh(Message &aMessage, Mac::Frame &aFrame);
|
||||||
otError HandleDatagram(Message &aMessage, const otThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource);
|
otError SendFragment(Message &aMessage, Mac::Frame &aFrame);
|
||||||
void ClearReassemblyList(void);
|
otError SendEmptyFrame(Mac::Frame &aFrame, bool aAckRequest);
|
||||||
otError RemoveMessageFromSleepyChild(Message &aMessage, Child &aChild);
|
otError UpdateIp6Route(Message &aMessage);
|
||||||
void RemoveMessage(Message &aMessage);
|
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header);
|
||||||
void HandleDiscoverComplete(void);
|
otError UpdateMeshRoute(Message &aMessage);
|
||||||
|
bool UpdateReassemblyList(void);
|
||||||
|
bool UpdateFragmentLifetime(void);
|
||||||
|
void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
|
||||||
|
uint8_t aFragmentLength,
|
||||||
|
uint16_t aSrcRloc16,
|
||||||
|
uint8_t aPriority);
|
||||||
|
otError HandleDatagram(Message &aMessage, const otThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource);
|
||||||
|
void ClearReassemblyList(void);
|
||||||
|
otError RemoveMessageFromSleepyChild(Message &aMessage, Child &aChild);
|
||||||
|
void RemoveMessage(Message &aMessage);
|
||||||
|
void HandleDiscoverComplete(void);
|
||||||
|
|
||||||
void HandleReceivedFrame(Mac::Frame &aFrame);
|
void HandleReceivedFrame(Mac::Frame &aFrame);
|
||||||
otError HandleFrameRequest(Mac::Frame &aFrame);
|
otError HandleFrameRequest(Mac::Frame &aFrame);
|
||||||
@@ -333,16 +449,25 @@ private:
|
|||||||
|
|
||||||
static void HandleDiscoverTimer(Timer &aTimer);
|
static void HandleDiscoverTimer(Timer &aTimer);
|
||||||
void HandleDiscoverTimer(void);
|
void HandleDiscoverTimer(void);
|
||||||
static void HandleReassemblyTimer(Timer &aTimer);
|
static void HandleUpdateTimer(Timer &aTimer);
|
||||||
void HandleReassemblyTimer(void);
|
void HandleUpdateTimer(void);
|
||||||
static void ScheduleTransmissionTask(Tasklet &aTasklet);
|
static void ScheduleTransmissionTask(Tasklet &aTasklet);
|
||||||
void ScheduleTransmissionTask(void);
|
void ScheduleTransmissionTask(void);
|
||||||
|
|
||||||
otError GetFramePriority(uint8_t * aFrame,
|
otError GetFramePriority(const uint8_t * aFrame,
|
||||||
uint8_t aFrameLength,
|
uint8_t aFrameLength,
|
||||||
const Mac::Address &aMacSource,
|
const Mac::Address &aMacSource,
|
||||||
const Mac::Address &aMacDest,
|
const Mac::Address &aMacDest,
|
||||||
uint8_t & aPriority);
|
uint8_t & aPriority);
|
||||||
|
otError GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, uint16_t aSrcRloc16, uint8_t &aPriority);
|
||||||
|
otError GetForwardFramePriority(const uint8_t * aFrame,
|
||||||
|
uint8_t aFrameLength,
|
||||||
|
const Mac::Address &aMacDest,
|
||||||
|
const Mac::Address &aMacSource,
|
||||||
|
uint8_t & aPriority);
|
||||||
|
|
||||||
|
FragmentPriorityEntry *FindFragmentPriorityEntry(uint16_t aTag, uint16_t aSrcRloc16);
|
||||||
|
FragmentPriorityEntry *GetUnusedFragementPriorityEntry(void);
|
||||||
|
|
||||||
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
|
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
|
||||||
|
|
||||||
@@ -409,7 +534,7 @@ private:
|
|||||||
#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||||
|
|
||||||
TimerMilli mDiscoverTimer;
|
TimerMilli mDiscoverTimer;
|
||||||
TimerMilli mReassemblyTimer;
|
TimerMilli mUpdateTimer;
|
||||||
|
|
||||||
PriorityQueue mSendQueue;
|
PriorityQueue mSendQueue;
|
||||||
MessageQueue mReassemblyList;
|
MessageQueue mReassemblyList;
|
||||||
@@ -441,6 +566,7 @@ private:
|
|||||||
otIpCounters mIpCounters;
|
otIpCounters mIpCounters;
|
||||||
|
|
||||||
#if OPENTHREAD_FTD
|
#if OPENTHREAD_FTD
|
||||||
|
FragmentPriorityEntry mFragmentEntries[kNumFragmentPriorityEntries];
|
||||||
MessageQueue mResolvingQueue;
|
MessageQueue mResolvingQueue;
|
||||||
SourceMatchController mSourceMatchController;
|
SourceMatchController mSourceMatchController;
|
||||||
uint32_t mSendMessageFrameCounter;
|
uint32_t mSendMessageFrameCounter;
|
||||||
|
|||||||
@@ -963,6 +963,8 @@ void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
|||||||
}
|
}
|
||||||
else if (meshHeader.GetHopsLeft() > 0)
|
else if (meshHeader.GetHopsLeft() > 0)
|
||||||
{
|
{
|
||||||
|
uint8_t priority = kDefaultMsgPriority;
|
||||||
|
|
||||||
netif.GetMle().ResolveRoutingLoops(aMacSource.GetShort(), meshDest.GetShort());
|
netif.GetMle().ResolveRoutingLoops(aMacSource.GetShort(), meshDest.GetShort());
|
||||||
|
|
||||||
SuccessOrExit(error = CheckReachability(aFrame, aFrameLength, meshSource, meshDest));
|
SuccessOrExit(error = CheckReachability(aFrame, aFrameLength, meshSource, meshDest));
|
||||||
@@ -970,7 +972,8 @@ void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
|||||||
meshHeader.SetHopsLeft(meshHeader.GetHopsLeft() - 1);
|
meshHeader.SetHopsLeft(meshHeader.GetHopsLeft() - 1);
|
||||||
meshHeader.AppendTo(aFrame);
|
meshHeader.AppendTo(aFrame);
|
||||||
|
|
||||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kType6lowpan, 0)) != NULL,
|
GetForwardFramePriority(aFrame, aFrameLength, meshDest, meshSource, priority);
|
||||||
|
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kType6lowpan, priority)) != NULL,
|
||||||
error = OT_ERROR_NO_BUFS);
|
error = OT_ERROR_NO_BUFS);
|
||||||
SuccessOrExit(error = message->SetLength(aFrameLength));
|
SuccessOrExit(error = message->SetLength(aFrameLength));
|
||||||
message->Write(0, aFrameLength, aFrame);
|
message->Write(0, aFrameLength, aFrame);
|
||||||
@@ -1023,6 +1026,155 @@ exit:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MeshForwarder::UpdateFragmentLifetime(void)
|
||||||
|
{
|
||||||
|
bool shouldRun = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < OT_ARRAY_LENGTH(mFragmentEntries); i++)
|
||||||
|
{
|
||||||
|
if (mFragmentEntries[i].GetLifetime() != 0)
|
||||||
|
{
|
||||||
|
mFragmentEntries[i].DecrementLifetime();
|
||||||
|
|
||||||
|
if (mFragmentEntries[i].GetLifetime() != 0)
|
||||||
|
{
|
||||||
|
shouldRun = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshForwarder::UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
|
||||||
|
uint8_t aFragmentLength,
|
||||||
|
uint16_t aSrcRloc16,
|
||||||
|
uint8_t aPriority)
|
||||||
|
{
|
||||||
|
FragmentPriorityEntry *entry;
|
||||||
|
|
||||||
|
if (aFragmentHeader.GetDatagramOffset() == 0)
|
||||||
|
{
|
||||||
|
VerifyOrExit((entry = GetUnusedFragementPriorityEntry()) != NULL);
|
||||||
|
|
||||||
|
entry->SetDatagramTag(aFragmentHeader.GetDatagramTag());
|
||||||
|
entry->SetSrcRloc16(aSrcRloc16);
|
||||||
|
entry->SetPriority(aPriority);
|
||||||
|
entry->SetLifetime(kReassemblyTimeout);
|
||||||
|
|
||||||
|
if (!mUpdateTimer.IsRunning())
|
||||||
|
{
|
||||||
|
mUpdateTimer.Start(kStateUpdatePeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VerifyOrExit((entry = FindFragmentPriorityEntry(aFragmentHeader.GetDatagramTag(), aSrcRloc16)) != NULL);
|
||||||
|
|
||||||
|
entry->SetLifetime(kReassemblyTimeout);
|
||||||
|
|
||||||
|
if (aFragmentHeader.GetDatagramOffset() + aFragmentLength >= aFragmentHeader.GetDatagramSize())
|
||||||
|
{
|
||||||
|
entry->SetLifetime(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragmentPriorityEntry *MeshForwarder::FindFragmentPriorityEntry(uint16_t aTag, uint16_t aSrcRloc16)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < OT_ARRAY_LENGTH(mFragmentEntries); i++)
|
||||||
|
{
|
||||||
|
if ((mFragmentEntries[i].GetLifetime() != 0) && (mFragmentEntries[i].GetDatagramTag() == aTag) &&
|
||||||
|
(mFragmentEntries[i].GetSrcRloc16() == aSrcRloc16))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (i >= OT_ARRAY_LENGTH(mFragmentEntries)) ? NULL : &mFragmentEntries[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
FragmentPriorityEntry *MeshForwarder::GetUnusedFragementPriorityEntry(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < OT_ARRAY_LENGTH(mFragmentEntries); i++)
|
||||||
|
{
|
||||||
|
if (mFragmentEntries[i].GetLifetime() == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (i >= OT_ARRAY_LENGTH(mFragmentEntries)) ? NULL : &mFragmentEntries[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
otError MeshForwarder::GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
|
||||||
|
uint16_t aSrcRloc16,
|
||||||
|
uint8_t & aPriority)
|
||||||
|
{
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
FragmentPriorityEntry *entry;
|
||||||
|
|
||||||
|
VerifyOrExit((entry = FindFragmentPriorityEntry(aFragmentHeader.GetDatagramTag(), aSrcRloc16)) != NULL,
|
||||||
|
error = OT_ERROR_NOT_FOUND);
|
||||||
|
aPriority = entry->GetPriority();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
otError MeshForwarder::GetForwardFramePriority(const uint8_t * aFrame,
|
||||||
|
uint8_t aFrameLength,
|
||||||
|
const Mac::Address &aMacDest,
|
||||||
|
const Mac::Address &aMacSource,
|
||||||
|
uint8_t & aPriority)
|
||||||
|
{
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
bool isFragment = false;
|
||||||
|
Lowpan::MeshHeader meshHeader;
|
||||||
|
Lowpan::FragmentHeader fragmentHeader;
|
||||||
|
|
||||||
|
SuccessOrExit(error = GetMeshHeader(aFrame, aFrameLength, meshHeader));
|
||||||
|
aFrame += meshHeader.GetHeaderLength();
|
||||||
|
aFrameLength -= meshHeader.GetHeaderLength();
|
||||||
|
|
||||||
|
if (GetFragmentHeader(aFrame, aFrameLength, fragmentHeader) == OT_ERROR_NONE)
|
||||||
|
{
|
||||||
|
isFragment = true;
|
||||||
|
aFrame += fragmentHeader.GetHeaderLength();
|
||||||
|
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||||
|
|
||||||
|
if (fragmentHeader.GetDatagramOffset() > 0)
|
||||||
|
{
|
||||||
|
// Get priority from the pre-buffered info
|
||||||
|
ExitNow(error = GetFragmentPriority(fragmentHeader, meshHeader.GetSource(), aPriority));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get priority from Ipv6 header or UDP destination port directly
|
||||||
|
error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, aPriority);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (error != OT_ERROR_NONE)
|
||||||
|
{
|
||||||
|
otLogNoteMac("Failed to get forwarded frame priority, error:%s, len:%d, dst:%s, src:%s",
|
||||||
|
otThreadErrorToString(error), aFrameLength, aMacDest.ToString().AsCString(),
|
||||||
|
aMacSource.ToString().AsCString());
|
||||||
|
}
|
||||||
|
else if (isFragment)
|
||||||
|
{
|
||||||
|
UpdateFragmentPriority(fragmentHeader, aFrameLength, meshHeader.GetSource(), aPriority);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
#if OPENTHREAD_ENABLE_SERVICE
|
#if OPENTHREAD_ENABLE_SERVICE
|
||||||
otError MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest)
|
otError MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user