static void handleRx(void) { if (sRxDone) { sRxDone = false; if (otPlatRadioGetPromiscuous(sInstance)) { // Timestamp sReceiveFrame.mInfo.mRxInfo.mMsec = otPlatAlarmMilliGetNow(); sReceiveFrame.mInfo.mRxInfo.mUsec = 0; // Don't support microsecond timer for now. } #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioReceiveDone(sInstance, &sReceiveFrame, OT_ERROR_NONE); } else #endif { // signal MAC layer for each received frame if promiscous is enabled // otherwise only signal MAC layer for non-ACK frame if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH) { otLogDebgPlat(sInstance, "Radio receive done, rssi: %d", sReceiveFrame.mInfo.mRxInfo.mRssi); otPlatRadioReceiveDone(sInstance, &sReceiveFrame, OT_ERROR_NONE); } } } }
void radioProcessFrame(void) { ThreadError error = kThreadError_None; otPanId dstpan; otShortAddress short_address; otExtAddress ext_address; VerifyOrExit(sPromiscuous == false, error = kThreadError_None); switch (sReceiveFrame.mPsdu[1] & IEEE802154_DST_ADDR_MASK) { case IEEE802154_DST_ADDR_NONE: break; case IEEE802154_DST_ADDR_SHORT: dstpan = getDstPan(sReceiveFrame.mPsdu); short_address = getShortAddress(sReceiveFrame.mPsdu); VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && (short_address == IEEE802154_BROADCAST || short_address == sShortAddress), error = kThreadError_Abort); break; case IEEE802154_DST_ADDR_EXT: dstpan = getDstPan(sReceiveFrame.mPsdu); getExtAddress(sReceiveFrame.mPsdu, &ext_address); VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && memcmp(&ext_address, sExtendedAddress, sizeof(ext_address)) == 0, error = kThreadError_Abort); break; default: ExitNow(error = kThreadError_Abort); } sReceiveFrame.mPower = -20; sReceiveFrame.mLqi = kPhyNoLqi; // generate acknowledgment if (isAckRequested(sReceiveFrame.mPsdu)) { radioSendAck(); } exit: otPlatRadioReceiveDone(error == kThreadError_None ? &sReceiveFrame : NULL, error); }
void TestFuzz(uint32_t aSeconds) { // Set the radio capabilities to disable any Mac related timer dependencies g_testPlatRadioCaps = (otRadioCaps)(kRadioCapsAckTimeout | kRadioCapsTransmitRetries); // Set the platform function pointers g_TransmitRadioPacket.mPsdu = g_TransmitPsdu; g_testPlatRadioIsEnabled = testFuzzRadioIsEnabled; g_testPlatRadioEnable = testFuzzRadioEnable; g_testPlatRadioDisable = testFuzzRadioDisable; g_testPlatRadioReceive = testFuzzRadioReceive; g_testPlatRadioTransmit = testFuzzRadioTransmit; g_testPlatRadioGetTransmitBuffer = testFuzztRadioGetTransmitBuffer; // Initialize our timing variables uint32_t tStart = otPlatAlarmGetNow(); uint32_t tEnd = tStart + (aSeconds * 1000); otInstance *aInstance; #ifdef _WIN32 uint32_t seed = (uint32_t)time(NULL); srand(seed); Log("Initialized seed = 0x%X", seed); #endif #ifdef OPENTHREAD_MULTIPLE_INSTANCE size_t otInstanceBufferLength = 0; uint8_t *otInstanceBuffer = NULL; // Call to query the buffer size (void)otInstanceInit(NULL, &otInstanceBufferLength); // Call to allocate the buffer otInstanceBuffer = (uint8_t *)malloc(otInstanceBufferLength); VerifyOrQuit(otInstanceBuffer != NULL, "Failed to allocate otInstance"); memset(otInstanceBuffer, 0, otInstanceBufferLength); // Initialize Openthread with the buffer aInstance = otInstanceInit(otInstanceBuffer, &otInstanceBufferLength); #else aInstance = otInstanceInit(); #endif VerifyOrQuit(aInstance != NULL, "Failed to initialize otInstance"); // Start the Thread network otSetPanId(aInstance, (otPanId)0xFACE); otInterfaceUp(aInstance); otThreadStart(aInstance); uint32_t countRecv = 0; while (otPlatAlarmGetNow() < tEnd) { otProcessQueuedTasklets(aInstance); if (g_testPlatAlarmSet && otPlatAlarmGetNow() >= g_testPlatAlarmNext) { g_testPlatAlarmSet = false; otPlatAlarmFired(aInstance); } if (g_fRadioEnabled) { if (g_fTransmit) { g_fTransmit = false; otPlatRadioTransmitDone(aInstance, &g_TransmitRadioPacket, true, kThreadError_None); #ifdef DBG_FUZZ Log("<== transmit"); #endif } if (g_RecvChannel != 0) { uint8_t fuzzRecvBuff[128]; RadioPacket fuzzPacket; // Initialize the radio packet with a random length memset(&fuzzPacket, 0, sizeof(fuzzPacket)); fuzzPacket.mPsdu = fuzzRecvBuff; fuzzPacket.mChannel = g_RecvChannel; fuzzPacket.mLength = (uint8_t)(otPlatRandomGet() % 127); // Populate the length with random for (uint8_t i = 0; i < fuzzPacket.mLength; i++) { fuzzRecvBuff[i] = (uint8_t)otPlatRandomGet(); } // Clear the global flag g_RecvChannel = 0; // Indicate the receive complete otPlatRadioReceiveDone(aInstance, &fuzzPacket, kThreadError_None); countRecv++; #ifdef DBG_FUZZ Log("<== receive (%llu, %u bytes)", countRecv, fuzzPacket.mLength); #endif // Hack to get a receive poll immediately otSetChannel(aInstance, 11); } } } Log("%u packets received", countRecv); // Clean up the instance otInstanceFinalize(aInstance); #ifdef OPENTHREAD_MULTIPLE_INSTANCE free(otInstanceBuffer); #endif }
void nrf5RadioProcess(otInstance *aInstance) { for (uint32_t i = 0; i < NRF_802154_RX_BUFFERS; i++) { if (sReceivedFrames[i].mPsdu != NULL) { #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioReceiveDone(aInstance, &sReceivedFrames[i], OT_ERROR_NONE); } else #endif { otPlatRadioReceiveDone(aInstance, &sReceivedFrames[i], OT_ERROR_NONE); } uint8_t *bufferAddress = &sReceivedFrames[i].mPsdu[-1]; sReceivedFrames[i].mPsdu = NULL; nrf_802154_buffer_free_raw(bufferAddress); } } if (isPendingEventSet(kPendingEventFrameTransmitted)) { resetPendingEvent(kPendingEventFrameTransmitted); #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE); } else #endif { otRadioFrame *ackPtr = (sAckFrame.mPsdu == NULL) ? NULL : &sAckFrame; otPlatRadioTxDone(aInstance, &sTransmitFrame, ackPtr, OT_ERROR_NONE); } if (sAckFrame.mPsdu != NULL) { nrf_802154_buffer_free_raw(sAckFrame.mPsdu - 1); sAckFrame.mPsdu = NULL; } } if (isPendingEventSet(kPendingEventChannelAccessFailure)) { resetPendingEvent(kPendingEventChannelAccessFailure); #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_CHANNEL_ACCESS_FAILURE); } else #endif { otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_CHANNEL_ACCESS_FAILURE); } } if (isPendingEventSet(kPendingEventInvalidOrNoAck)) { resetPendingEvent(kPendingEventInvalidOrNoAck); #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NO_ACK); } else #endif { otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_NO_ACK); } } if (isPendingEventSet(kPendingEventReceiveFailed)) { resetPendingEvent(kPendingEventReceiveFailed); #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioReceiveDone(aInstance, NULL, sReceiveError); } else #endif { otPlatRadioReceiveDone(aInstance, NULL, sReceiveError); } } if (isPendingEventSet(kPendingEventEnergyDetected)) { resetPendingEvent(kPendingEventEnergyDetected); otPlatRadioEnergyScanDone(aInstance, sEnergyDetected); } if (isPendingEventSet(kPendingEventSleep)) { if (nrf_802154_sleep()) { resetPendingEvent(kPendingEventSleep); } } if (isPendingEventSet(kPendingEventEnergyDetectionStart)) { nrf_802154_channel_set(sEnergyDetectionChannel); if (nrf_802154_energy_detection(sEnergyDetectionTime)) { resetPendingEvent(kPendingEventEnergyDetectionStart); } } }
void cbQorvoRadioReceiveDone(otRadioFrame *aPacket, otError aError) { otPlatRadioReceiveDone(pQorvoInstance, aPacket, aError); }