From b7c7d4349a9fb5a8bce4bc3b6b371e38e92a2069 Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Thu, 29 Apr 2021 19:08:31 -0400 Subject: [PATCH] Device: Extend open() API for long-running tasks --- device/device.cpp | 11 +++-- include/icsneo/device/device.h | 49 ++++++++++++++++++- .../device/extensions/deviceextension.h | 5 +- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/device/device.cpp b/device/device.cpp index 3bb379d..1c4f19f 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -2,6 +2,7 @@ #include "icsneo/communication/message/callback/messagecallback.h" #include "icsneo/api/eventmanager.h" #include "icsneo/communication/command.h" +#include "icsneo/device/extensions/deviceextension.h" #include #include #include @@ -164,7 +165,7 @@ void Device::enforcePollingMessageLimit() { } } -bool Device::open() { +bool Device::open(OpenFlags flags, OpenStatusHandler handler) { if(!com) { report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; @@ -178,8 +179,8 @@ bool Device::open() { if(attemptErr != APIEvent::Type::NoErrorFound) { // We could not communicate with the device, let's see if an extension can bool tryAgain = false; - forEachExtension([&tryAgain](const std::shared_ptr& ext) -> bool { - if(ext->onDeviceCommunicationDead()) + forEachExtension([&tryAgain, &flags, &handler](const std::shared_ptr& ext) -> bool { + if(ext->onDeviceCommunicationDead(flags, handler)) tryAgain = true; return true; }); @@ -197,8 +198,8 @@ bool Device::open() { } bool block = false; - forEachExtension([&block](const std::shared_ptr& ext) { - if(ext->onDeviceOpen()) + forEachExtension([&block, &flags, &handler](const std::shared_ptr& ext) { + if(ext->onDeviceOpen(flags, handler)) return true; block = true; return false; diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 70bc615..e4c9409 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -8,13 +8,13 @@ #include #include #include +#include #include "icsneo/api/eventmanager.h" #include "icsneo/api/lifetime.h" #include "icsneo/device/neodevice.h" #include "icsneo/device/idevicesettings.h" #include "icsneo/device/nullsettings.h" #include "icsneo/device/devicetype.h" -#include "icsneo/device/extensions/deviceextension.h" #include "icsneo/communication/communication.h" #include "icsneo/communication/packetizer.h" #include "icsneo/communication/encoder.h" @@ -29,6 +29,8 @@ namespace icsneo { +class DeviceExtension; + class Device { public: virtual ~Device(); @@ -50,7 +52,50 @@ public: return os; } - virtual bool open(); + class OpenFlags { + public: + enum Enum { + /** + * Even if the firmware does not match the current firmware version, + * the device will not be updated. + * + * Note: The device may still be flashed if the device has no firmware + * + * This has no effect if the DFU extension is not present + */ + SuppressAutoUpdate = 1 << 0, + + /** + * Force reflash the device. + * + * This has no effect if the DFU extension is not present + */ + ForceReflash = 1 << 1 + }; + using EnumType = std::underlying_type::type; + + OpenFlags(Enum e = Enum(0)) : val(e) {} + EnumType operator&(Enum e) const { return EnumType(val) & EnumType(e); } + + private: + const Enum val; + }; + + enum class OpenDirective { + Continue, + Cancel, + Skip + }; + + enum class OpenStatusType { + Question, + Progress + }; + + using OpenStatusHandler = std::function progress)>; + + bool open(OpenFlags flags = {}, OpenStatusHandler handler = + [](OpenStatusType type, const std::string& _s, optional _p) { return OpenDirective::Continue; }); virtual bool close(); virtual bool isOnline() const { return online; } virtual bool isOpen() const { return com->isOpen(); } diff --git a/include/icsneo/device/extensions/deviceextension.h b/include/icsneo/device/extensions/deviceextension.h index 27e55e0..07b4f99 100644 --- a/include/icsneo/device/extensions/deviceextension.h +++ b/include/icsneo/device/extensions/deviceextension.h @@ -6,6 +6,7 @@ #include #include "icsneo/communication/message/message.h" #include "icsneo/api/eventmanager.h" +#include "icsneo/device/device.h" namespace icsneo { @@ -18,10 +19,10 @@ public: virtual const char* getName() const = 0; // Return false to block opening - virtual bool onDeviceOpen() { return true; } + virtual bool onDeviceOpen(Device::OpenFlags flags, const Device::OpenStatusHandler& handler) { return true; } // Return true to indicate that communication should now be back - virtual bool onDeviceCommunicationDead() { return false; } + virtual bool onDeviceCommunicationDead(Device::OpenFlags flags, const Device::OpenStatusHandler& handler) { return false; } virtual void onGoOnline() {} virtual void onGoOffline() {}