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_InvalidState = 14,
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,
} ThreadError;
+11 -11
View File
@@ -55,7 +55,7 @@ static Tasklet sTransmitDoneTask(&Mac::TransmitDoneTask, NULL);
void Mac::StartCsmaBackoff(void)
{
uint32_t backoffExponent = kMinBE + mCsmaAttempts;
uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts;
uint32_t backoff;
if (backoffExponent > kMaxBE)
@@ -84,6 +84,7 @@ Mac::Mac(ThreadNetif &aThreadNetif):
mRxOnWhenIdle = true;
mCsmaAttempts = 0;
mTransmitAttempts = 0;
mTransmitBeacon = false;
mBeacon.Init();
@@ -499,17 +500,16 @@ void Mac::TransmitDoneTask(void)
mAckTimer.Stop();
if (error != kThreadError_None)
if (error == kThreadError_ChannelAccessFailure &&
mCsmaAttempts < kMaxCSMABackoffs)
{
if (mCsmaAttempts < kMaxCSMABackoffs)
{
mCsmaAttempts++;
}
mCsmaAttempts++;
StartCsmaBackoff();
ExitNow();
}
mCsmaAttempts = 0;
switch (mState)
{
case kStateActiveScan:
@@ -530,7 +530,7 @@ void Mac::TransmitDoneTask(void)
mReceiveTimer.Stop();
}
SentFrame(true);
SentFrame(error == kThreadError_None);
break;
default:
@@ -619,9 +619,9 @@ void Mac::SentFrame(bool aAcked)
{
otDumpDebgMac("NO ACK", mSendFrame.GetHeader(), 16);
if (mCsmaAttempts < kMaxCSMABackoffs)
if (mTransmitAttempts < kMaxFrameAttempts)
{
mCsmaAttempts++;
mTransmitAttempts++;
StartCsmaBackoff();
ExitNow();
}
@@ -634,7 +634,7 @@ void Mac::SentFrame(bool aAcked)
}
}
mCsmaAttempts = 0;
mTransmitAttempts = 0;
sender = mSendHead;
mSendHead = mSendHead->mNext;
+13 -10
View File
@@ -65,19 +65,21 @@ namespace Mac {
*/
enum
{
kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006)
kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006)
kMaxCSMABackoffs = 12, ///< macMaxCSMABackoffs (IEEE 802.15.4-2006)
kUnitBackoffPeriod = 20, ///< Number of symbols (IEEE 802.15.4-2006)
kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006)
kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006)
kMaxCSMABackoffs = 4, ///< macMaxCSMABackoffs (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).
kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds).
kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes).
kAckTimeout = 16, ///< Timeout for waiting on an ACK (milliseconds).
kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds).
kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes).
kScanChannelsAll = 0xffff, ///< All channels.
kScanDurationDefault = 200, ///< Default interval between channels (milliseconds).
kScanChannelsAll = 0xffff, ///< All channels.
kScanDurationDefault = 200, ///< Default interval between channels (milliseconds).
};
/**
@@ -440,6 +442,7 @@ private:
uint8_t mDataSequence;
bool mRxOnWhenIdle;
uint8_t mCsmaAttempts;
uint8_t mTransmitAttempts;
bool mTransmitBeacon;
bool mActiveScanRequest;