diff --git a/src/posix/platform/hdlc_interface.cpp b/src/posix/platform/hdlc_interface.cpp index 64183dd1d..96ae4cfe6 100644 --- a/src/posix/platform/hdlc_interface.cpp +++ b/src/posix/platform/hdlc_interface.cpp @@ -250,13 +250,12 @@ exit: otError HdlcInterface::WaitForFrame(const struct timeval &aTimeout) { - otError error = OT_ERROR_NONE; - struct timeval timeout = aTimeout; - + otError error = OT_ERROR_NONE; #if OPENTHREAD_POSIX_VIRTUAL_TIME struct Event event; + uint64_t delay = static_cast(aTimeout.tv_sec) * US_PER_S + static_cast(aTimeout.tv_usec); - virtualTimeSendSleepEvent(&timeout); + virtualTimeSendSleepEvent(&aTimeout); virtualTimeReceiveEvent(&event); switch (event.mEvent) @@ -266,7 +265,7 @@ otError HdlcInterface::WaitForFrame(const struct timeval &aTimeout) break; case OT_SIM_EVENT_ALARM_FIRED: - ExitNow(error = OT_ERROR_RESPONSE_TIMEOUT); + VerifyOrExit(event.mDelay <= delay, error = OT_ERROR_RESPONSE_TIMEOUT); break; default: @@ -274,6 +273,8 @@ otError HdlcInterface::WaitForFrame(const struct timeval &aTimeout) break; } #else // OPENTHREAD_POSIX_VIRTUAL_TIME + struct timeval timeout = aTimeout; + fd_set read_fds; fd_set error_fds; int rval; diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h index e582cbfe3..476940563 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -82,6 +82,11 @@ enum * System call or library function error. */ OT_EXIT_ERROR_ERRNO = 5, + + /** + * No response from radio spinel. + */ + OT_EXIT_RADIO_SPINEL_NO_RESPONSE = 6, }; /** diff --git a/src/posix/platform/misc.cpp b/src/posix/platform/misc.cpp index e26e96eec..a5cd1da65 100644 --- a/src/posix/platform/misc.cpp +++ b/src/posix/platform/misc.cpp @@ -133,6 +133,10 @@ const char *otExitCodeToString(uint8_t aExitCode) retval = "RadioSpinelReset"; break; + case OT_EXIT_RADIO_SPINEL_NO_RESPONSE: + retval = "RadioSpinelNoResponse"; + break; + case OT_EXIT_ERROR_ERRNO: retval = strerror(errno); break; diff --git a/src/posix/platform/radio_spinel.cpp b/src/posix/platform/radio_spinel.cpp index c49d26b38..5673f6c68 100644 --- a/src/posix/platform/radio_spinel.cpp +++ b/src/posix/platform/radio_spinel.cpp @@ -1237,36 +1237,26 @@ otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...) otError RadioSpinel::WaitResponse(void) { - uint64_t now = platformGetTime(); - uint64_t end = now + kMaxWaitTime * US_PER_MS; - struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000}; + uint64_t end = platformGetTime() + kMaxWaitTime * US_PER_MS; + + otLogInfoPlat("Wait response: tid=%u key=%u", mWaitingTid, mWaitingKey); do { - if (mSpinelInterface.WaitForFrame(timeout) == OT_ERROR_RESPONSE_TIMEOUT) - { - FreeTid(mWaitingTid); - mWaitingTid = 0; - ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT); - } + uint64_t now; + uint64_t remain; + struct timeval timeout; now = platformGetTime(); + VerifyOrDie(end > now, OT_EXIT_RADIO_SPINEL_NO_RESPONSE); + remain = end - now; - if (end > now) - { - uint64_t remain = end - now; + timeout.tv_sec = static_cast(remain / US_PER_S); + timeout.tv_usec = static_cast(remain % US_PER_S); - timeout.tv_sec = static_cast(remain / US_PER_S); - timeout.tv_usec = static_cast(remain % US_PER_S); - } - else - { - mWaitingTid = 0; - mError = OT_ERROR_RESPONSE_TIMEOUT; - } + VerifyOrDie(mSpinelInterface.WaitForFrame(timeout) == OT_ERROR_NONE, OT_EXIT_RADIO_SPINEL_NO_RESPONSE); } while (mWaitingTid || !mIsReady); -exit: LogIfFail("Error waiting response", mError); // This indicates end of waiting repsonse. mWaitingKey = SPINEL_PROP_LAST_STATUS;