OpcUaCanOpen
CANopen OPC-UA server
CanPDOObject.cpp
Go to the documentation of this file.
1 #include <opcua_basedatavariabletype.h>
2 #include "uabasenodes.h"
3 #include "CanBusObject.h"
4 #include "CanNodeObject.h"
5 #include "CanPDOObject.h"
6 #include "CanPDOItem.h"
7 #include <uadatetime.h>
8 #include <boost/lexical_cast.hpp>
9 
10 namespace CanOpen
11 {
12  using boost::lexical_cast;
13  using boost::bad_lexical_cast;
21  PDO *conf, UaNode *blink,OpcUa_UInt32 code) :
22  CanOpenObject(par,conf,blink,code)
23  {
24  char *p;
25  m_cobId = (OpcUa_UInt16)strtol(conf->cobid().data(),&p,16);
26  const char *rtrvalue = conf->rtr().c_str();
27 
28 
29  m_bInitRTR = (strcmp(rtrvalue,"init") == 0);
30 
31  m_buffer.resize(8);
32  for( int i = 0; i < 8; i++)
33  m_buffer[i] = 0;
34  OpcUa_UInt32 m_numch = conf->numch();
35  m_pdoBuffer.resize(m_numch+1,m_buffer);
37 
38  m_iCount = 0;
39  m_iMaxCount = (m_numch == 0) ? 1 : m_numch; // maximum channel for PDO object (ELMB)
40  };
41 
42 
48  void CanPDOObject::setItem(OpcUa_Byte ch,CanPDOItem *pdoi)
49  {
50  m_cPDOs.insert(pair<OpcUa_Byte,CanPDOItem *>(ch,pdoi));
51  pdoi->setIndex(ch);
52  }
53 
59  {
60  OpcUa_Byte selByte;
61  if ((m_iMaxCount > 1) && (m_iMaxCount < cms->c_data[0]))
62  return;
63 
64  for(int i = 0; i < cms->c_dlc; i++) // copy to buffer
65  m_buffer[i] = cms->c_data[i];
66 
67  selByte = cms->c_data[0];
68 
69  if (m_iMaxCount > 1)
70  m_pdoBuffer[selByte] = m_buffer; // copy to channel cache
71  m_udt = UaDateTime::fromTime_t(cms->c_time.tv_sec);
72  m_udt.addMilliSecs(cms->c_time.tv_usec/1000); // convert time stamp to ua format
73 
74  typedef multimap<OpcUa_Byte,CanPDOItem *>::iterator m_iter;
75  pair<m_iter,m_iter> selec;
76  if (m_iMaxCount > 1) { // find all item for this PDO object
77  selec = m_cPDOs.equal_range(selByte);
78  }
79  else
80  selec = m_cPDOs.equal_range(0);
81 
82  m_iter it;
83 
84  for (it = selec.first; it != selec.second; ++it)
85  {
86  CanPDOItem *ucpdo = ((*it).second);
87  ucpdo->setItemValue(); // extract date from PDO object to item
88  }
89 
90  messageCame();
91  }
92 
94  {
95  CCanAccess *b = getCanBus();
96  if (b) {
97  if (m_bInitRTR) {
99  }
100  }
101  }
102 
106  UaStatus CanPDOObject::sendDeviceMessage(OpcUa_UInt32 code, UaDataValue *value)
107  {
108  OpcUa_ReferenceParameter(value);
109  CCanAccess *b = getCanBus();
110  if (b) {
111  lock();
112  if (code == BA_PDOOBJECT_RTR_COMMAND || code == BA_PDOOBJECT_RTR)
113  {
114  sendRTR();
115  unlock();
116  LOG(Log::DBG, Pdo1Message) << "bus=" << getBusName() << " phase=RTR Command " << "node=" << hex << getCobId();
117  return OpcUa_Good;
118  }
119  unsigned char mes[8];
120  for (int i = 0; i < 8; i++)
121  mes[i] = m_buffer[i];
122 
123  LOG(Log::DBG, PdoMessage) << " bus=" << getBusName() << " output " << "node=" << hex << getCobId() << " len=8 " << " output " <<
124  hex << (int)mes[0] << (int)mes[1] << (int)mes[2] << (int)mes[3] << (int)mes[4] << (int)mes[5] << (int)mes[6] << (int)mes[7];
125 
126  b->sendMessage(this->getCobId(), 8, mes);
127 
128  unlock();
129  }
130  return OpcUa_Good;
131  }
132 
134  {
135  CanNodeObject *cn = static_cast<CanNodeObject *>(getParentDevice());
136  if (type)
137  m_cobId = m_cobId + cn->getCanNodeId();
138  static_cast<CanBusObject *>(cn->getParentDevice())->addPDO(this);
139  }
140 
141 
142  UaStatus CanPDOObject::connectCode(OpcUa_UInt32 code, ::xsd::cxx::tree::type *conf, UaNode *blink)
143  {
144  UaDataValue udt;
145  UaVariant val;
146  UaDateTime sdt = UaDateTime::now();
147  PDO *pdob = (PDO *)conf;
148  switch (code) {
150  if (this->getDirectionType() == CAN_IN) {
151  ((OpcUa::BaseDataVariableType *)blink)->setDataType(OpcUaType_UInt32);
152  val.setUInt32(0);
153  udt.setDataValue(val, OpcUa_False, OpcUa_Good, sdt, sdt);
154  ((OpcUa::BaseDataVariableType *)blink)->setValue(0, udt, OpcUa_False);
155  m_pRTRCommand = (OpcUa::BaseVariableType *)blink;
156  ((OpcUa::BaseDataVariableType *)blink)->setValueHandling(UaVariable_Value_Cache);
157  }
158  break;
159  }
160  return OpcUa_Good;
161  }
162 
164  {
165  UaVariant val;
166  val.clear();
167  PDO *pdob = (PDO *)conf;
168  if (code == BA_PDOOBJECT_COBID)
169  {
170  OpcUa_UInt16 cobid = boost::lexical_cast<short>(pdob->cobid().c_str());
171  val.setUInt16(cobid);
172  }
173  return val;
174  }
175 }