Line data Source code
1 : /// IndiConnection.hpp
2 : ///
3 : /// @author Paul Grenz
4 : ///
5 : /// This is a virtual class which must be derived from to be useful.
6 : /// See 'IndiClient' and 'IndiDriver' for a class that can be insantiated.
7 : ///
8 : ////////////////////////////////////////////////////////////////////////////////
9 :
10 : #ifndef PCF_INDI_CONNECTION_HPP
11 : #define PCF_INDI_CONNECTION_HPP
12 :
13 : #include <string>
14 : #include <vector>
15 : #include "Thread.hpp"
16 : #include "MutexLock.hpp"
17 : #include "TimeStamp.hpp"
18 : //#include "ConfigFile.hpp"
19 : #include "IndiXmlParser.hpp"
20 : #include "IndiMessage.hpp"
21 : #include "IndiProperty.hpp"
22 :
23 : ////////////////////////////////////////////////////////////////////////////////
24 :
25 : namespace pcf
26 : {
27 : class IndiConnection : public pcf::Thread
28 : {
29 : private:
30 : enum Constants
31 : {
32 : // This is the size of the input buffer to hold the incoming commands.
33 : InputBufSize = 65536,
34 : };
35 :
36 : // construction/destruction/assign/copy
37 : public:
38 : /// Standard constructor.
39 : IndiConnection();
40 : /// Constructor which sets the name, version, and INDI protocol version.
41 : IndiConnection( const std::string &szName,
42 : const std::string &szVersion,
43 : const std::string &szProtocolVersion );
44 : /// Standard destructor.
45 : virtual ~IndiConnection();
46 :
47 : // Prevent these from being invoked.
48 : private:
49 : /// Copy constructor.
50 : IndiConnection( const IndiConnection &idRhs );
51 : /// Assignment operator.
52 : const IndiConnection &operator= ( const IndiConnection &idRhs );
53 : /// Called from the constructor to initialize member variables.
54 : void construct( const std::string &szName,
55 : const std::string &szVersion,
56 : const std::string &szProtocolVersion );
57 : /// Listens on the file descriptor in a loop for incoming INDI messages.
58 : /// Exits when the 'Quit Process' flag becomes true.
59 : void process();
60 :
61 : // Standard client interface methods.
62 : public:
63 : /// Try to start the driver 'execute' thread. If it is already running, this
64 : /// will throw. When the thread starts, it calls 'beforeExecute' before
65 : /// calling 'execute' in a loop.
66 : void activate();
67 : /// Override this function to do something after this device has been told to
68 : /// stop running the thread, like clean up allocated memory.
69 : virtual void afterExecute();
70 : /// Override this function to do something before this device has been told to
71 : /// start running the thread, like allocate memory.
72 : virtual void beforeExecute();
73 : /// Try to stop the driver 'execute' thread and the 'process' thread. If
74 : /// neither is running, this will have no effect. This will stop the 'execute'
75 : /// being called in a loop and call 'afterExecute' before stopping the thread.
76 : void deactivate();
77 : /// Chooses what to do with the received property.
78 : virtual void dispatch( const IndiMessage::Type &tType,
79 : const IndiProperty &ipDispatch ) = 0;
80 : /// Turns the additional logging on or off.
81 : void enableVerboseMode( const bool &oEnable );
82 : /// Function which executes in a loop in a separate thread.
83 : /// Override in derived class to perform some action.
84 : virtual void execute();
85 : /// Return the config file path.
86 : std::string getConfigPath() const;
87 : /// Return the log file path.
88 : std::string getLogPath() const;
89 : /// Return the name of this client.
90 : std::string getName() const;
91 : /// Return the INDI protocol version.
92 : std::string getProtocolVersion() const;
93 : /// Returns the version of this component.
94 : std::string getVersion() const;
95 :
96 : /// Is the driver currently active ('execute' thread running)?
97 : bool isActive() const;
98 : /// Are we logging additional messages?
99 : bool isVerboseModeEnabled() const;
100 : /// Called to ensure that incoming INDI messages are received and handled.
101 : /// It will not exit until we receive a signal. May create a new thread.
102 : void processIndiRequests( const bool &oUseThread = false );
103 : /// Sends an XML string out to a file descriptor. If there is an error,
104 : /// it will be logged.
105 : virtual void sendXml( const std::string &szXml ) const;
106 :
107 : /// Which FD will be used for input?
108 : void setInputFd( const int &iFd );
109 : /// Set the name of this component.
110 : void setName( const std::string &szName );
111 : /// Which FD will be used for output?
112 : void setOutputFd( const int &iFd );
113 : /// Set the version of the INDI protocol.
114 : void setProtocolVersion( const std::string &szProtocolVersion );
115 : /// Sets the INDI protocol version.
116 : void setVersion( const std::string &szVersion );
117 :
118 : /// Called in the process loop to perform an action each time through.
119 : virtual void update() = 0;
120 : /// This will cause the process to quit, the same as if a ctrl-c was sent.
121 : void quitProcess();
122 :
123 0 : bool getQuitProcess()
124 : {
125 0 : return m_oQuitProcess;
126 : }
127 :
128 : // Helper functions.
129 : protected:
130 : /// 'pthread_create' needs a static function to get the thread going.
131 : /// Passing a pointer back to this class allows us to call the 'runLoop'
132 : /// function from within the new thread.
133 : static void *pthreadProcess( void *pUnknown );
134 :
135 : // Variables
136 : private:
137 : /// The name of this client.
138 : std::string m_szName;
139 : /// the version of this software. may be "none".
140 : std::string m_szVersion;
141 : /// Is this client generating additional messages?
142 : bool m_oIsVerboseModeEnabled;
143 : /// Which CPU do we want to run the worker thread on?
144 : int m_iCpuAffinity;
145 : /// allocate a big buffer to hold the input data.
146 : std::vector<unsigned char> m_vecInputBuf;
147 :
148 : /// The flag to tell this to quit.
149 : //Changed from static to prevent app-wide INDI shutdown.
150 : bool m_oQuitProcess {false};
151 :
152 : /// This is the object that conglomerates all the INDI XML
153 : pcf::IndiXmlParser m_ixpIndi;
154 : /// A mutex to protect output.
155 : mutable pcf::MutexLock m_mutOutput;
156 : /// The file descriptor to read from.
157 : int m_fdInput;
158 :
159 : /// The file descriptor to write to.
160 : int m_fdOutput;
161 :
162 : /// Stream for safer output
163 : FILE * m_fstreamOutput {NULL};
164 :
165 : FILE * m_fstreamSTDOUT {NULL};
166 :
167 : /// If the processing of INDI messages is put in a separate thread,
168 : /// this is the thread id of it.
169 : pthread_t m_idProcessThread;
170 :
171 : }; // class IndiConnection
172 : } // namespace pcf
173 :
174 : ////////////////////////////////////////////////////////////////////////////////
175 :
176 : #endif // PCF_INDI_CONNECTION_HPP
|