release
[tango-nonfree.git] / lib / cpp / client / Connection.h
blobbceba553d24f5f5dde8258a2b550de5d52026f6e
1 //////////////////////////////////////////////////////////////////
2 //
3 // Connection.h - include file for TANGO class Connection
4 //
5 //
6 // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015
7 // European Synchrotron Radiation Facility
8 // BP 220, Grenoble 38043
9 // FRANCE
11 // This file is part of Tango.
13 // Tango is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU Lesser General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
18 // Tango is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public License
24 // along with Tango. If not, see <http://www.gnu.org/licenses/>.
26 // $Revision: 20437 $
28 ///////////////////////////////////////////////////////////////
30 #ifndef _CONNECTION_H
31 #define _CONNECTION_H
35 /****************************************************************************************
36 * *
37 * The Connection class *
38 * -------------------- *
39 * *
40 ***************************************************************************************/
42 /**
43 * Base class for Tango device access
45 * Base class for Tango device access. This class is pure virtual and can be instanciated
46 * as is.
48 * $Author: taurel $
49 * $Revision: 1 $
51 * @ingroup Client
52 * @headerfile tango.h
55 class Connection
57 protected :
58 ///@privatesection
59 bool dbase_used; // Dev. with database
60 bool from_env_var; // DB from TANGO_HOST
62 string host; // DS host (if dbase_used=false)
63 string port; // DS port (if dbase_used=false)
64 int port_num; // DS port (as number)
66 string db_host; // DB host
67 string db_port; // DB port
68 int db_port_num; // DB port (as number)
70 string ior;
71 long pasyn_ctr;
72 long pasyn_cb_ctr;
74 Tango::Device_var device;
75 Tango::Device_2_var device_2;
77 int timeout;
79 int connection_state;
80 int version;
81 Tango::DevSource source;
83 bool check_acc;
84 AccessControlType access;
86 virtual string get_corba_name(bool)=0;
87 virtual string build_corba_name()=0;
88 virtual int get_lock_ctr()=0;
89 virtual void set_lock_ctr(int)=0;
91 DeviceData redo_synch_cmd(TgRequest &);
93 int get_env_var(const char *,string &);
94 int get_env_var_from_file(string &,const char *,string &);
96 void set_connection_state(int);
98 void check_and_reconnect();
99 void check_and_reconnect(Tango::DevSource &);
100 void check_and_reconnect(Tango::AccessControlType &);
101 void check_and_reconnect(Tango::DevSource &,Tango::AccessControlType &);
103 long add_asyn_request(CORBA::Request_ptr,TgRequest::ReqType);
104 void remove_asyn_request(long);
106 void add_asyn_cb_request(CORBA::Request_ptr,CallBack *,Connection *,TgRequest::ReqType);
107 void remove_asyn_cb_request(Connection *,CORBA::Request_ptr);
108 long get_pasyn_cb_ctr();
110 class ConnectionExt
112 public:
113 ConnectionExt():has_alt_adr(false) {}
114 ~ConnectionExt() {}
115 ConnectionExt & operator=(const ConnectionExt &);
117 bool has_alt_adr;
120 #ifdef HAS_UNIQUE_PTR
121 unique_ptr<ConnectionExt> ext;
122 #else
123 ConnectionExt *ext; // Class extension
124 #endif
126 bool tr_reco;
127 Tango::Device_3_var device_3;
129 bool prev_failed;
130 double prev_failed_t0;
132 Tango::Device_4_var device_4;
133 omni_mutex adm_dev_mutex;
134 omni_mutex asyn_mutex;
135 ReadersWritersLock con_to_mon;
137 int user_connect_timeout;
138 bool tango_host_localhost;
140 Tango::Device_5_var device_5;
142 public :
143 ///@publicsection
144 /**@name Miscellaneous methods */
145 //@{
147 * Set device timeout
149 * Set client side timeout for device in milliseconds. Any method which takes longer than this time to execute
150 * will throw an exception.
152 * @param [in] timeout The timeout value in mS
154 virtual void set_timeout_millis(int timeout);
156 * Get device timeout
158 * Get the client side timeout in milliseconds.
160 * @return The device timeout (in mS)
162 virtual int get_timeout_millis();
164 * Get device IDL version
166 * Get the version of the Tango Device IDL interface implemented by the device
168 * @return The device IDL version
170 int get_idl_version() {return version;}
172 * Get device source
174 * Get the device data source used by command_inout or read_attribute methods. The DevSource is an enumerated
175 * type which can be one of {DEV, CACHE, CACHE_DEV}. See chapter on Advanced Feature in
176 * <a href=http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/ds_prog/index.html target=new>Tango book</a>
177 * for all details regarding polling.
179 * @return The device source flag
181 virtual Tango::DevSource get_source();
183 * Set device source
185 * Set the data source (device, polling buffer, polling buffer than device) for command_inout and read_attribute
186 * methods. The DevSource is an enumerated type which can be one of {DEV, CACHE, CACHE_DEV}. The
187 * default value is CACHE_DEV. See chapter on Advanced Feature for all details regarding polling
189 * @param [in] sou The device source
191 virtual void set_source(Tango::DevSource sou);
193 * Set device transparency (reconnection) mode
195 * If flag is true, no exception will be thrown in case of network communication error between client and
196 * server. The API will try to re-build the network connection between client and server as soon as an error is
197 * detected. See @ref recon for more details on reconnection and exception
199 * @param [in] val The device transparency flag
201 virtual void set_transparency_reconnection(bool val) {tr_reco = val;}
203 * Get device transparency (reconnection) mode
205 * Returns the transparency reconnection flag.
206 * See @ref recon for more details on reconnection and exception
208 * @return The device transparency flag
210 virtual bool get_transparency_reconnection() {return tr_reco;}
211 //@}
213 /** @name Synchronous command oriented methods */
214 //@{
216 * Execute a command (without input data)
218 * Execute a command on a device which takes no input arguments (void). The result is returned in a DeviceData object
220 * @param [in] cmd_name The command name
221 * @return The command result
222 * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
224 virtual DeviceData command_inout(string &cmd_name);
226 * Execute a command (without input data)
228 * Execute a command on a device which takes no input arguments (void). The result is returned in a DeviceData object
230 * @param [in] cmd_name The command name
231 * @return The command result
232 * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
234 virtual DeviceData command_inout(const char *cmd_name) {string str(cmd_name);return command_inout(str);}
236 * Execute a command (with input data)
238 * Execute a command on a device. Input arguments are passed in a DeviceData object, output is returned as
239 * a DeviceData object.
241 * @param [in] cmd_name The command name
242 * @param [in] d_in Command input data
243 * @return The command result
244 * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
246 virtual DeviceData command_inout(string &cmd_name, DeviceData &d_in);
248 * Execute a command (with input data)
250 * Execute a command on a device. Input arguments are passed in a DeviceData object, output is returned as
251 * a DeviceData object.
253 * @param [in] cmd_name The command name
254 * @param [in] d_in Command input data
255 * @return The command result
256 * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
258 virtual DeviceData command_inout(const char *cmd_name,DeviceData &d_in) {string str(cmd_name);return command_inout(str,d_in);}
259 //@}
261 /** @name Aynchronous command oriented methods */
262 //@{
264 * Execute a command asynchronously (with input argument)
266 * Execute asynchronously (polling model) a command on a device. Input arguments are passed in a DeviceData
267 * object (see following chapters on how to insert data into DeviceData object). The last argument
268 * is a fire and forget flag. If this flag is set to true, this means that the client does not care at all about the
269 * server answer and will even not try to get it. A false default value is provided. Please, note that device
270 * re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an
271 * application using only fire and forget requests is not able to automatically re-connnect to device. This call
272 * returns an asynchronous call identifier which is needed to get the command result.
274 * @param [in] cmd_name The command name
275 * @param [in] argin Command input data
276 * @param [in] forget Fire and forget flag
277 * @return The call identifier
278 * @throws ConnectionFailed
280 virtual long command_inout_asynch(const char *cmd_name,DeviceData &argin,bool forget=false);
282 * Execute a command asynchronously (with input argument)
284 * Execute asynchronously (polling model) a command on a device. Input arguments are passed in a DeviceData
285 * object (see following chapters on how to insert data into DeviceData object). The last argument
286 * is a fire and forget flag. If this flag is set to true, this means that the client does not care at all about the
287 * server answer and will even not try to get it. A false default value is provided. Please, note that device
288 * re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an
289 * application using only fire and forget requests is not able to automatically re-connnect to device. This call
290 * returns an asynchronous call identifier which is needed to get the command result.
292 * @param [in] cmd_name The command name
293 * @param [in] argin Command input data
294 * @param [in] forget Fire and forget flag
295 * @return The call identifier
296 * @throws ConnectionFailed
298 virtual long command_inout_asynch(string &cmd_name,DeviceData &argin,bool forget=false);
300 * Execute a command asynchronously
302 * Execute asynchronously (polling model) a command on a device which takes no input argument. The last
303 * argument is a fire and forget flag. If this flag is set to true, this means that the client does not care at all
304 * about the server answer and will even not try to get it. A false default value is provided. Please, note that
305 * device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore,
306 * an application using only fire and forget requests is not able to automatically re-connnect to device. This
307 * call returns an asynchronous call identifier which is needed to get the command result.
309 * @param [in] cmd_name The command name
310 * @param [in] forget Fire and forget flag
311 * @return The call identifier
312 * @throws ConnectionFailed
314 virtual long command_inout_asynch(const char *cmd_name,bool forget=false);
316 * Execute a command asynchronously
318 * Execute asynchronously (polling model) a command on a device which takes no input argument. The last
319 * argument is a fire and forget flag. If this flag is set to true, this means that the client does not care at all
320 * about the server answer and will even not try to get it. A false default value is provided. Please, note that
321 * device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore,
322 * an application using only fire and forget requests is not able to automatically re-connnect to device. This
323 * call returns an asynchronous call identifier which is needed to get the command result.
325 * @param [in] cmd_name The command name
326 * @param [in] forget Fire and forget flag
327 * @return The call identifier
328 * @throws ConnectionFailed
330 virtual long command_inout_asynch(string &cmd_name,bool forget=false);
332 * Check an asynchronous command_inout answer is arrived
334 * Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous
335 * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData
336 * object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the
337 * reply is not yet arrived. Example :
338 * @code
339 * Tango::DeviceProxy dev("...");
340 * long asyn_id;
341 * asyn_id = dev.command_inout_asynch("MyCmd");
342 * ...
343 * ...
344 * ...
345 * Tango::DeviceData arg;
346 * try
348 * arg = dev.command_inout_reply(asyn_id);
350 * catch(Tango::AsynReplyNotArrived)
352 * cerr << "Command not arrived !" << endl;
354 * catch (Tango::DevFailed &e)
356 * Tango::Except::print_exception(e);
358 * @endcode
360 * @param [in] id The call identifier
361 * @return The command result
362 * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device
364 virtual DeviceData command_inout_reply(long id);
366 * Check an asynchronous command_inout answer is arrived with timeout
368 * Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous
369 * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData
370 * object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will
371 * wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still
372 * not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived.
374 * @param [in] id The call identifier
375 8 @param [in] timeout The timeout value
376 * @return The command result
377 * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device
379 virtual DeviceData command_inout_reply(long id,long timeout);
381 * Execute a command asynchronously with callback
383 * Execute asynchronously (callback model) a command on a device which takes no input argument. The
384 * last argument is a reference to a callback object. This callback object should be an instance of a user class
385 * inheriting from the Tango::CallBack class with the cmd_ended() method overloaded.
387 * @param [in] cmd_name The command name
388 * @param [in] cb The call-back object
389 * @throws ConnectionFailed
391 virtual void command_inout_asynch(string &cmd_name,CallBack &cb);
393 * Execute a command asynchronously with callback
395 * Execute asynchronously (callback model) a command on a device which takes no input argument. The
396 * last argument is a reference to a callback object. This callback object should be an instance of a user class
397 * inheriting from the Tango::CallBack class with the cmd_ended() method overloaded.
399 * @param [in] cmd_name The command name
400 * @param [in] cb The call-back object
401 * @throws ConnectionFailed
403 virtual void command_inout_asynch(const char *cmd_name,CallBack &cb);
405 * Execute a command asynchronously with input value and callback
407 * Execute asynchronously (callback model) a command on a device. Input arguments are passed in a DeviceData
408 * object (see following chapters on how to insert data into DeviceData object). The last argument is
409 * a reference to a callback object. This callback object should be an instance of a user class inheriting from
410 * the Tango::CallBack class with the cmd_ended() method overloaded.
412 * @param [in] cmd_name The command name
413 * @param [in] argin The command input data
414 * @param [in] cb The call-back object
415 * @throws ConnectionFailed
417 virtual void command_inout_asynch(string &cmd_name,DeviceData &argin,CallBack &cb);
419 * Execute a command asynchronously with input value and callback
421 * Execute asynchronously (callback model) a command on a device. Input arguments are passed in a DeviceData
422 * object (see following chapters on how to insert data into DeviceData object). The last argument is
423 * a reference to a callback object. This callback object should be an instance of a user class inheriting from
424 * the Tango::CallBack class with the cmd_ended() method overloaded.
426 * @param [in] cmd_name The command name
427 * @param [in] argin The command input data
428 * @param [in] cb The call-back object
429 * @throws ConnectionFailed
431 virtual void command_inout_asynch(const char *cmd_name,DeviceData &argin,CallBack &cb);
433 //@}
435 /** @name Asynchronous attribute related methods */
436 //@{
438 * Fire callback methods
440 * Fire callback methods for device asynchronous requests with already arrived replied. Returns immediately
441 * if there is no replies already arrived or if there is no asynchronous request for the device. Example :
442 * @code
443 * class MyCallBack: Tango::CallBack
445 * public:
446 * MyCallback(double d):data(d) {};
447 * virtual void cmd_ended(Tango::CmdDoneEvent *);
448 * private:
449 * double data;
450 * };
452 * void MyCallBack::cmd_ended(Tango CmdDoneEvent *cmd)
454 * if (cmd->err == true)
455 * Tango::Except::print_error_stack(cmd->errors);
456 * else
458 * short cmd_result;
459 * cmd->argout >> cmd_result;
460 * cout << "Command result = " << cmd_result << endl;
461 * cout << "Callback personal data = " << data << endl;
465 * int main(int argc, char *argv[])
467 * ....
468 * ....
469 * Tango::DeviceProxy dev("...");
470 * double my_data = ...;
471 * MyCallBack cb(my_data);
472 * ...
473 * dev.command_inout_asynch("MyCmd",cb);
474 * ...
475 * ...
476 * ...
477 * dev.get_asynch_replies();
478 * ...
479 * ...
481 * @endcode
484 virtual void get_asynch_replies();
486 * Fire callback methds with timeout
488 * Fire callback methods for device asynchronous requests (command and attributes) with already arrived
489 * replied. Wait and block the caller for timeout milliseconds if they are some device asynchronous requests
490 * which are not yet arrived. Returns immediately if there is no asynchronous request for the device. If
491 * timeout is set to 0, the call waits until all the asynchronous requests sent to the device has received a reply.
493 * @param [in] timeout The timeout value
495 virtual void get_asynch_replies(long timeout);
497 * Cancel a pending asynchronous request
499 * Cancel a pending asynchronous request. id is the asynchronous call identifier. This is a call local to the
500 * client. It simply allows the caller not to get the answer of the asynchronous request. It does not interrupt
501 * the call execution on the remote device.
503 * @param [in] id The call identifier
504 * @throws AsynCall
506 virtual void cancel_asynch_request(long id);
508 * Cancel all pending asynchronous request
510 * Cancel all pending polling asynchronous requests. This is a call local to the client. It simply allows the
511 * caller not to get the answers of the asynchronous requests. It does not interrupt the call execution on the
512 * remote devices.
515 virtual void cancel_all_polling_asynch_request();
516 //@}
518 ///@privatesection
519 virtual string dev_name()=0;
521 Connection(CORBA::ORB *orb = NULL);
522 Connection(bool dummy);
523 virtual ~Connection();
524 Connection(const Connection &);
525 Connection & operator=(const Connection &);
527 string &get_db_host() {return db_host;}
528 string &get_db_port() {return db_port;}
529 int get_db_port_num() {return db_port_num;}
530 bool get_from_env_var() {return from_env_var;}
531 static void get_fqdn(string &);
533 bool is_dbase_used() {return dbase_used;}
534 string &get_dev_host() {return host;}
535 string &get_dev_port() {return port;}
537 void connect(string &name);
538 virtual void reconnect(bool);
539 bool is_connected();
541 Tango::Device_var &get_device() {return device;} // For CORBA expert !!
542 Tango::Device_4_ptr get_device_4() {return Device_4::_duplicate(device_4);}
543 Tango::Device_5_ptr get_device_5() {return Device_5::_duplicate(device_5);}
545 virtual CORBA::Any_var command_inout(string &, CORBA::Any&);
546 virtual CORBA::Any_var command_inout(const char *co, CORBA::Any &d) {string str(co);return command_inout(str,d);}
549 // Asynchronous methods
552 void Cb_Cmd_Request(CORBA::Request_ptr,Tango::CallBack *);
553 void Cb_ReadAttr_Request(CORBA::Request_ptr,Tango::CallBack *);
554 void Cb_WriteAttr_Request(CORBA::Request_ptr req,Tango::CallBack *cb_ptr);
555 void dec_asynch_counter(asyn_req_type ty);
558 // Control access related methods
561 AccessControlType get_access_control() {return access;}
562 void set_access_control(AccessControlType acc) {access=acc;}
563 AccessControlType get_access_right() {return get_access_control();}
565 friend class FwdAttribute;
567 private:
568 void omni420_timeout(int,char *);
569 DeviceData omni420_except(int,char *,TgRequest &);
570 void toIOR(const char*,IOP::IOR&);
574 #endif /* _CONNECTION_H */