mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Detect device disconnects
When a device is sending any traffic, the device is considered to be connected. If no traffic if being received from the device, a status is requested. If the device fails to report the status back in a timely manner, it is considered to be disconnected. If the device fails to reply to the status request, it is important to confirm that the device is not applying settings. While the device is applying settings, it will not be sending heartbeats or able to process a status request.
This commit is contained in:
@@ -205,6 +205,32 @@ bool Device::open() {
|
||||
handleInternalMessage(message);
|
||||
}));
|
||||
|
||||
std::atomic<bool> receivedMessage{false};
|
||||
messageReceivedCallbackID = com->addMessageCallback(MessageCallback(filter, [&](std::shared_ptr<Message> message) {
|
||||
receivedMessage = true;
|
||||
}));
|
||||
|
||||
heartbeatThread = std::thread([&]() {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
while(true) {
|
||||
// Wait for 110ms for a possible heartbeat
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(110));
|
||||
if(!receivedMessage) {
|
||||
// No heartbeat received, request a status
|
||||
com->sendCommand(Command::RequestStatusUpdate);
|
||||
// The response should come back quickly if the com is quiet
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
// Check if we got a message, and if not, if settings are being applied
|
||||
if(!receivedMessage && !settings->applyingSettings) {
|
||||
if(!stopHeartbeatThread)
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
receivedMessage = false;
|
||||
}
|
||||
});
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceOpen(); return true; });
|
||||
return true;
|
||||
}
|
||||
@@ -215,12 +241,17 @@ bool Device::close() {
|
||||
return false;
|
||||
}
|
||||
|
||||
stopHeartbeatThread = true;
|
||||
|
||||
if(isOnline())
|
||||
goOffline();
|
||||
|
||||
if(internalHandlerCallbackID)
|
||||
com->removeMessageCallback(internalHandlerCallbackID);
|
||||
|
||||
if(messageReceivedCallbackID)
|
||||
com->removeMessageCallback(messageReceivedCallbackID);
|
||||
|
||||
internalHandlerCallbackID = 0;
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceClose(); return true; });
|
||||
|
||||
@@ -210,6 +210,8 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
bytestream[6] = (uint8_t)(gs_checksum >> 8);
|
||||
memcpy(bytestream.data() + 7, getMutableRawStructurePointer(), settings.size());
|
||||
|
||||
// Pause I/O with the device while the settings are applied
|
||||
applyingSettings = true;
|
||||
|
||||
std::shared_ptr<Message> msg = com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
@@ -250,6 +252,8 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
}, Main51MessageFilter(Command::SaveSettings), std::chrono::milliseconds(5000));
|
||||
}
|
||||
|
||||
applyingSettings = false;
|
||||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||
@@ -270,6 +274,8 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
applyingSettings = true;
|
||||
|
||||
std::shared_ptr<Message> msg = com->waitForMessageSync([this]() {
|
||||
return com->sendCommand(Command::SetDefaultSettings);
|
||||
}, Main51MessageFilter(Command::SetDefaultSettings), std::chrono::milliseconds(1000));
|
||||
@@ -317,6 +323,8 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
return com->sendCommand(Command::SaveSettings);
|
||||
}, Main51MessageFilter(Command::SaveSettings), std::chrono::milliseconds(5000));
|
||||
}
|
||||
|
||||
applyingSettings = false;
|
||||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
|
||||
Reference in New Issue
Block a user