1 //===================================================================================================================
5 // description : C++ source code for the Device_3Impl class template methods
9 // author(s) : E.Taurel
11 // Copyright (C) : 2011,2012,2013,2014,2015
12 // European Synchrotron Radiation Facility
13 // BP 220, Grenoble 38043
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/>.
31 //==================================================================================================================
39 //+---------------------------------------------------------------------------------------------------------------
42 // Device_3Impl::set_attribute_config_3_local
45 // Set attribute configuration for both AttributeConfig_3 and AttributeConfig_5
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();
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");
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();
90 EventSupplier::SuppliedEventData ad;
91 ::memset(&ad,0,sizeof(ad));
95 for (i = 0;i < nb_attr;i++)
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)
106 FwdAttribute &fwd_attr = static_cast<FwdAttribute &>(attr);
108 fwd_attr.set_att_config(new_conf[i]);
111 fwd_attr.upd_att_config_base(new_conf[i].label.in());
112 fwd_attr.upd_att_config(new_conf[i]);
117 attr.set_upd_properties(new_conf[i],device_name);
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);
133 if (attr.use_notifd_event() == true)
134 event_supplier_nd = tg->get_notifd_event_supplier();
136 event_supplier_nd = NULL;
138 if (attr.use_zmq_event() == true)
139 event_supplier_zmq = tg->get_zmq_event_supplier();
141 event_supplier_zmq = NULL;
143 if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL))
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)
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)
164 vector<int> cl_lib = attr.get_client_lib(ATTR_CONF_EVENT);
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++)
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 *));
186 ::memcpy(&(ad.attr_conf_3),&(tmp_ptr),sizeof(V *));
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);
195 ad.attr_conf_5 = NULL;
197 ad.attr_conf_3 = NULL;
202 for (size_t i = 0;i < cl_lib.size();i++)
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 *));
213 ::memcpy(&(ad.attr_conf_5),&(tmp_ptr),sizeof(V *));
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);
222 ad.attr_conf_5 = NULL;
224 ad.attr_conf_3 = NULL;
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);
241 catch (Tango::DevFailed &e)
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++)
251 Attribute &att = dev_attr->get_attr_by_ind(j);
252 if (att.is_alarmed().any() == true)
254 if (att.get_writable() != Tango::WRITE)
255 dev_attr->get_alarm_list().push_back(j);
260 // Change the exception reason flag
263 TangoSys_OMemStream o;
265 o << e.errors[0].reason;
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";
273 e.errors[0].reason = CORBA::string_dup(s.c_str());
278 // Re build the list of "alarmable" attribute
281 dev_attr->get_alarm_list().clear();
282 for (i = 0;i < nb_dev_attr;i++)
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)
288 if (w_type != Tango::WRITE)
289 dev_attr->get_alarm_list().push_back(i);
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);
309 template <typename T>
310 inline void Device_3Impl::error_from_errorlist(T &back,DevErrorList &e,const char *na)
313 back.quality = ATTR_INVALID;
314 back.name = CORBA::string_dup(na);
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());
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);
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))
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();
375 if ( w_type == Tango::WRITE)
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();
383 // Tango::Read : read only attributes
384 back.w_dim.dim_x = 0;
385 back.w_dim.dim_y = 0;
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();
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)
409 struct _timeb 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;
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;
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)
436 struct _timeb 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;
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;
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 */