From 9e49c315edbe554d24dbfb6f81e9e596bf2004e7 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Wed, 4 Nov 2026 15:54:14 -0500 Subject: [PATCH] Communication: Clear disconnected on open --- CMakeLists.txt | 1 + communication/communication.cpp | 2 ++ test/unit/communicationtest.cpp | 48 +++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/unit/communicationtest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 43a961fe..c47a2da8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -512,6 +512,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS) test/unit/icsneoc2.cpp test/unit/ethphyregistertest.cpp test/unit/tc10test.cpp + test/unit/communicationtest.cpp test/unit/periodictest.cpp ) diff --git a/communication/communication.cpp b/communication/communication.cpp index e402deba..893efe00 100644 --- a/communication/communication.cpp +++ b/communication/communication.cpp @@ -36,6 +36,8 @@ bool Communication::open() { return false; } + // A heartbeat timeout marks the driver disconnected and leaves the cleanup to the user, a new open starts connected + driver->setIsDisconnected(false); if(!driver->open()) return false; spawnThreads(); diff --git a/test/unit/communicationtest.cpp b/test/unit/communicationtest.cpp new file mode 100644 index 00000000..5ee60dc9 --- /dev/null +++ b/test/unit/communicationtest.cpp @@ -0,0 +1,48 @@ +#include "gtest/gtest.h" + +#include +#include + +#include "icsneo/icsneocpp.h" +#include "icsneo/communication/driver.h" +#include "icsneo/device/tree/radmoon2/radmoon2zl.h" + +using namespace icsneo; + +namespace { + +class ReopenTestDriver : public Driver { +public: + explicit ReopenTestDriver(const device_eventhandler_t& handler) : Driver(handler) {} + + bool open() override { opened = true; return true; } + bool isOpen() override { return opened; } + bool close() override { opened = false; return true; } + driver_finder_t getFinder() override { return [](std::vector&) {}; } + +protected: + bool writeInternal(const std::vector&) override { return true; } + +private: + bool opened = false; +}; + +} + +// The heartbeat marks the driver disconnected and the user closes and opens again. Drivers like Servd stop their +// threads while disconnected, so the reopened connection must not start disconnected. +TEST(Communication, OpenAfterDisconnectIsConnected) { + FoundDevice found; + std::memcpy(found.serial, "RN0001", 6); + found.makeDriver = [](device_eventhandler_t handler, neodevice_t&) { + return std::make_unique(handler); + }; + auto device = std::make_shared(found); + ASSERT_TRUE(device->com->open()); + + device->com->driver->setIsDisconnected(true); + ASSERT_TRUE(device->com->close()); + ASSERT_TRUE(device->com->open()); + EXPECT_FALSE(device->com->isDisconnected()); + EXPECT_TRUE(device->com->close()); +}