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; }
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 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); } }
/** * This static method returns the current time in milliseconds. * * @returns The current time in milliseconds. * */ static uint32_t GetNow(void) { return otPlatAlarmGetNow(); }