1 //////////////////////////////////////////////////////////////////
3 // Connection.h - include file for TANGO class Connection
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
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/>.
28 ///////////////////////////////////////////////////////////////
35 /****************************************************************************************
37 * The Connection class *
38 * -------------------- *
40 ***************************************************************************************/
43 * Base class for Tango device access
45 * Base class for Tango device access. This class is pure virtual and can be instanciated
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)
74 Tango::Device_var device
;
75 Tango::Device_2_var device_2
;
81 Tango::DevSource source
;
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();
113 ConnectionExt():has_alt_adr(false) {}
115 ConnectionExt
& operator=(const ConnectionExt
&);
120 #ifdef HAS_UNIQUE_PTR
121 unique_ptr
<ConnectionExt
> ext
;
123 ConnectionExt
*ext
; // Class extension
127 Tango::Device_3_var device_3
;
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
;
144 /**@name Miscellaneous methods */
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
);
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
;}
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();
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
;}
213 /** @name Synchronous command oriented methods */
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
);}
261 /** @name Aynchronous command oriented methods */
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 :
339 * Tango::DeviceProxy dev("...");
341 * asyn_id = dev.command_inout_asynch("MyCmd");
345 * Tango::DeviceData arg;
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);
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
);
435 /** @name Asynchronous attribute related methods */
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 :
443 * class MyCallBack: Tango::CallBack
446 * MyCallback(double d):data(d) {};
447 * virtual void cmd_ended(Tango::CmdDoneEvent *);
452 * void MyCallBack::cmd_ended(Tango CmdDoneEvent *cmd)
454 * if (cmd->err == true)
455 * Tango::Except::print_error_stack(cmd->errors);
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[])
469 * Tango::DeviceProxy dev("...");
470 * double my_data = ...;
471 * MyCallBack cb(my_data);
473 * dev.command_inout_asynch("MyCmd",cb);
477 * dev.get_asynch_replies();
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
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
515 virtual void cancel_all_polling_asynch_request();
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);
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
;
568 void omni420_timeout(int,char *);
569 DeviceData
omni420_except(int,char *,TgRequest
&);
570 void toIOR(const char*,IOP::IOR
&);
574 #endif /* _CONNECTION_H */