示例#1
0
文件: alarm.c 项目: 0-T-0/openthread
void *alarm_thread(void *arg)
{
    int32_t remaining;
    struct timeval tva;
    struct timeval tvb;
    struct timespec ts;

    while (1)
    {
        pthread_mutex_lock(&s_mutex);

        if (!s_is_running)
        {
            // alarm is not running, wait indefinitely
            pthread_cond_wait(&s_cond, &s_mutex);
            pthread_mutex_unlock(&s_mutex);
        }
        else
        {
            // alarm is running
            remaining = s_alarm - otPlatAlarmGetNow();

            if (remaining > 0)
            {
                // alarm has not passed, wait
                gettimeofday(&tva, NULL);
                tvb.tv_sec = remaining / 1000;
                tvb.tv_usec = (remaining % 1000) * 1000;
                timeradd(&tva, &tvb, &tva);

                ts.tv_sec = tva.tv_sec;
                ts.tv_nsec = tva.tv_usec * 1000;

                pthread_cond_timedwait(&s_cond, &s_mutex, &ts);
                pthread_mutex_unlock(&s_mutex);
            }
            else
            {
                // alarm has passed, signal
                s_is_running = false;
                pthread_mutex_unlock(&s_mutex);
                otPlatAlarmSignalFired();
            }
        }
    }

    return NULL;
}
示例#2
0
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
}
示例#3
0
void Client::HandleRetransmissionTimer(void)
{
    uint32_t now = otPlatAlarmGetNow();
    uint32_t nextDelta = 0xffffffff;
    RequestMetadata requestMetadata;
    Message *message = mPendingRequests.GetHead();
    Message *nextMessage = NULL;
    Ip6::MessageInfo messageInfo;

    while (message != NULL)
    {
        nextMessage = message->GetNext();
        requestMetadata.ReadFrom(*message);

        if (requestMetadata.IsLater(now))
        {
            // Calculate the next delay and choose the lowest.
            if (requestMetadata.mNextTimerShot - now < nextDelta)
            {
                nextDelta = requestMetadata.mNextTimerShot - now;
            }
        }
        else if ((requestMetadata.mConfirmable) &&
                 (requestMetadata.mRetransmissionCount < kMaxRetransmit))
        {
            // Increment retransmission counter and timer.
            requestMetadata.mRetransmissionCount++;
            requestMetadata.mRetransmissionTimeout *= 2;
            requestMetadata.mNextTimerShot = now + requestMetadata.mRetransmissionTimeout;
            requestMetadata.UpdateIn(*message);

            // Check if retransmission time is lower than current lowest.
            if (requestMetadata.mRetransmissionTimeout < nextDelta)
            {
                nextDelta = requestMetadata.mRetransmissionTimeout;
            }

            // Retransmit
            if (!requestMetadata.mAcknowledged)
            {
                memset(&messageInfo, 0, sizeof(messageInfo));
                messageInfo.GetPeerAddr() = requestMetadata.mDestinationAddress;
                messageInfo.mPeerPort = requestMetadata.mDestinationPort;

                SendCopy(*message, messageInfo);
            }
        }
        else
        {
            // No expected response or acknowledgment.
            FinalizeCoapTransaction(*message, requestMetadata, NULL, NULL, kThreadError_ResponseTimeout);
        }

        message = nextMessage;
    }

    if (nextDelta != 0xffffffff)
    {
        mRetransmissionTimer.Start(nextDelta);
    }
}
示例#4
0
 /**
  * This static method returns the current time in milliseconds.
  *
  * @returns The current time in milliseconds.
  *
  */
 static uint32_t GetNow(void) { return otPlatAlarmGetNow(); }