diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 3d515fb4c..cf0636bbe 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -937,7 +937,7 @@ exit: if (error != OT_ERROR_NONE) { - TransmitDoneTask(mTxFrame, NULL, OT_ERROR_ABORT); + HandleTransmitDone(mTxFrame, NULL, OT_ERROR_ABORT); } } @@ -947,12 +947,12 @@ extern "C" void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame otLogFuncEntry(); VerifyOrExit(instance->IsInitialized()); - instance->GetThreadNetif().GetMac().TransmitStartedTask(aFrame); + instance->GetThreadNetif().GetMac().HandleTransmitStarted(aFrame); exit: otLogFuncExit(); } -void Mac::TransmitStartedTask(otRadioFrame *aFrame) +void Mac::HandleTransmitStarted(otRadioFrame *aFrame) { Frame *frame = static_cast(aFrame); @@ -980,111 +980,60 @@ extern "C" void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, o else #endif // OPENTHREAD_ENABLE_RAW_LINK_API { - instance->GetThreadNetif().GetMac().TransmitDoneTask(aFrame, aAckFrame, aError); + instance->GetThreadNetif().GetMac().HandleTransmitDone(aFrame, aAckFrame, aError); } exit: otLogFuncExit(); } -void Mac::TransmitDoneTask(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError) +void Mac::HandleTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError) { - Frame *txFrame = static_cast(aFrame); - Address addr; + Frame &sendFrame = *static_cast(aFrame); bool framePending = false; + Address dstAddr; + // Stop the ack timer. mMacTimer.Stop(); - txFrame->GetDstAddr(addr); - - if (aError == OT_ERROR_NONE && txFrame->GetAckRequest() && aAckFrame != NULL) - { - Frame *ackFrame = static_cast(aAckFrame); - Neighbor *neighbor; - - framePending = ackFrame->GetFramePending(); - neighbor = GetNetif().GetMle().GetNeighbor(addr); - - if (neighbor != NULL) - { - neighbor->GetLinkInfo().AddRss(GetNoiseFloor(), ackFrame->GetRssi()); - } - } - - if (aError == OT_ERROR_ABORT) + switch (aError) { + case OT_ERROR_ABORT: mCounters.mTxErrAbort++; + + // fall through + + case OT_ERROR_NONE: + case OT_ERROR_NO_ACK: + case OT_ERROR_CHANNEL_ACCESS_FAILURE: + break; + + default: + assert(false); + ExitNow(); } + // Determine whether a CSMA retry is required. + if (aError == OT_ERROR_CHANNEL_ACCESS_FAILURE) { mCounters.mTxErrCca++; - } - if (!RadioSupportsCsmaBackoff() && - aError == OT_ERROR_CHANNEL_ACCESS_FAILURE && - mCsmaAttempts < kMaxCSMABackoffs) - { - mCsmaAttempts++; - StartCsmaBackoff(); - - ExitNow(); + if (!RadioSupportsCsmaBackoff() && mCsmaAttempts < kMaxCSMABackoffs) + { + mCsmaAttempts++; + StartCsmaBackoff(); + ExitNow(); + } } mCsmaAttempts = 0; - switch (mOperation) - { - case kOperationTransmitData: - - if (framePending && txFrame->IsDataRequestCommand()) - { - mReceiveTimer.Start(kDataPollTimeout); - StartOperation(kOperationWaitingForData); - } - - // fall through - - case kOperationActiveScan: - case kOperationTransmitBeacon: - SentFrame(aError); - break; - - default: -#if OPENTHREAD_ENABLE_RAW_LINK_API - if (GetInstance().GetLinkRaw().IsEnabled()) - { - GetInstance().GetLinkRaw().InvokeTransmitDone(mTxFrame, NULL, OT_ERROR_NO_ACK); - } - else -#endif - { - assert(false); - } - - break; - } - -exit: - return; -} - -void Mac::SentFrame(otError aError) -{ - Frame &sendFrame(*mTxFrame); - Sender *sender; - Address addr; + // Determine whether to re-transmit the frame. mTransmitAttempts++; - switch (aError) - { - case OT_ERROR_NONE: - break; - - case OT_ERROR_CHANNEL_ACCESS_FAILURE: - case OT_ERROR_ABORT: - case OT_ERROR_NO_ACK: + if (aError != OT_ERROR_NONE) { char stringBuffer[Frame::kInfoStringSize]; @@ -1093,25 +1042,36 @@ void Mac::SentFrame(otError aError) sendFrame.ToInfoString(stringBuffer, sizeof(stringBuffer))); otDumpDebgMac(GetInstance(), "TX ERR", sendFrame.GetHeader(), 16); - if (!RadioSupportsRetries() && - mTransmitAttempts < sendFrame.GetMaxTxAttempts()) + if (!RadioSupportsRetries() && mTransmitAttempts < sendFrame.GetMaxTxAttempts()) { - StartCsmaBackoff(); mCounters.mTxRetry++; + StartCsmaBackoff(); ExitNow(); } OT_UNUSED_VARIABLE(stringBuffer); - break; - } - - default: - assert(false); - break; } mTransmitAttempts = 0; - mCsmaAttempts = 0; + + // Process the ack frame for "frame pending". + + sendFrame.GetDstAddr(dstAddr); + + if (aError == OT_ERROR_NONE && sendFrame.GetAckRequest() && aAckFrame != NULL) + { + Frame &ackFrame = *static_cast(aAckFrame); + Neighbor *neighbor = GetNetif().GetMle().GetNeighbor(dstAddr); + + framePending = ackFrame.GetFramePending(); + + if (neighbor != NULL) + { + neighbor->GetLinkInfo().AddRss(GetNoiseFloor(), ackFrame.GetRssi()); + } + } + + // Update MAC counters. mCounters.mTxTotal++; @@ -1120,16 +1080,12 @@ void Mac::SentFrame(otError aError) mCounters.mTxErrBusyChannel++; } - mTxFrame->GetDstAddr(addr); - - if (addr.mShortAddress == kShortAddrBroadcast) + if (dstAddr.mShortAddress == kShortAddrBroadcast) { - // Broadcast frame mCounters.mTxBroadcast++; } else { - // Unicast Frame mCounters.mTxUnicast++; } @@ -1147,6 +1103,8 @@ void Mac::SentFrame(otError aError) mCounters.mTxNoAckRequested++; } + // Determine next action based on current operation. + switch (mOperation) { case kOperationActiveScan: @@ -1160,8 +1118,17 @@ void Mac::SentFrame(otError aError) break; case kOperationTransmitData: - if (mReceiveTimer.IsRunning()) + { + Sender *sender; + + if (sendFrame.IsDataRequestCommand()) { + if (framePending) + { + mReceiveTimer.Start(kDataPollTimeout); + StartOperation(kOperationWaitingForData); + } + mCounters.mTxDataPoll++; } else @@ -1186,9 +1153,9 @@ void Mac::SentFrame(otError aError) otDumpDebgMac(GetInstance(), "TX", sendFrame.GetHeader(), sendFrame.GetLength()); sender->HandleSentFrame(sendFrame, aError); - FinishOperation(); break; + } default: assert(false); @@ -1319,7 +1286,7 @@ void Mac::HandleMacTimer(void) case kOperationTransmitData: otLogDebgMac(GetInstance(), "Ack timer fired"); - SentFrame(OT_ERROR_NO_ACK); + HandleTransmitDone(mTxFrame, NULL, OT_ERROR_NO_ACK); break; default: @@ -1527,14 +1494,14 @@ extern "C" void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFra else #endif // OPENTHREAD_ENABLE_RAW_LINK_API { - instance->GetThreadNetif().GetMac().ReceiveDoneTask(static_cast(aFrame), aError); + instance->GetThreadNetif().GetMac().HandleReceivedFrame(static_cast(aFrame), aError); } exit: otLogFuncExit(); } -void Mac::ReceiveDoneTask(Frame *aFrame, otError aError) +void Mac::HandleReceivedFrame(Frame *aFrame, otError aError) { Address srcaddr; Address dstaddr; diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 9f31f161a..56bb18a2c 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -164,7 +164,8 @@ class Sender: public OwnerLocator public: /** - * This function pointer is called when the MAC is about to transmit the frame. + * This function pointer is called when the MAC is about to transmit the frame asking MAC sender client to provide + * the frame. * * @param[in] aSender A reference to the MAC sender client object. * @param[in] aFrame A reference to the MAC frame buffer. @@ -466,34 +467,34 @@ public: #endif // OPENTHREAD_ENABLE_MAC_FILTER /** - * This method is called to handle receive events. + * This method is called to handle a received frame. * - * @param[in] aFrame A pointer to the received frame, or NULL if the receive operation aborted. - * @param[in] aError OT_ERROR_NONE when successfully received a frame, OT_ERROR_ABORT when reception - * was aborted and a frame was not received. + * @param[in] aFrame A pointer to the received frame, or NULL if the receive operation was aborted. + * @param[in] aError OT_ERROR_NONE when successfully received a frame, + * OT_ERROR_ABORT when reception was aborted and a frame was not received. * */ - void ReceiveDoneTask(Frame *aFrame, otError aError); + void HandleReceivedFrame(Frame *aFrame, otError aError); /** * This method is called to handle transmission start events. * * @param[in] aFrame A pointer to the frame that is transmitted. */ - void TransmitStartedTask(otRadioFrame *aFrame); + void HandleTransmitStarted(otRadioFrame *aFrame); /** * This method is called to handle transmit events. * * @param[in] aFrame A pointer to the frame that was transmitted. * @param[in] aAckFrame A pointer to the ACK frame, NULL if no ACK was received. - * @param[in] aError OT_ERROR_NONE when the frame was transmitted, OT_ERROR_NO_ACK when the frame was - * transmitted but no ACK was received, OT_ERROR_CHANNEL_ACCESS_FAILURE when the - * transmission could not take place due to activity on the channel, OT_ERROR_ABORT when - * transmission was aborted for other reasons. + * @param[in] aError OT_ERROR_NONE when the frame was transmitted, + * OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received, + * OT_ERROR_CHANNEL_ACCESS_FAILURE when the tx failed due to activity on the channel, + * OT_ERROR_ABORT when transmission was aborted for other reasons. * */ - void TransmitDoneTask(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError); + void HandleTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError); /** * This method returns if an active scan is in progress. @@ -627,7 +628,6 @@ private: void UpdateIdleMode(void); void StartOperation(Operation aOperation); void FinishOperation(void); - void SentFrame(otError aError); void SendBeaconRequest(Frame &aFrame); void SendBeacon(Frame &aFrame); void StartBackoff(void);