示例#1
0
otError LinkRaw::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration, otLinkRawEnergyScanDone aCallback)
{
    otError error = OT_ERROR_INVALID_STATE;

    if (mEnabled)
    {
        mEnergyScanDoneCallback = aCallback;

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN
        // Start listening on the scan channel
        otPlatRadioReceive(&mInstance, aScanChannel);

        // Reset the RSSI value and start scanning
        mEnergyScanRssi = kInvalidRssiValue;
        mTimerReason    = kTimerReasonEnergyScanComplete;
        mTimer.Start(aScanDuration);
        mEnergyScanTask.Post();
#else
        // Do the HW offloaded energy scan
        error = otPlatRadioEnergyScan(&mInstance, aScanChannel, aScanDuration);
#endif
    }

    return error;
}
示例#2
0
void LinkRaw::InvokeTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
{
    otLogDebgPlat(&mInstance, "LinkRaw Transmit Done (err=0x%x)", aError);

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT
    mTimer.Stop();
#endif

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT

    if (aError == OT_ERROR_CHANNEL_ACCESS_FAILURE)
    {
        if (mCsmaAttempts < Mac::kMaxCSMABackoffs)
        {
            mCsmaAttempts++;
            StartCsmaBackoff();
            goto exit;
        }
    }
    else
    {
        mCsmaAttempts = 0;
    }

    if (aError == OT_ERROR_NO_ACK)
    {
        if (mTransmitAttempts < aFrame->mMaxTxAttempts)
        {
            mTransmitAttempts++;
            StartCsmaBackoff();
            goto exit;
        }
    }

#endif

    // Transition back to receive state on previous channel
    otPlatRadioReceive(&mInstance, mReceiveChannel);

    if (mTransmitDoneCallback)
    {
        if (aError == OT_ERROR_NONE)
        {
            otLogInfoPlat(&mInstance, "LinkRaw Invoke Transmit Done");
        }
        else
        {
            otLogWarnPlat(&mInstance, "LinkRaw Invoke Transmit Failed (err=0x%x)", aError);
        }

        mTransmitDoneCallback(&mInstance, aFrame, aAckFrame, aError);
        mTransmitDoneCallback = NULL;
    }

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
exit:
    return;
#endif
}
示例#3
0
void LinkRaw::HandleTimer(void)
{
    TimerReason timerReason = mTimerReason;
    mTimerReason            = kTimerReasonNone;

    switch (timerReason)
    {
#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT

    case kTimerReasonAckTimeout:
    {
        // Transition back to receive state on previous channel
        otPlatRadioReceive(&mInstance, mReceiveChannel);

        // Invoke completion callback for transmit
        InvokeTransmitDone(otPlatRadioGetTransmitBuffer(&mInstance), NULL, OT_ERROR_NO_ACK);
        break;
    }

#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT

    case kTimerReasonRetransmitTimeout:
    {
        otRadioFrame *aFrame = otPlatRadioGetTransmitBuffer(&mInstance);

        // Start the  transmit now
        otError error = DoTransmit(aFrame);

        if (error != OT_ERROR_NONE)
        {
            InvokeTransmitDone(aFrame, NULL, error);
        }

        break;
    }

#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT

#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN

    case kTimerReasonEnergyScanComplete:
    {
        // Invoke completion callback for the energy scan
        InvokeEnergyScanDone(mEnergyScanRssi);
        break;
    }

#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN

    default:
        assert(false);
    }
}
示例#4
0
otError LinkRaw::Receive(uint8_t aChannel, otLinkRawReceiveDone aCallback)
{
    otError error = OT_ERROR_INVALID_STATE;

    if (mEnabled)
    {
        mReceiveChannel      = aChannel;
        mReceiveDoneCallback = aCallback;
        error                = otPlatRadioReceive(&mInstance, aChannel);
    }

    return error;
}
示例#5
0
void Mac::NextOperation(void)
{
    switch (mState)
    {
    case kStateActiveScan:
        mReceiveFrame.SetChannel(mScanChannel);
        otPlatRadioReceive(&mReceiveFrame);
        break;

    default:
        if (mRxOnWhenIdle || mReceiveTimer.IsRunning())
        {
            mReceiveFrame.SetChannel(mChannel);
            otPlatRadioReceive(&mReceiveFrame);
        }
        else
        {
            otPlatRadioSleep();
        }

        break;
    }
}