Example #1
0
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:
    {}
}
Example #2
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 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);
}
Example #3
0
//*****************************************************************************
//
// 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);
}
Example #4
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);
}
Example #5
0
//*****************************************************************************
//
//! 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);
}
Example #6
0
//*****************************************************************************
//
//! 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);
}
Example #7
0
//*****************************************************************************
//
// 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);
}
Example #8
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();
}