void Mac::SentFrame(bool aAcked) { Address destination; Neighbor *neighbor; Sender *sender; switch (mState) { case kStateActiveScan: mAckTimer.Start(mScanDuration); break; case kStateTransmitBeacon: ScheduleNextTransmission(); break; case kStateTransmitData: if (mSendFrame.GetAckRequest() && !aAcked) { otDumpDebgMac("NO ACK", mSendFrame.GetHeader(), 16); if (mTransmitAttempts < kMaxFrameAttempts) { mTransmitAttempts++; StartCsmaBackoff(); ExitNow(); } mSendFrame.GetDstAddr(destination); if ((neighbor = mMle.GetNeighbor(destination)) != NULL) { neighbor->mState = Neighbor::kStateInvalid; } } mTransmitAttempts = 0; sender = mSendHead; mSendHead = mSendHead->mNext; if (mSendHead == NULL) { mSendTail = NULL; } mDataSequence++; sender->HandleSentFrame(mSendFrame); ScheduleNextTransmission(); break; default: assert(false); break; } exit: {} }
//***************************************************************************** // //! Indicates that a client has written data directly into the buffer and //! wishes to start transmission. //! //! \param psBuffer is the pointer to the buffer instance into which data has //! been written. //! \param ulLength is the number of bytes of data that the client has written. //! //! This function updates the USB buffer write pointer and starts transmission //! of the data in the buffer assuming the lower layer is ready to receive a //! new packet. The function is provided to aid a client wishing to write //! data directly into the USB buffer rather than using the USBBufferWrite() //! function. This may be necessary to control when the USB buffer starts //! transmission of a large block of data, for example. //! //! A transmit buffer will immediately send a new packet on any call to //! USBBufferWrite() if the underlying layer indicates that a transmission can //! be started. In some cases this is not desirable and a client may wish to //! write more data to the buffer in advance of starting transmission //! to the lower layer. In such cases, USBBufferInfoGet() may be called to //! retrieve the current ring buffer indices and the buffer accessed directly. //! Once the client has written all data it wishes to send (taking care to //! handle the ring buffer wrap), it should call this function to indicate that //! transmission may begin. //! //! \return None. // //***************************************************************************** void USBBufferDataWritten(const tUSBBuffer *psBuffer, unsigned long ulLength) { tUSBBufferVars *psVars; // // Check parameter validity. // ASSERT(psBuffer); // // Get our workspace variables. // psVars = psBuffer->pvWorkspace; // // Advance the ring buffer write pointer to include the newly written // data. // if(ulLength) { USBRingBufAdvanceWrite(&psVars->sRingBuf, ulLength); } // // Try to schedule a new packet transmission. // ScheduleNextTransmission(psBuffer); }
//***************************************************************************** // // Handles USB_EVENT_TX_COMPLETE for a transmit buffer. // // \param psBuffer points to the buffer which is receiving the event. // \param ulSize is the number of bytes that have been transmitted and // acknowledged. // // This function informs us that data written to the lower layer from a // transmit buffer has been successfully transmitted. We use this to update // the buffer read pointer and attempt to schedule the next transmission if // data remains in the buffer. // // \return Returns the number of bytes remaining to be processed. // //***************************************************************************** static unsigned long HandleTxComplete(tUSBBuffer *psBuffer, unsigned long ulSize) { tUSBBufferVars *psVars; // // Get a pointer to our workspace variables. // psVars = psBuffer->pvWorkspace; // // Update the transmit buffer read pointer to remove the data that has // now been transmitted. // USBRingBufAdvanceRead(&psVars->sRingBuf, ulSize); // // Try to schedule the next packet transmission if data remains to be // sent. // ScheduleNextTransmission(psBuffer); // // The return code from this event is ignored. // return(0); }
//***************************************************************************** // //! Indicates that a client has written data directly into the buffer and //! wishes to start transmission. //! //! \param psBuffer is the pointer to the buffer instance into which data has //! been written. //! \param ui32Length is the number of bytes of data that the client has //! written. //! //! This function updates the USB buffer write pointer and starts transmission //! of the data in the buffer assuming the lower layer is ready to receive a //! new packet. The function is provided to aid a client wishing to write //! data directly into the USB buffer rather than using the USBBufferWrite() //! function. This may be necessary to control when the USB buffer starts //! transmission of a large block of data, for example. //! //! A transmit buffer will immediately send a new packet on any call to //! USBBufferWrite() if the underlying layer indicates that a transmission can //! be started. In some cases this is not desirable and a client may wish to //! write more data to the buffer in advance of starting transmission //! to the lower layer. In such cases, USBBufferInfoGet() may be called to //! retrieve the current ring buffer indices and the buffer accessed directly. //! Once the client has written all data it wishes to send (taking care to //! handle the ring buffer wrap), it should call this function to indicate that //! transmission may begin. //! //! \return None. // //***************************************************************************** void USBBufferDataWritten(const tUSBBuffer *psBuffer, uint32_t ui32Length) { tUSBBufferVars *psPrivate; // // Check parameter validity. // ASSERT(psBuffer); // // Create a writable pointer to the private data. // psPrivate = &((tUSBBuffer *)psBuffer)->sPrivateData; // // Advance the ring buffer write pointer to include the newly written // data. // if(ui32Length) { USBRingBufAdvanceWrite(&psPrivate->sRingBuf, ui32Length); } // // Try to schedule a new packet transmission. // ScheduleNextTransmission((tUSBBuffer *)psBuffer); }
//***************************************************************************** // //! Writes a block of data to the transmit buffer and queues it for //! transmission to the USB controller. //! //! \param psBuffer points to the pointer instance into which data is to be //! written. //! \param pucData points to the first byte of data which is to be written. //! \param ulLength is the number of bytes of data to write to the buffer. //! //! This function copies the supplied data into the transmit buffer. The //! transmit buffer data will be packetized according to the constraints //! imposed by the lower layer in use and sent to the USB controller as soon as //! possible. Once a packet is transmitted and acknowledged, a //! \b USB_EVENT_TX_COMPLETE event will be sent to the application callback //! indicating the number of bytes that have been sent from the buffer. //! //! Attempts to send more data than there is space for in the transmit buffer //! will result in fewer bytes than expected being written. The value returned //! by the function indicates the actual number of bytes copied to the buffer. //! //! \return Returns the number of bytes actually written. // //***************************************************************************** unsigned long USBBufferWrite(const tUSBBuffer *psBuffer, const unsigned char *pucData, unsigned long ulLength) { unsigned long ulSpace; tUSBBufferVars *psVars; // // Check parameter validity. // ASSERT(psBuffer && pucData); ASSERT(psBuffer->bTransmitBuffer == true); // // Get our workspace variables. // psVars = psBuffer->pvWorkspace; // // How much space is left in the buffer? // ulSpace = USBRingBufFree(&psVars->sRingBuf); // // How many bytes will we write? // ulLength = (ulLength > ulSpace) ? ulSpace : ulLength; // // Write the data to the buffer. // if(ulLength) { USBRingBufWrite(&psVars->sRingBuf, pucData, ulLength); } // // Try to transmit the next packet to the host. // ScheduleNextTransmission(psBuffer); // // Tell the caller how many bytes we wrote to the buffer. // return(ulLength); }
//***************************************************************************** // //! Writes a block of data to the transmit buffer and queues it for //! transmission to the USB controller. //! //! \param psBuffer points to the pointer instance into which data is to be //! written. //! \param pui8Data points to the first byte of data which is to be written. //! \param ui32Length is the number of bytes of data to write to the buffer. //! //! This function copies the supplied data into the transmit buffer. The //! transmit buffer data will be packetized according to the constraints //! imposed by the lower layer in use and sent to the USB controller as soon as //! possible. Once a packet is transmitted and acknowledged, a //! \b USB_EVENT_TX_COMPLETE event will be sent to the application callback //! indicating the number of bytes that have been sent from the buffer. //! //! Attempts to send more data than there is space for in the transmit buffer //! will result in fewer bytes than expected being written. The value returned //! by the function indicates the actual number of bytes copied to the buffer. //! //! \return Returns the number of bytes actually written. // //***************************************************************************** uint32_t USBBufferWrite(const tUSBBuffer *psBuffer, const uint8_t *pui8Data, uint32_t ui32Length) { uint32_t ui32Space; tUSBBufferVars *psPrivate; // // Check parameter validity. // ASSERT(psBuffer && pui8Data); ASSERT(psBuffer->bTransmitBuffer == true); // // Create a writable pointer to the private data. // psPrivate = &((tUSBBuffer *)psBuffer)->sPrivateData; // // How much space is left in the buffer? // ui32Space = USBRingBufFree(&psPrivate->sRingBuf); // // How many bytes will we write? // ui32Length = (ui32Length > ui32Space) ? ui32Space : ui32Length; // // Write the data to the buffer. // if(ui32Length) { USBRingBufWrite(&psPrivate->sRingBuf, pui8Data, ui32Length); } // // Try to transmit the next packet to the host. // ScheduleNextTransmission((tUSBBuffer *)psBuffer); // // Tell the caller how many bytes we wrote to the buffer. // return(ui32Length); }
//***************************************************************************** // // Handles USB_EVENT_TX_COMPLETE for a transmit buffer. // // \param psBuffer points to the buffer which is receiving the event. // \param ui32Size is the number of bytes that have been transmitted and // acknowledged. // // This function informs us that data written to the lower layer from a // transmit buffer has been successfully transmitted. We use this to update // the buffer read pointer and attempt to schedule the next transmission if // data remains in the buffer. // // \return Returns the number of bytes remaining to be processed. // //***************************************************************************** static uint32_t HandleTxComplete(tUSBBuffer *psBuffer, uint32_t ui32Size) { // // Update the transmit buffer read pointer to remove the data that has // now been transmitted. // USBRingBufAdvanceRead(&psBuffer->sPrivateData.sRingBuf, ui32Size); // // Try to schedule the next packet transmission if data remains to be // sent. // ScheduleNextTransmission(psBuffer); // // The return code from this event is ignored. // return(0); }
void Mac::HandleAckTimer(void) { otPlatRadioIdle(); switch (mState) { case kStateActiveScan: do { mScanChannels >>= 1; mScanChannel++; if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { mActiveScanHandler(mActiveScanContext, NULL); ScheduleNextTransmission(); ExitNow(); } } while ((mScanChannels & 1) == 0); StartCsmaBackoff(); break; case kStateTransmitData: otLogDebgMac("ack timer fired\n"); SentFrame(false); break; default: assert(false); break; } exit: NextOperation(); }