#ifndef IOMAN_H #define IOMAN_H #include "cmdman.h" #include "fileman.h" #include #include #include #include #include #include #include #include using boost::asio::ip::tcp; /** * @class IoMan * * Input/Output manager * * Provides the glue logic for getting user and network input * as well as providing user and network output */ class IoMan { /* this is technically private and protected stuff which needs to be public * for the readline callback */ public: /** * Type of message to be output */ enum OutMsgType { normal, error, debug }; /** * Output msg to the user, treating it as type */ virtual void printMessage(std::string msg, OutMsgType type); /** * Flag wether to keep the main thread running * Matching mutex to provide syncthonizes access */ bool runmain; std::mutex mainmutex; /** * Vector to hold input generated/fetched locally (e.g. from the user) * Matching condition variable to wake up waiting threads * Matching mutex to provide synchronized access */ std::mutex localmutex; std::vector localinput; std::condition_variable localcv; boost::system::error_code errcode; protected: /** * Prompt messages for readline prompt */ virtual void printWelcomeMessage() = 0; virtual std::string getCmdPrompt() = 0; /** * The IP and port to connect to * Flag telling wether one is connected */ std::string ipstring; unsigned short port; bool connected; /** * Thread handles for processing local and network input as well as generating * responses to both Matching mutexes for the flags wether the threads should * keep running Function prototypes for the main thread functions */ std::thread tinput, tnetwork, tresponse; std::mutex inputmutex, networkmutex, responsemutex; bool runinput, runnetwork, runresponse; void networkMain(); void inputMain(); void responseMain(); /** * Instances of CmdMan and FileMan to process user input and handle File I/O */ CmdMan cmdman; FileMan fileman; /** * Functions used to handle results produced by CmdMan for user input or network input */ virtual void handleInCmdResponse(CmdMan::CmdRet cmdret); virtual void handleOutCmdResponse(CmdMan::CmdRet cmdret, vector &toput); /** * Boost asio sockets used for tcp and ssl communication and flag wether to use ssl or not */ tcp::socket *tcpsock; boost::asio::ssl::stream *sslsock; bool usessl; private: /** * Internal state to provide class-wide asio networking functionality */ boost::asio::io_service ios; boost::asio::streambuf recvbuf; boost::asio::ssl::context *sslctx; /** * Class-wide json functionality */ Json::CharReader *reader; Json::StreamWriterBuilder wbuilder; string jsonerror; /** * Vector to hold preprocessed input from the network * Matching condition variable to wake up waiting threads * Matching mutex to provide synchronized access */ std::vector netinput; std::mutex netmutex; std::condition_variable netcv; /** * Tokenizes input based on space as seperator * Respects double-quoted tokens * Returns a vector with the tokens as elements in order */ std::vector tokenizeInput(std::string in); /** * Timestamp saves the sending time of the oldest request to the server that was not followed by an answer. * If the timestamp is not valid, since the last request to the server, there was an answer * (or the cli is disconnected, or there was no request yet). * Mutex used for access to the timestamps. */ time_t sendtimestamp; bool sendtimestampValid; std::mutex timestampmutex; public: /** * Constructor and destructor */ IoMan(bool enablessl, const char *certfile); virtual ~IoMan(); /** * Establish connection to server and perform vesion check * Return true if successful, false otherwise */ virtual bool init(); /** * Main loop, call init first */ virtual void run(); /** * Establish connection to server * Return true if successful, false otherwise */ bool connect(); /** * Disconnect from a connected server */ void disconnect(); }; #endif