release
[tango-nonfree.git] / lib / cpp / server / device_3.tpp
blobfdc13359b1bc5ba66d2a9aca6757de0067acf68c
1 //===================================================================================================================
2 //
3 // file :               device_3.tpp
4 //
5 // description :        C++ source code for the Device_3Impl class template methods
6 //
7 // project :            TANGO
8 //
9 // author(s) :          E.Taurel
11 // Copyright (C) :      2011,2012,2013,2014,2015
12 //                                              European Synchrotron Radiation Facility
13 //                      BP 220, Grenoble 38043
14 //                      FRANCE
16 // This file is part of Tango.
18 // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
19 // License as published by the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
22 // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
23 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 // GNU Lesser General Public License for more details.
26 // You should have received a copy of the GNU Lesser General Public License along with Tango.
27 // If not, see <http://www.gnu.org/licenses/>.
29 // $Revision$
31 //==================================================================================================================
33 #ifndef _DEVICE_3_TPP
34 #define _DEVICE_3_TPP
36 namespace Tango
39 //+---------------------------------------------------------------------------------------------------------------
41 // method :
42 //              Device_3Impl::set_attribute_config_3_local
44 // description :
45 //              Set attribute configuration for both AttributeConfig_3 and AttributeConfig_5
47 // args :
48 //              in :
49 //                      - new_conf : The new attribute configuration
50 //                      - dummy_arg : Dummy and unnused arg. Just to help template coding
51 //                      - fwd_cb : Set to true if called from fwd att call back
52 //                      - caller_idl : IDL release used by caller
54 //----------------------------------------------------------------------------------------------------------------
56 template <typename T,typename V>
57 void Device_3Impl::set_attribute_config_3_local(const T &new_conf,TANGO_UNUSED(const V &dummy_arg),
58                                                                                                 bool fwd_cb,int caller_idl)
60         cout4 << "Entering Device_3Impl::set_attribute_config_3_local" << endl;
63 // Return exception if the device does not have any attribute
66         long nb_dev_attr = dev_attr->get_attr_nb();
67         if (nb_dev_attr == 0)
68         {
69                 Except::throw_exception((const char *)API_AttrNotFound,
70                                         (const char *)"The device does not have any attribute",
71                                         (const char *)"Device_3Impl::set_attribute_config_3_local");
72         }
75 // Get some event related data
78         EventSupplier *event_supplier_nd = NULL;
79         EventSupplier *event_supplier_zmq = NULL;
81         Tango::Util *tg = Tango::Util::instance();
84 // Update attribute config first locally then in database
87         long nb_attr = new_conf.length();
88         long i;
90     EventSupplier::SuppliedEventData ad;
91     ::memset(&ad,0,sizeof(ad));
93         try
94         {
95                 for (i = 0;i < nb_attr;i++)
96                 {
97                         Attribute &attr = dev_attr->get_attr_by_name(new_conf[i].name);
98                         bool old_alarm = attr.is_alarmed().any();
101 // Special case for forwarded attributes
104                         if (attr.is_fwd_att() == true)
105                         {
106                                 FwdAttribute &fwd_attr = static_cast<FwdAttribute &>(attr);
107                                 if (fwd_cb == true)
108                                         fwd_attr.set_att_config(new_conf[i]);
109                                 else
110                                 {
111                                         fwd_attr.upd_att_config_base(new_conf[i].label.in());
112                                         fwd_attr.upd_att_config(new_conf[i]);
113                                 }
114                         }
115                         else
116                         {
117                                 attr.set_upd_properties(new_conf[i],device_name);
118                         }
121 // In case the attribute quality factor was set to ALARM, reset it to VALID
124                         if ((attr.get_quality() == Tango::ATTR_ALARM) &&
125                                 (old_alarm == true) &&
126                                 (attr.is_alarmed().any() == false))
127                                 attr.set_quality(Tango::ATTR_VALID);
130 // Send the event
133                         if (attr.use_notifd_event() == true)
134                                 event_supplier_nd = tg->get_notifd_event_supplier();
135                         else
136                                 event_supplier_nd = NULL;
138                         if (attr.use_zmq_event() == true)
139                                 event_supplier_zmq = tg->get_zmq_event_supplier();
140                         else
141                                 event_supplier_zmq = NULL;
143                         if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL))
144                         {
145                                 string tmp_name(new_conf[i].name);
148 // The event data has to be the new attribute conf which could be different than the one we received (in case some
149 // of the parameters are reset to lib/user/class default value)
152                                 V mod_conf;
153                                 attr.get_prop(mod_conf);
155                                 const V *tmp_ptr = &mod_conf;
157                                 Tango::AttributeConfig_3 conf3;
158                                 Tango::AttributeConfig_5 conf5;
159                                 AttributeConfig_3 *tmp_conf_ptr;
160                                 AttributeConfig_5 *tmp_conf_ptr5;
162                                 if (get_dev_idl_version() > 4)
163                                 {
164                                         vector<int> cl_lib = attr.get_client_lib(ATTR_CONF_EVENT);
166                                         if (caller_idl <= 4)
167                                         {
170 // Even if device is IDL 5, the change has been done from one old client (IDL4) thus with AttributeConfig_3.
171 // If a new client is listening to event, don't forget to send it.
174                                                 for (size_t i = 0;i < cl_lib.size();i++)
175                                                 {
176                                                         if (cl_lib[i] == 5)
177                                                         {
178                                                                 attr.AttributeConfig_3_2_AttributeConfig_5(mod_conf,conf5);
179                                                                 attr.add_config_5_specific(conf5);
180                                                                 tmp_conf_ptr5 = &conf5;
182                                                                 ::memcpy(&(ad.attr_conf_5),&(tmp_conf_ptr5),sizeof(V *));
183                                                         }
184                                                         else
185                                                         {
186                                                                 ::memcpy(&(ad.attr_conf_3),&(tmp_ptr),sizeof(V *));
187                                                         }
189                                                         if (event_supplier_nd != NULL)
190                                                                 event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
191                                                         if (event_supplier_zmq != NULL)
192                                                                 event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
194                                                         if (cl_lib[i] == 5)
195                                                                 ad.attr_conf_5 = NULL;
196                                                         else
197                                                                 ad.attr_conf_3 = NULL;
198                                                 }
199                                         }
200                                         else
201                                         {
202                                                 for (size_t i = 0;i < cl_lib.size();i++)
203                                                 {
204                                                         if (cl_lib[i] < 5)
205                                                         {
206                                                                 attr.AttributeConfig_5_2_AttributeConfig_3(mod_conf,conf3);
207                                                                 tmp_conf_ptr = &conf3;
209                                                                 ::memcpy(&(ad.attr_conf_3),&(tmp_conf_ptr),sizeof(V *));
210                                                         }
211                                                         else
212                                                         {
213                                                                 ::memcpy(&(ad.attr_conf_5),&(tmp_ptr),sizeof(V *));
214                                                         }
216                                                         if (event_supplier_nd != NULL)
217                                                                 event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
218                                                         if (event_supplier_zmq != NULL)
219                                                                 event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
221                                                         if (cl_lib[i] == 5)
222                                                                 ad.attr_conf_5 = NULL;
223                                                         else
224                                                                 ad.attr_conf_3 = NULL;
225                                                 }
226                                         }
227                                 }
228                                 else
229                                 {
230                                         ::memcpy(&(ad.attr_conf_3),&(tmp_ptr),sizeof(V *));
232                                         if (event_supplier_nd != NULL)
233                                                 event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
234                                         if (event_supplier_zmq != NULL)
235                                                 event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name);
236                                 }
237                         }
238                 }
240         }
241         catch (Tango::DevFailed &e)
242         {
245 // Re build the list of "alarmable" attribute
248                 dev_attr->get_alarm_list().clear();
249                 for (long j = 0;j < nb_dev_attr;j++)
250                 {
251                         Attribute &att = dev_attr->get_attr_by_ind(j);
252                         if (att.is_alarmed().any() == true)
253                         {
254                                 if (att.get_writable() != Tango::WRITE)
255                                         dev_attr->get_alarm_list().push_back(j);
256                         }
257                 }
260 // Change the exception reason flag
263                 TangoSys_OMemStream o;
265                 o << e.errors[0].reason;
266                 if (i != 0)
267                         o << "\nAll previous attribute(s) have been successfully updated";
268                 if (i != (nb_attr - 1))
269                         o << "\nAll remaining attribute(s) have not been updated";
270                 o << ends;
272                 string s = o.str();
273                 e.errors[0].reason = CORBA::string_dup(s.c_str());
274                 throw;
275         }
278 // Re build the list of "alarmable" attribute
281         dev_attr->get_alarm_list().clear();
282         for (i = 0;i < nb_dev_attr;i++)
283         {
284                 Tango::Attribute &attr = dev_attr->get_attr_by_ind(i);
285                 Tango::AttrWriteType w_type = attr.get_writable();
286                 if (attr.is_alarmed().any() == true)
287                 {
288                         if (w_type != Tango::WRITE)
289                                 dev_attr->get_alarm_list().push_back(i);
290                 }
291         }
294 // Return to caller
297         cout4 << "Leaving Device_3Impl::set_attribute_config_3_local" << endl;
300 template <typename T>
301 inline void Device_3Impl::error_from_devfailed(T &back,DevFailed &e,const char *na)
303         back.err_list = e.errors;
304         back.quality = ATTR_INVALID;
305         back.name = CORBA::string_dup(na);
306         clear_att_dim(back);
309 template <typename T>
310 inline void Device_3Impl::error_from_errorlist(T &back,DevErrorList &e,const char *na)
312         back.err_list = e;
313         back.quality = ATTR_INVALID;
314         back.name = CORBA::string_dup(na);
315         clear_att_dim(back);
318 template <typename T>
319 inline void Device_3Impl::one_error(T &back,const char *reas,const char *ori,string &mess,Attribute &att)
321         back.err_list.length(1);
323         back.err_list[0].severity = Tango::ERR;
324         back.err_list[0].reason = CORBA::string_dup(reas);
325         back.err_list[0].origin = CORBA::string_dup(ori);
326         back.err_list[0].desc = CORBA::string_dup(mess.c_str());
328         back.quality = Tango::ATTR_INVALID;
329         back.name = CORBA::string_dup(att.get_name().c_str());
330         clear_att_dim(back);
333 template <typename T>
334 inline void Device_3Impl::one_error(T &back,const char *reas,const char *ori,string &mess,const char *na)
336         back.err_list.length(1);
338         back.err_list[0].severity = Tango::ERR;
339         back.err_list[0].reason = CORBA::string_dup(reas);
340         back.err_list[0].origin = CORBA::string_dup(ori);
341         back.err_list[0].desc = CORBA::string_dup(mess.c_str());
343         back.quality = Tango::ATTR_INVALID;
344         back.name = CORBA::string_dup(na);
345         clear_att_dim(back);
348 template <typename T,typename V>
349 inline void Device_3Impl::init_polled_out_data(T &back,V &att_val)
351         back.quality = att_val.quality;
352         back.time = att_val.time;
353         back.r_dim = att_val.r_dim;
354         back.w_dim = att_val.w_dim;
355         back.name = CORBA::string_dup(att_val.name);
358 template <typename T>
359 inline void Device_3Impl::init_out_data(T &back,Attribute &att,AttrWriteType &w_type)
361         back.time = att.get_when();
362         back.quality = att.get_quality();
363         back.name = CORBA::string_dup(att.get_name().c_str());
364         back.r_dim.dim_x = att.get_x();
365         back.r_dim.dim_y = att.get_y();
366         if ((w_type == Tango::READ_WRITE) ||
367                 (w_type == Tango::READ_WITH_WRITE))
368         {
369                 WAttribute &assoc_att = dev_attr->get_w_attr_by_ind(att.get_assoc_ind());
370                 back.w_dim.dim_x = assoc_att.get_w_dim_x();
371                 back.w_dim.dim_y = assoc_att.get_w_dim_y();
372         }
373         else
374         {
375                 if ( w_type == Tango::WRITE)
376                 {
377                         // for write only attributes read and set value are the same!
378                         back.w_dim.dim_x = att.get_x();
379                         back.w_dim.dim_y = att.get_y();
380                 }
381                 else
382                 {
383                         // Tango::Read : read only attributes
384                         back.w_dim.dim_x = 0;
385                         back.w_dim.dim_y = 0;
386                 }
387         }
390 template <typename T>
391 inline void Device_3Impl::init_out_data_quality(T &back,Attribute &att,AttrQuality qual)
393         back.time = att.get_when();
394         back.quality = qual;
395         back.name = CORBA::string_dup(att.get_name().c_str());
396         back.r_dim.dim_x = att.get_x();
397         back.r_dim.dim_y = att.get_y();
398         back.r_dim.dim_x = 0;
399         back.r_dim.dim_y = 0;
400         back.w_dim.dim_x = 0;
401         back.w_dim.dim_y = 0;
404 template <typename T>
405 inline void Device_3Impl::base_state2attr(T &back)
408 #ifdef _TG_WINDOWS_
409         struct _timeb after_win;
411         _ftime(&after_win);
412         back.time.tv_sec = (long)after_win.time;
413         back.time.tv_usec = (long)after_win.millitm * 1000;
414         back.time.tv_nsec = 0;
415 #else
416         struct timeval after;
418         gettimeofday(&after,NULL);
419         back.time.tv_sec = after.tv_sec;
420         back.time.tv_usec = after.tv_usec;
421         back.time.tv_nsec = 0;
422 #endif
423         back.quality = Tango::ATTR_VALID;
424         back.name = CORBA::string_dup("State");
425         back.r_dim.dim_x = 1;
426         back.r_dim.dim_y = 0;
427         back.w_dim.dim_x = 0;
428         back.w_dim.dim_y = 0;
431 template <typename T>
432 inline void Device_3Impl::base_status2attr(T &back)
435 #ifdef _TG_WINDOWS_
436         struct _timeb after_win;
438         _ftime(&after_win);
439         back.time.tv_sec = (long)after_win.time;
440         back.time.tv_usec = (long)after_win.millitm * 1000;
441         back.time.tv_nsec = 0;
442 #else
443         struct timeval after;
445         gettimeofday(&after,NULL);
446         back.time.tv_sec = after.tv_sec;
447         back.time.tv_usec = after.tv_usec;
448         back.time.tv_nsec = 0;
449 #endif
450         back.quality = Tango::ATTR_VALID;
451         back.name = CORBA::string_dup("Status");
452         back.r_dim.dim_x = 1;
453         back.r_dim.dim_y = 0;
454         back.w_dim.dim_x = 0;
455         back.w_dim.dim_y = 0;
458 } // End of Tango namespace
460 #endif /* DEVICE_3_TPP */