#ifndef __COMMUNICATION_H_ #define __COMMUNICATION_H_ #include "icsneo/communication/icommunication.h" #include "icsneo/communication/command.h" #include "icsneo/communication/network.h" #include "icsneo/communication/packet.h" #include "icsneo/communication/message/callback/messagecallback.h" #include "icsneo/communication/message/serialnumbermessage.h" #include "icsneo/api/eventmanager.h" #include "icsneo/communication/packetizer.h" #include "icsneo/communication/encoder.h" #include "icsneo/communication/decoder.h" #include #include #include #include #include #include namespace icsneo { class Communication { public: Communication( device_eventhandler_t report, std::unique_ptr com, std::shared_ptr p, std::unique_ptr e, std::unique_ptr md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), report(report), impl(std::move(com)) {} virtual ~Communication() { close(); } bool open(); bool close(); bool isOpen(); virtual void spawnThreads(); virtual void joinThreads(); bool rawWrite(const std::vector& bytes) { return impl->write(bytes); } virtual bool sendPacket(std::vector& bytes); void setWriteBlocks(bool blocks) { impl->writeBlocks = blocks; } virtual bool sendCommand(Command cmd, bool boolean) { return sendCommand(cmd, std::vector({ (uint8_t)boolean })); } virtual bool sendCommand(Command cmd, std::vector arguments = {}); bool getSettingsSync(std::vector& data, std::chrono::milliseconds timeout = std::chrono::milliseconds(50)); std::shared_ptr getSerialNumberSync(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)); int addMessageCallback(const MessageCallback& cb); bool removeMessageCallback(int id); std::shared_ptr waitForMessageSync( MessageFilter f = MessageFilter(), std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) { return waitForMessageSync([](){ return true; }, f, timeout); } // onceWaitingDo is a way to avoid race conditions. // Return false to bail early, in case your initial command failed. std::shared_ptr waitForMessageSync( std::function onceWaitingDo, MessageFilter f = MessageFilter(), std::chrono::milliseconds timeout = std::chrono::milliseconds(50)); std::shared_ptr packetizer; // Ownership is shared with the encoder std::unique_ptr encoder; std::unique_ptr decoder; device_eventhandler_t report; protected: std::unique_ptr impl; static int messageCallbackIDCounter; std::mutex messageCallbacksLock; std::map messageCallbacks; std::atomic closing{false}; void dispatchMessage(const std::shared_ptr& msg); private: std::thread readTaskThread; void readTask(); }; } #endif