diff --git a/api/icsneocpp/eventmanager.cpp b/api/icsneocpp/eventmanager.cpp index cf94c02..481c8a3 100644 --- a/api/icsneocpp/eventmanager.cpp +++ b/api/icsneocpp/eventmanager.cpp @@ -15,27 +15,6 @@ void EventManager::ResetInstance() { singleton = std::unique_ptr(new EventManager()); } -// If this thread is not in the map, add it to be ignored -// If it is, set it to be ignored -void EventManager::downgradeErrorsOnCurrentThread() { - std::lock_guard lk(downgradedThreadsMutex); - auto i = downgradedThreads.find(std::this_thread::get_id()); - if(i != downgradedThreads.end()) { - i->second = true; - } else { - downgradedThreads.insert({std::this_thread::get_id(), true}); - } -} - -// If this thread exists in the map, turn off downgrading -void EventManager::cancelErrorDowngradingOnCurrentThread() { - std::lock_guard lk(downgradedThreadsMutex); - auto i = downgradedThreads.find(std::this_thread::get_id()); - if(i != downgradedThreads.end()) { - i->second = false; - } -} - int EventManager::addEventCallback(const EventCallback &cb) { std::lock_guard lk(callbacksMutex); callbacks.insert({callbackID, cb}); diff --git a/communication/communication.cpp b/communication/communication.cpp index 51956b6..be8874a 100644 --- a/communication/communication.cpp +++ b/communication/communication.cpp @@ -131,7 +131,8 @@ std::shared_ptr Communication::waitForMessageSync(std::shared_ptr lk(m); - cv.wait_for(lk, timeout, [&returnedMessage]{ return !!returnedMessage; }); // `!!shared_ptr` checks if the ptr has a value + cv.wait_for(lk, timeout, [&returnedMessage] { return !!returnedMessage; }); // `!!shared_ptr` checks if the ptr has a value + lk.unlock(); // We don't actually check that we got a message, because either way we want to remove the callback (since it should only happen once) removeMessageCallback(cb); diff --git a/device/device.cpp b/device/device.cpp index 3632804..610eab0 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -222,15 +222,24 @@ bool Device::goOnline() { ledState = LEDState::Online; - online = true; updateLEDState(); + MessageFilter filter(Network::NetID::Reset_Status); + filter.includeInternalInAny = true; + // wait until communication is enabled or 10 seconds, whichever comes first - while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds::duration(10)) { + while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds::duration(5)) { if(latestResetStatus && latestResetStatus->comEnabled) break; - } + + if(!com->sendCommand(Command::RequestStatusUpdate)) + return false; + com->waitForMessageSync(filter, std::chrono::milliseconds(100)); + } + + online = true; + return true; } @@ -243,13 +252,22 @@ bool Device::goOffline() { ledState = (latestResetStatus && latestResetStatus->cmRunning) ? LEDState::CoreMiniRunning : LEDState::Offline; updateLEDState(); - online = false; + + MessageFilter filter(Network::NetID::Reset_Status); + filter.includeInternalInAny = true; // wait until communication is disabled or 10 seconds, whichever comes first - while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds::duration(10)) { + while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds::duration(5)) { if(latestResetStatus && !latestResetStatus->comEnabled) break; + + if(!com->sendCommand(Command::RequestStatusUpdate)) + return false; + + com->waitForMessageSync(filter, std::chrono::milliseconds(100)); } + + online = false; return true; } diff --git a/include/icsneo/api/eventmanager.h b/include/icsneo/api/eventmanager.h index d456cac..1cce3aa 100644 --- a/include/icsneo/api/eventmanager.h +++ b/include/icsneo/api/eventmanager.h @@ -21,9 +21,26 @@ public: static void ResetInstance(); - void downgradeErrorsOnCurrentThread(); + // If this thread is not in the map, add it to be ignored + // If it is, set it to be ignored + void downgradeErrorsOnCurrentThread() { + std::lock_guard lk(downgradedThreadsMutex); + auto i = downgradedThreads.find(std::this_thread::get_id()); + if(i != downgradedThreads.end()) { + i->second = true; + } else { + downgradedThreads.insert({std::this_thread::get_id(), true}); + } + } - void cancelErrorDowngradingOnCurrentThread(); + // If this thread exists in the map, turn off downgrading + void cancelErrorDowngradingOnCurrentThread() { + std::lock_guard lk(downgradedThreadsMutex); + auto i = downgradedThreads.find(std::this_thread::get_id()); + if(i != downgradedThreads.end()) { + i->second = false; + } + } int addEventCallback(const EventCallback &cb); diff --git a/include/icsneo/communication/command.h b/include/icsneo/communication/command.h index 8f61740..20b4537 100644 --- a/include/icsneo/communication/command.h +++ b/include/icsneo/communication/command.h @@ -10,6 +10,7 @@ enum class Command : uint8_t { //GetSettings = 0xA5, // Previously known as RED_CMD_READ_BAUD_REQ, now unused SaveSettings = 0xA6, SetDefaultSettings = 0xA8, // Follow up with SaveSettings to write to EEPROM + RequestStatusUpdate = 0xBC, ReadSettings = 0xC7, // Previously known as 3G_READ_SETTINGS_EX UpdateLEDState = 0xA7 }; diff --git a/platform/windows/vcp.cpp b/platform/windows/vcp.cpp index 2bedd23..24b9dcc 100644 --- a/platform/windows/vcp.cpp +++ b/platform/windows/vcp.cpp @@ -378,7 +378,7 @@ void VCP::readTask() { } else report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); } - if(ret == WAIT_ABANDONED) { + if(ret == WAIT_ABANDONED || ret == WAIT_FAILED) { state = LAUNCH; report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); }