OpcUaCanOpen
CANopen OPC-UA server
CanPDOItem.cpp
Go to the documentation of this file.
1 #include "CanPDOItem.h"
2 #include "CanOpenObject.h"
3 #include "CanOpenData.h"
4 #include "CanPDOObject.h"
5 
6 namespace CanOpen
7 {
8  CanPDOItem::CanPDOItem(pUserDeviceStruct *parent, PDOITEM *conf, UaNode *pAS, OpcUa_UInt32 code)
9  : CanOpenItem(parent, conf, pAS, code)
10  {
11  UaDataValue udt;
12  UaVariant val;
13  UaDateTime sdt = UaDateTime::now();
14  m_startByte = conf->byteindex();
15  m_numBit = conf->bit();
16  m_Index = 0;
17  CanOpenDataAddress::getOpcUaType(conf->type().data(), itemType);
18 
20 
21  switch (getItemType()) {
22  case OpcUaType_Boolean:
23  val.setBool(false);
24  break;
25  case OpcUaType_Byte:
26  val.setByte(0);
27  break;
28  case OpcUaType_Int16:
29  val.setInt16(0);
30  break;
31  case OpcUaType_UInt16:
32  val.setUInt16(0);
33  break;
34  case OpcUaType_Int32:
35  val.setInt32(0);
36  break;
37  case OpcUaType_UInt32:
38  val.setUInt32(0);
39  break;
40  case OpcUaType_Int64:
41  val.setInt64(0);
42  break;
43  case OpcUaType_UInt64:
44  val.setUInt64(0);
45  break;
46  case OpcUaType_Float:
47  val.setFloat(0.0);
48  break;
49  case OpcUaType_Double:
50  val.setDouble(0.0);
51  break;
52 
53  default:
54  val.setUInt32(0);
55  break;
56  }
57 
58  udt.setDataValue(val, OpcUa_False, OpcUa_Good, sdt, sdt);
59  ((OpcUa::BaseDataVariableType *)pAS)->setValue(0, udt, OpcUa_False);
60  }
61  else
62  {
63  val.setStatusCode(OpcUa_BadWaitingForInitialData);
64  udt.setDataValue(val, OpcUa_False, OpcUa_Good, sdt, sdt);
65  ((OpcUa::BaseDataVariableType *)pAS)->setValue(0, udt, OpcUa_False);
66  }
67  }
68 
70  CanPDOObject *in = static_cast<CanPDOObject*>(getParentDevice());
71  return in;
72  }
73 
74  UaStatus CanPDOItem::write(UaDataValue &udv)
75  {
76  pack(udv.value());
78  }
79 
84  UaStatus CanPDOItem::pack(const OpcUa_Variant *sData)
85  {
86  UaStatus ret;
87  OpcUa_Byte index;
88  index = getIndex();
89 
90  OpcUa_Variant convData;
91  UaStatus compatible = convertOpcUaType(sData, &convData, getItemType());
92  if (compatible.isBad())
93  {
94 
95  UaString sDiag = "Not compatible Data Types";
96  ret.setStatus(OpcUa_BadDataEncodingUnsupported, sDiag);
97  return ret;
98  }
99 
100  UaByteArray& m_buffer = getCanPDOObject()->getBuffer(index);
101  switch (getItemType()) {
102  case OpcUaType_Boolean:
103  {
104 
105  OpcUa_Byte t = 1 << getBit();
106  if (convData.Value.Boolean)
107  m_buffer[getStartByte()] = m_buffer[getStartByte()] | t;
108  else {
109  t = ~t;
110  m_buffer[getStartByte()] = m_buffer[getStartByte()] & t;
111  }
112  }
113  break;
114  case OpcUaType_Byte:
115 
116 
117  m_buffer[getStartByte()] = convData.Value.Byte;
118  break;
119  case OpcUaType_Int16:
120  case OpcUaType_UInt16:
121  {
122  union {
123  unsigned char temp[2];
124  unsigned short dtemp;
125  } dt;
126 
127  dt.dtemp = convData.Value.UInt16;
128  m_buffer[getStartByte()+1] = dt.temp[1];
129  m_buffer[getStartByte()] = dt.temp[0];
130  }
131  break;
132  case OpcUaType_Int32:
133  {
134  union {
135  unsigned char temp[4];
136  int dtemp;
137  } dt;
138  dt.dtemp = convData.Value.Int32;
139 
140  m_buffer[getStartByte() + 3] = dt.temp[3];
141  m_buffer[getStartByte() + 2] = dt.temp[2];
142  m_buffer[getStartByte() + 1] = dt.temp[1];
143  m_buffer[getStartByte()] = dt.temp[0];
144  break;
145  }
146  case OpcUaType_UInt32:
147  {
148  union {
149  unsigned char temp[4];
150  unsigned int dtemp;
151  } dt;
152  dt.dtemp = convData.Value.UInt32;
153 
154  m_buffer[getStartByte() + 3] = dt.temp[3];
155  m_buffer[getStartByte() + 2] = dt.temp[2];
156  m_buffer[getStartByte() + 1] = dt.temp[1];
157  m_buffer[getStartByte()] = dt.temp[0];
158  break;
159  }
160  case OpcUaType_Float:
161  {
162  union {
163  unsigned char temp[4];
164  float dtemp;
165  } dt;
166  dt.dtemp = convData.Value.Float;
167 
168  m_buffer[getStartByte() + 3] = dt.temp[3];
169  m_buffer[getStartByte() + 2] = dt.temp[2];
170  m_buffer[getStartByte() + 1] = dt.temp[1];
171  m_buffer[getStartByte()] = dt.temp[0];
172  break;
173  }
174  case OpcUaType_Double:
175  {
176  union {
177  unsigned char temp[8];
178  double dtemp;
179  } dt;
180 
181  dt.dtemp = convData.Value.Double;
182  m_buffer[7] = dt.temp[7];
183  m_buffer[6] = dt.temp[6];
184  m_buffer[5] = dt.temp[5];
185  m_buffer[4] = dt.temp[4];
186  m_buffer[3] = dt.temp[3];
187  m_buffer[2] = dt.temp[2];
188  m_buffer[1] = dt.temp[1];
189  m_buffer[0] = dt.temp[0];
190  break;
191  }
192 
193  case OpcUaType_ByteString:
194  {
195 
196  m_buffer[7] = sData->Value.ByteString.Data[7];
197  m_buffer[6] = sData->Value.ByteString.Data[6];
198  m_buffer[5] = sData->Value.ByteString.Data[5];
199  m_buffer[4] = sData->Value.ByteString.Data[4];
200  m_buffer[3] = sData->Value.ByteString.Data[3];
201  m_buffer[2] = sData->Value.ByteString.Data[2];
202  m_buffer[1] = sData->Value.ByteString.Data[1];
203  m_buffer[0] = sData->Value.ByteString.Data[0];
204  break;
205  }
206 
207  default:
208  return OpcUa_Bad;
209  }
210  /*
211  if (m_numch) {
212  m_pdoBuffer[index] = m_buffer;
213  }
214  */
215  return OpcUa_Good;
216  }
217 
218  UaVariant CanPDOItem::UnPack()
219  {
220  UaVariant newValue;
221  newValue.clear();
222 
223  UaByteArray &m_buffer = getCanPDOObject()->m_buffer;
224  OpcUa_Byte sByte = getStartByte();
225  switch (getItemType()) {
226  case OpcUaType_Boolean:
227  {
228  OpcUa_Byte t = 1 << getBit();
229  newValue.setBool((m_buffer[sByte] & t) != 0 );
230  break;
231  }
232  case OpcUaType_Byte:
233  {
234  newValue.setByte(m_buffer[sByte]);
235  break;
236  }
237  case OpcUaType_UInt16:
238  {
239  unsigned short ushortTemp = (unsigned char)m_buffer[sByte+1];
240  ushortTemp = ( ushortTemp << 8 ) + (unsigned char)m_buffer[sByte];
241  newValue.setUInt16(ushortTemp);
242  break;
243  }
244  case OpcUaType_UInt32:
245  {
246  unsigned int uintTemp = (unsigned char)m_buffer[sByte+3];
247  uintTemp = ((((( uintTemp << 8 ) + (unsigned char)m_buffer[sByte+2]) << 8) + (unsigned char)m_buffer[sByte+1]) << 8) + (unsigned char)m_buffer[sByte];
248  newValue.setUInt32(uintTemp);
249  break;
250  }
251  case OpcUaType_Float:
252  {
253  union {
254  unsigned int temp;
255  float dtemp;
256  } dt;
257  dt.temp = (unsigned char)m_buffer[sByte+3];
258  dt.temp = ((((( dt.temp << 8 ) + (unsigned char)m_buffer[sByte+2]) << 8) + (unsigned char)m_buffer[sByte+1]) << 8) + (unsigned char)m_buffer[sByte];
259  newValue.setFloat(dt.dtemp);
260 
261  }
262  break;
263  case OpcUaType_Double:
264  {
265  union {
266  unsigned long temp;
267  float dtemp;
268  } dt;
269  dt.dtemp = (unsigned char)m_buffer[7];
270  dt.temp = ((((( dt.temp << 8 ) + (unsigned char)m_buffer[6]) << 8) + (unsigned char)m_buffer[5]) << 8) + (unsigned char)m_buffer[4]+
271  (unsigned char)m_buffer[3]+(unsigned char)m_buffer[2]+(unsigned char)m_buffer[1]+(unsigned char)m_buffer[0];
272  newValue.setDouble(dt.dtemp);
273  }
274  break;
275  case OpcUaType_Int16:
276  {
277  unsigned short shortTemp = (unsigned char)m_buffer[sByte+1];
278  shortTemp = ( shortTemp << 8 ) + (unsigned char)m_buffer[sByte];
279  newValue.setInt16((OpcUa_Int16)shortTemp);
280  break;
281  }
282  case OpcUaType_Int32:
283  {
284  unsigned int intTemp = (unsigned char)m_buffer[sByte+3];
285  intTemp = ((((( intTemp << 8 ) + (unsigned char)m_buffer[sByte+2]) << 8) + (unsigned char)m_buffer[sByte+1]) << 8) + (unsigned char)m_buffer[sByte];
286  newValue.setInt32((OpcUa_Int32)intTemp);
287  break;
288  }
289  /*
290  case OpcUaType_ByteString:
291  {
292  UaByteString tmp;
293  tmp.setByteString(4,(OpcUa_Byte *)(m_buffer.c_data()+sByte));
294  newValue.setByteString(tmp,false);
295  break;
296  }
297  */
298  default:
299  break;
300  };
301 
302  return newValue;
303  }
304 
306  {
307  UaDataValue dataValue;
308  UaDateTime sdt;
309  UaStatus Status = OpcUa_Bad;
310 
311  sdt = UaDateTime::now();
312 
313  UaVariant val = UnPack();
314 
315  dataValue.setDataValue(val, OpcUa_True, OpcUa_Good, getCanPDOObject()->m_udt,sdt);
316  OpcUa::BaseDataVariableType *uaentry = getUaEntry();
317  if (uaentry)
318  Status = uaentry->setValue(NULL, dataValue, OpcUa_False);
319  }
320 
321  UaStatus CanPDOItem::connectCode(OpcUa_UInt32 code, ::xsd::cxx::tree::type *conf, UaNode *blink)
322  {
323  OpcUa_ReferenceParameter(conf);
324  OpcUa_ReferenceParameter(code);
325  OpcUa_ReferenceParameter(blink);
326  // UaDataValue udt;
327  // UaVariant val;
328  // UaDateTime sdt = UaDateTime::now();
329  //PDOITEM *pdoi = (PDOITEM *)conf;
330 
331  //switch (code) {
332  //case BA_PDOITEM_BIT:
333  // val.setByte(pdoi->bit());
334  // udt.setDataValue(val, OpcUa_False, OpcUa_Good, sdt, sdt);
335  // ((OpcUa::BaseDataVariableType *)blink)->setValue(0, udt, OpcUa_False);
336  // break;
337  //case BA_PDOITEM_BYTEINDEX:
338  //{
339  // val.setByte(pdoi->byteindex());
340  // udt.setDataValue(val, OpcUa_False, OpcUa_Good, sdt, sdt);
341  // ((OpcUa::BaseDataVariableType *)blink)->setValue(0, udt, OpcUa_False);
342  //}
343  //break;
344  //default: return OpcUa_Bad;
345  //}
346 
347  std::cout << "Empty list of children\n" << endl;
348  return OpcUa_Good;
349  }
350 
351  UaVariant CanPDOItem::getPropertyValue(OpcUa_UInt32 code, ::xsd::cxx::tree::type *conf)
352  {
353  PDOITEM *pdoi = (PDOITEM *)conf;
354  UaVariant val;
355  val.clear();
356  switch (code) {
357  case BA_PDOITEM_BIT:
358  val.setByte(pdoi->bit());
359  break;
361  {
362  val.setByte(pdoi->byteindex());
363  }
364  break;
365  }
366  return val;
367  }
368 
369 }