mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-08 02:48:36 +02:00
54 lines
1.4 KiB
C++
54 lines
1.4 KiB
C++
#include "icsneo/api/heartbeat.h"
|
|
#include "icsneo/api/lifetime.h"
|
|
#include "icsneo/device/device.h"
|
|
|
|
using namespace icsneo;
|
|
|
|
Heartbeat::Heartbeat(Device& device) :
|
|
device(device), mode(device.isOnline() ? Mode::Passive : Mode::Active), thread(&Heartbeat::run, this) {
|
|
}
|
|
|
|
Heartbeat::~Heartbeat() {
|
|
{
|
|
std::lock_guard lk(mutex);
|
|
stop = true;
|
|
}
|
|
cv.notify_one();
|
|
thread.join();
|
|
}
|
|
|
|
void Heartbeat::run() {
|
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
|
|
|
auto filter = std::make_shared<MessageFilter>(Message::Type::ResetStatus);
|
|
bool status = false;
|
|
auto cbHandle = device.com->addMessageCallback(std::make_shared<MessageCallback>(filter, [&](std::shared_ptr<Message>) {
|
|
{
|
|
std::lock_guard lk(mutex);
|
|
status = true;
|
|
}
|
|
cv.notify_one();
|
|
}));
|
|
Lifetime cbLifetime([&] {
|
|
device.com->removeMessageCallback(cbHandle);
|
|
});
|
|
while(true) {
|
|
std::unique_lock lk(mutex);
|
|
if(mode == Mode::Active) {
|
|
if(cv.wait_for(lk, std::chrono::milliseconds(100), [&] { return stop; })) {
|
|
break;
|
|
}
|
|
device.com->sendCommand(Command::RequestStatusUpdate);
|
|
}
|
|
if(!cv.wait_for(lk, std::chrono::seconds(2), [&] { return status || stop; })) {
|
|
// we disconnect instead of close because it indicates to the user that a cleanup is still required (our thread join)
|
|
device.report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
|
device.com->driver->setIsDisconnected(true);
|
|
break;
|
|
}
|
|
if(stop)
|
|
break;
|
|
status = false;
|
|
}
|
|
}
|