Line data Source code
1 : /// $Id: IndiClient.cpp
2 : ///
3 : /// @author Paul Grenz
4 : ///
5 : ////////////////////////////////////////////////////////////////////////////////
6 :
7 : #include "IndiClient.hpp"
8 : #include "SystemSocket.hpp"
9 : //#include "Config.hpp"
10 :
11 : using std::runtime_error;
12 : using std::string;
13 : using std::endl;
14 : using std::vector;
15 : using pcf::Thread;
16 : using pcf::IndiClient;
17 : using pcf::IndiMessage;
18 : using pcf::IndiProperty;
19 :
20 : ////////////////////////////////////////////////////////////////////////////////
21 : /// Standard constructor.
22 :
23 0 : IndiClient::IndiClient( const string & szIPAddr,
24 : const int & port
25 0 : )
26 0 : : IndiConnection()
27 : {
28 0 : setup(szIPAddr, port);
29 0 : }
30 :
31 : ////////////////////////////////////////////////////////////////////////////////
32 :
33 0 : IndiClient::IndiClient( const string &szName,
34 : const string &szVersion,
35 : const string &szProtocolVersion,
36 : const string & szIPAddr,
37 : const int & port
38 0 : )
39 0 : : IndiConnection( szName, szVersion, szProtocolVersion )
40 : {
41 0 : setup(szIPAddr, port);
42 0 : }
43 :
44 : ////////////////////////////////////////////////////////////////////////////////
45 : /// \brief IndiClient::IndiClient
46 : /// Copy constructor.
47 : /// \param icRhs Another version of the driver.
48 :
49 0 : IndiClient::IndiClient(const IndiClient &icRhs ) : IndiConnection()
50 : // : IndiConnection( icRhs ) // can't invoke - private
51 : {
52 : static_cast<void>(icRhs);
53 : // Empty because this is private.
54 0 : }
55 :
56 : ////////////////////////////////////////////////////////////////////////////////
57 : /// \brief IndiClient::operator =
58 : /// Assignment operator.
59 : /// \param icRhs The right-hand side of the operation.
60 : /// \return This object.
61 :
62 0 : const IndiClient &IndiClient::operator= ( const IndiClient &icRhs )
63 : // : IndiConnection::operator= ( icRhs ) // can't invoke - private
64 : {
65 : static_cast<void>(icRhs);
66 : // Empty because this is private.
67 0 : return *this;
68 : }
69 :
70 : ////////////////////////////////////////////////////////////////////////////////
71 : /// \brief IndiClient::~IndiClient
72 : /// Standard destructor.
73 :
74 0 : IndiClient::~IndiClient()
75 : {
76 0 : if ( m_socClient.isValid() == true )
77 : {
78 0 : m_socClient.close();
79 0 : Thread::msleep( 10 );
80 : }
81 0 : }
82 :
83 : ////////////////////////////////////////////////////////////////////////////////
84 : /// \brief IndiClient::setup Sets up file descriptors and other things that
85 : /// need to be initialized at construction time.
86 :
87 0 : void IndiClient::setup( const string & szIPAddr,
88 : const int & port
89 : )
90 : {
91 : try
92 : {
93 : // These are the two descriptors we will use to talk to the outside world.
94 : // Set them by default to an invalid value.
95 0 : setInputFd( -1 ); // STDIN_FILENO;
96 0 : setOutputFd( -1 ); // STDOUT_FILENO;
97 :
98 0 : if ( m_socClient.isValid() == true )
99 : {
100 0 : m_socClient.close();
101 0 : Thread::msleep( 10 );
102 : }
103 :
104 : //Config cfReader;
105 0 : m_socClient = SystemSocket( SystemSocket::Stream, port, szIPAddr.c_str());
106 :
107 0 : m_socClient.connect();
108 :
109 : // Make sure we have a limit on how long we wait for a response.
110 : //m_socClient.setRecvTimeout( 1000 );
111 : // Make sure the socket will wait for data.
112 : //m_socClient.setNonBlocking( false );
113 : // Send all data, no matter how small.
114 0 : m_socClient.disableNagle( true );
115 :
116 : // Give the server a moment to set up.
117 0 : Thread::msleep( 10 );
118 :
119 : // Assign the file descriptor to the member variables.
120 0 : setInputFd( m_socClient.getFd() );
121 0 : setOutputFd( m_socClient.getFd() );
122 :
123 : }
124 0 : catch ( const SystemSocket::Error &err )
125 : {
126 0 : m_socClient.close();
127 0 : Thread::msleep( 10 );
128 0 : return;
129 0 : }
130 0 : catch ( const runtime_error &excepRuntime )
131 : {
132 0 : m_socClient.close();
133 0 : Thread::msleep( 10 );
134 0 : return;
135 0 : }
136 : }
137 :
138 : ////////////////////////////////////////////////////////////////////////////////
139 : /// \brief IndiClient::update
140 : /// Called in the process loop to perform an action each time through.
141 :
142 0 : void IndiClient::update()
143 : {
144 0 : }
145 :
146 : ////////////////////////////////////////////////////////////////////////////////
147 : /// \brief IndiClient::dispatch
148 : /// Chooses what to do with the received property.
149 : /// \param tType Type of the message we received.
150 : /// \param ipDispatch The property contained in the message.
151 :
152 0 : void IndiClient::dispatch( const IndiMessage::Type &tType,
153 : const IndiProperty &ipDispatch )
154 : {
155 : // Decide what we should do based on the type of the message.
156 0 : switch ( tType )
157 : {
158 0 : case IndiMessage::Define:
159 0 : handleDefProperty( ipDispatch ); break;
160 0 : case IndiMessage::Delete:
161 0 : handleDelProperty( ipDispatch ); break;
162 0 : case IndiMessage::Message:
163 0 : handleMessage( ipDispatch ); break;
164 0 : case IndiMessage::NewProperty:
165 0 : handleNewProperty( ipDispatch ); break;
166 0 : case IndiMessage::SetProperty:
167 0 : handleSetProperty( ipDispatch ); break;
168 0 : default:
169 0 : break;
170 : }
171 0 : }
172 :
173 : ////////////////////////////////////////////////////////////////////////////////
174 : /// Override this function to do something before this device has been told to
175 : /// start, like allocate memory.
176 :
177 0 : void IndiClient::beforeExecute()
178 : {
179 0 : }
180 :
181 : ////////////////////////////////////////////////////////////////////////////////
182 : /// Override this function to do something after this device has been told to
183 : /// stop, like clean up allocated memory.
184 :
185 0 : void IndiClient::afterExecute()
186 : {
187 0 : }
188 :
189 : ////////////////////////////////////////////////////////////////////////////////
190 : /// Override in derived class, place the code to do something here.
191 :
192 0 : void IndiClient::execute()
193 : {
194 0 : }
195 :
196 : ////////////////////////////////////////////////////////////////////////////////
197 : /// Received a DEF PROPERTY. A remote device sends a 'DEF' to tell other
198 : /// INDI devices that are interested what properties it has available.
199 : /// (see 'sendDefProperty')
200 :
201 0 : void IndiClient::handleDefProperty( const pcf::IndiProperty &ipRecv )
202 : {
203 : static_cast<void>(ipRecv);
204 0 : }
205 :
206 : ////////////////////////////////////////////////////////////////////////////////
207 : /// Received a DEL PROPERTY. A remote device is telling us that one of its
208 : /// properties is no longer available, or a device is no longer available.
209 : /// (see 'sendDelProperty')
210 :
211 0 : void IndiClient::handleDelProperty( const pcf::IndiProperty &ipRecv )
212 : {
213 : static_cast<void>(ipRecv);
214 0 : }
215 :
216 : ////////////////////////////////////////////////////////////////////////////////
217 : /// Received a MESSAGE. a remote device sent a generic message,
218 : /// associated with a device or entire system.
219 :
220 0 : void IndiClient::handleMessage( const pcf::IndiProperty &ipRecv )
221 : {
222 : static_cast<void>(ipRecv);
223 0 : }
224 :
225 : ////////////////////////////////////////////////////////////////////////////////
226 : /// Received a NEW PROPERTY. This is a request to update one of the
227 : /// INDI properties we own.
228 :
229 0 : void IndiClient::handleNewProperty( const pcf::IndiProperty &ipRecv )
230 : {
231 : static_cast<void>(ipRecv);
232 0 : }
233 :
234 : ////////////////////////////////////////////////////////////////////////////////
235 : /// Received a SET PROPERTY. This is a notification telling us that a
236 : /// remote device changed one of its INDI properties.
237 :
238 0 : void IndiClient::handleSetProperty( const pcf::IndiProperty &ipRecv )
239 : {
240 : static_cast<void>(ipRecv);
241 0 : }
242 :
243 : ////////////////////////////////////////////////////////////////////////////////
244 : /// Send an ENABLE BLOB. This behavior is only to be implemented in
245 : /// intermediate INDI server processes; individual devices shall
246 : /// disregard enableBLOB and send all elements at will.
247 :
248 0 : void IndiClient::sendEnableBLOB( const IndiProperty &ipSend )
249 : {
250 0 : IndiXmlParser ixp( IndiMessage( IndiMessage::EnableBLOB, ipSend ),
251 0 : getProtocolVersion() );
252 0 : sendXml( ixp.createXmlString() );
253 0 : }
254 :
255 : ////////////////////////////////////////////////////////////////////////////////
256 : /// Send a GET PROPERTIES. When a Client first starts up, it begins
257 : /// by sending the getProperties command. This includes the protocol
258 : /// version and may include the name of a specific Device and Property
259 : /// if it is known by some other means. If no device is specified,
260 : /// then all devices are reported; if no name is specified,
261 : /// then all properties for the given device are reported. The Device
262 : /// then calls 'sendDefProperty' for each matching Property it offers
263 : /// for control, limited to the Properties of the specified Device if
264 : /// included.
265 :
266 0 : void IndiClient::sendGetProperties( const IndiProperty &ipSend )
267 : {
268 0 : IndiXmlParser ixp( IndiMessage( IndiMessage::GetProperties, ipSend ),
269 0 : getProtocolVersion() );
270 0 : sendXml( ixp.createXmlString() );
271 0 : }
272 :
273 : ////////////////////////////////////////////////////////////////////////////////
274 : // Send a MESSAGE.
275 :
276 0 : void IndiClient::sendMessage( const IndiProperty &ipSend )
277 : {
278 0 : IndiXmlParser ixp( IndiMessage( IndiMessage::Message, ipSend ),
279 0 : getProtocolVersion() );;
280 0 : sendXml( ixp.createXmlString() );
281 0 : }
282 :
283 : ////////////////////////////////////////////////////////////////////////////////
284 : // Send a NEW PROPERTY. This is a request to a remote device to
285 : // update a property that the remote device owns.
286 :
287 0 : void IndiClient::sendNewProperty( const IndiProperty &ipSend )
288 : {
289 0 : IndiXmlParser ixp( IndiMessage( IndiMessage::NewProperty, ipSend ),
290 0 : getProtocolVersion() );
291 0 : sendXml( ixp.createXmlString() );
292 0 : }
293 :
294 : ////////////////////////////////////////////////////////////////////////////////
295 : // Send an NEW PROPERTY vector. This is a request to a remote device to
296 : // update a property that the remote device owns.
297 :
298 0 : void IndiClient::sendNewProperties( const vector<IndiProperty> &vecIpSend )
299 : {
300 0 : for ( unsigned int ii = 0; ii < vecIpSend.size(); ii++ )
301 : {
302 0 : IndiXmlParser ixp( IndiMessage( IndiMessage::NewProperty, vecIpSend[ii] ),
303 0 : getProtocolVersion() );
304 0 : sendXml( ixp.createXmlString() );
305 0 : }
306 0 : }
307 :
308 : ////////////////////////////////////////////////////////////////////////////////
|