| /* |
| * Copyright (c) 2016, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "test_platform.h" |
| //#include <mac/mac_frame.hpp> |
| |
| //#define DBG_FUZZ 1 |
| |
| bool g_fRadioEnabled = false; |
| uint8_t g_RecvChannel = 0; |
| uint8_t g_TransmitPsdu[128]; |
| otRadioFrame g_TransmitRadioFrame; |
| bool g_fTransmit = false; |
| |
| bool testFuzzRadioIsEnabled(otInstance *) |
| { |
| return g_fRadioEnabled; |
| } |
| |
| otError testFuzzRadioEnable(otInstance *) |
| { |
| #ifdef DBG_FUZZ |
| Log("Radio enabled"); |
| #endif |
| g_fRadioEnabled = true; |
| return OT_ERROR_NONE; |
| } |
| |
| otError testFuzzRadioDisable(otInstance *) |
| { |
| #ifdef DBG_FUZZ |
| Log("Radio disabled"); |
| #endif |
| g_fRadioEnabled = false; |
| return OT_ERROR_NONE; |
| } |
| |
| otError testFuzzRadioReceive(otInstance *, uint8_t aChannel) |
| { |
| #ifdef DBG_FUZZ |
| Log("==> receive"); |
| #endif |
| g_RecvChannel = aChannel; |
| return OT_ERROR_NONE; |
| } |
| |
| otError testFuzzRadioTransmit(otInstance *) |
| { |
| #ifdef DBG_FUZZ |
| Log("==> transmit"); |
| #endif |
| g_fTransmit = true; |
| return OT_ERROR_NONE; |
| } |
| |
| otRadioFrame *testFuzztRadioGetTransmitBuffer(otInstance *) |
| { |
| return &g_TransmitRadioFrame; |
| } |
| |
| void TestFuzz(uint32_t aSeconds) |
| { |
| // Set the radio capabilities to disable any Mac related timer dependencies |
| g_testPlatRadioCaps = (otRadioCaps)(OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES); |
| |
| // Set the platform function pointers |
| g_TransmitRadioFrame.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 |
| |
| #if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES |
| 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 = otInstanceInitSingle(); |
| #endif |
| |
| VerifyOrQuit(aInstance != NULL, "Failed to initialize otInstance"); |
| |
| // Start the Thread network |
| otLinkSetPanId(aInstance, (otPanId)0xFACE); |
| otIp6SetEnabled(aInstance, true); |
| otThreadSetEnabled(aInstance, true); |
| |
| uint32_t countRecv = 0; |
| |
| while (otPlatAlarmGetNow() < tEnd) |
| { |
| otTaskletsProcess(aInstance); |
| |
| if (g_testPlatAlarmSet && otPlatAlarmGetNow() >= g_testPlatAlarmNext) |
| { |
| g_testPlatAlarmSet = false; |
| otPlatAlarmFired(aInstance); |
| } |
| |
| if (g_fRadioEnabled) |
| { |
| if (g_fTransmit) |
| { |
| g_fTransmit = false; |
| otPlatRadioTxDone(aInstance, &g_TransmitRadioFrame, NULL, OT_ERROR_NONE); |
| #ifdef DBG_FUZZ |
| Log("<== transmit"); |
| #endif |
| } |
| |
| if (g_RecvChannel != 0) |
| { |
| uint8_t fuzzRecvBuff[128]; |
| otRadioFrame 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, OT_ERROR_NONE); |
| |
| countRecv++; |
| #ifdef DBG_FUZZ |
| Log("<== receive (%llu, %u bytes)", countRecv, fuzzPacket.mLength); |
| #endif |
| |
| // Hack to get a receive poll immediately |
| otLinkSetChannel(aInstance, 11); |
| } |
| } |
| } |
| |
| Log("%u packets received", countRecv); |
| |
| // Clean up the instance |
| otInstanceFinalize(aInstance); |
| |
| #if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES |
| free(otInstanceBuffer); |
| #endif |
| } |
| |
| #ifdef ENABLE_TEST_MAIN |
| int main(void) |
| { |
| TestFuzz(30); |
| printf("All tests passed\n"); |
| return 0; |
| } |
| #endif |