Add support to handle 'CHANNEL_ACCESS_FAILURE' and 'NO_ACK' results from the PHY layer. (#67)

This commit is contained in:
Jonathan Hui
2016-05-24 15:09:05 -07:00
parent 161b241e86
commit 9cb7aad7bf
3 changed files with 36 additions and 21 deletions
+12
View File
@@ -62,6 +62,18 @@ typedef enum ThreadError
kThreadError_NotImplemented = 13, kThreadError_NotImplemented = 13,
kThreadError_InvalidState = 14, kThreadError_InvalidState = 14,
kThreadError_NoTasklets = 15, kThreadError_NoTasklets = 15,
/**
* No acknowledgment was received after macMaxFrameRetries (IEEE 802.15.4-2006).
*/
kThreadError_NoAck = 16,
/**
* A transmission could not take place due to activity on the channel, i.e., the CSMA-CA mechanism has failed
* (IEEE 802.15.4-2006).
*/
kThreadError_ChannelAccessFailure = 17,
kThreadError_Error = 255, kThreadError_Error = 255,
} ThreadError; } ThreadError;
+11 -11
View File
@@ -55,7 +55,7 @@ static Tasklet sTransmitDoneTask(&Mac::TransmitDoneTask, NULL);
void Mac::StartCsmaBackoff(void) void Mac::StartCsmaBackoff(void)
{ {
uint32_t backoffExponent = kMinBE + mCsmaAttempts; uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts;
uint32_t backoff; uint32_t backoff;
if (backoffExponent > kMaxBE) if (backoffExponent > kMaxBE)
@@ -84,6 +84,7 @@ Mac::Mac(ThreadNetif &aThreadNetif):
mRxOnWhenIdle = true; mRxOnWhenIdle = true;
mCsmaAttempts = 0; mCsmaAttempts = 0;
mTransmitAttempts = 0;
mTransmitBeacon = false; mTransmitBeacon = false;
mBeacon.Init(); mBeacon.Init();
@@ -499,17 +500,16 @@ void Mac::TransmitDoneTask(void)
mAckTimer.Stop(); mAckTimer.Stop();
if (error != kThreadError_None) if (error == kThreadError_ChannelAccessFailure &&
mCsmaAttempts < kMaxCSMABackoffs)
{ {
if (mCsmaAttempts < kMaxCSMABackoffs) mCsmaAttempts++;
{
mCsmaAttempts++;
}
StartCsmaBackoff(); StartCsmaBackoff();
ExitNow(); ExitNow();
} }
mCsmaAttempts = 0;
switch (mState) switch (mState)
{ {
case kStateActiveScan: case kStateActiveScan:
@@ -530,7 +530,7 @@ void Mac::TransmitDoneTask(void)
mReceiveTimer.Stop(); mReceiveTimer.Stop();
} }
SentFrame(true); SentFrame(error == kThreadError_None);
break; break;
default: default:
@@ -619,9 +619,9 @@ void Mac::SentFrame(bool aAcked)
{ {
otDumpDebgMac("NO ACK", mSendFrame.GetHeader(), 16); otDumpDebgMac("NO ACK", mSendFrame.GetHeader(), 16);
if (mCsmaAttempts < kMaxCSMABackoffs) if (mTransmitAttempts < kMaxFrameAttempts)
{ {
mCsmaAttempts++; mTransmitAttempts++;
StartCsmaBackoff(); StartCsmaBackoff();
ExitNow(); ExitNow();
} }
@@ -634,7 +634,7 @@ void Mac::SentFrame(bool aAcked)
} }
} }
mCsmaAttempts = 0; mTransmitAttempts = 0;
sender = mSendHead; sender = mSendHead;
mSendHead = mSendHead->mNext; mSendHead = mSendHead->mNext;
+13 -10
View File
@@ -65,19 +65,21 @@ namespace Mac {
*/ */
enum enum
{ {
kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006) kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006)
kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006) kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006)
kMaxCSMABackoffs = 12, ///< macMaxCSMABackoffs (IEEE 802.15.4-2006) kMaxCSMABackoffs = 4, ///< macMaxCSMABackoffs (IEEE 802.15.4-2006)
kUnitBackoffPeriod = 20, ///< Number of symbols (IEEE 802.15.4-2006) kMaxFrameRetries = 15, ///< macMaxFrameRetries (IEEE 802.15.4-2006)
kUnitBackoffPeriod = 20, ///< Number of symbols (IEEE 802.15.4-2006)
kMinBackoff = 16, ///< Minimum backoff (milliseconds). kMinBackoff = 16, ///< Minimum backoff (milliseconds).
kMaxFrameAttempts = kMaxFrameRetries + 1, ///< Number of transmission attempts.
kAckTimeout = 16, ///< Timeout for waiting on an ACK (milliseconds). kAckTimeout = 16, ///< Timeout for waiting on an ACK (milliseconds).
kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds). kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds).
kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes).
kScanChannelsAll = 0xffff, ///< All channels. kScanChannelsAll = 0xffff, ///< All channels.
kScanDurationDefault = 200, ///< Default interval between channels (milliseconds). kScanDurationDefault = 200, ///< Default interval between channels (milliseconds).
}; };
/** /**
@@ -440,6 +442,7 @@ private:
uint8_t mDataSequence; uint8_t mDataSequence;
bool mRxOnWhenIdle; bool mRxOnWhenIdle;
uint8_t mCsmaAttempts; uint8_t mCsmaAttempts;
uint8_t mTransmitAttempts;
bool mTransmitBeacon; bool mTransmitBeacon;
bool mActiveScanRequest; bool mActiveScanRequest;