iCub-main
hostTransceiver.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 iCub Facility, Istituto Italiano di Tecnologia
3  * Author: Alberto Cardellino, Marco Accame
4  * email: alberto.cardellino@iit.it, marco.accame@iit.it
5  * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
6  *
7  */
8 
9 
10 // --------------------------------------------------------------------------------------------------------------------
11 // - macros
12 // --------------------------------------------------------------------------------------------------------------------
13 
14 #define HOSTTRANSCEIVER_USE_INTERNAL_MUTEXES
15 
16 // if this macro is defined then ethManager sends pkts even if they dont have ROPs inside
17 #undef HOSTTRANSCEIVER_EmptyROPframesAreTransmitted
18 
19 // --------------------------------------------------------------------------------------------------------------------
20 // - external dependencies
21 // --------------------------------------------------------------------------------------------------------------------
22 
23 using namespace std;
24 
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 #include "hostTransceiver.hpp"
31 #include "FeatureInterface.h"
32 
33 #include "EOYmutex.h"
34 #include "EOYtheSystem.h"
35 #include "EOtheErrorManager.h"
36 #include "EoCommon.h"
37 #include "EOnv.h"
38 #include "EOnv_hid.h"
39 #include "EOrop.h"
40 #include "EoProtocol.h"
41 
42 #include "ethManager.h"
43 #include "ethParser.h"
44 
45 #include "FeatureInterface.h"
46 
47 
48 
49 #include "EoProtocol.h"
50 #include "EoProtocolMN.h"
51 #include "EoProtocolMC.h"
52 #include "EoProtocolAS.h"
53 #include "EoProtocolSK.h"
54 
55 
56 #include <yarp/os/LogStream.h>
57 
58 #include <yarp/os/Time.h>
59 
60 using namespace eth;
61 
62 bool HostTransceiver::lock_transceiver(bool on)
63 {
64 #if !defined(HOSTTRANSCEIVER_USE_INTERNAL_MUTEXES)
65  if(on)
66  htmtx.lock();
67  else
68  htmtx.unlock();
69 #endif
70  return true;
71 }
72 
73 
74 
75 
76 bool HostTransceiver::lock_nvs(bool on)
77 {
78 #if !defined(HOSTTRANSCEIVER_USE_INTERNAL_MUTEXES)
79  if(on)
80  nvmtx.lock();
81  else
82  nvmtx.unlock();
83 #endif
84  return true;
85 }
86 
87 
88 
89 HostTransceiver::HostTransceiver():delayAfterROPloadingFailure(0.001) // 1ms
90 {
91  yTrace();
92 
93 // delayAfterROPloadingFailure = TheEthManager::instance()->getEthSender()->getPeriod();
94 
95  ipport = 0;
96  localipaddr = 0;
97  remoteipaddr = 0;
98  eo_common_ipv4addr_to_string(remoteipaddr, remoteipstring, sizeof(remoteipstring));
99  pktsizerx = 0;
100 
101  protboardnumber = eo_prot_BRDdummy;
102  p_RxPkt = NULL;
103  hosttxrx = NULL;
104  pc104txrx = NULL;
105  nvset = NULL;
106  memcpy(&hosttxrxcfg, &eo_hosttransceiver_cfg_default, sizeof(eOhosttransceiver_cfg_t));
107 
108 
109 
110  capacityofTXpacket = defMaxSizeOfTXpacket;
111  maxSizeOfROP = defMaxSizeOfROP;
112 }
113 
114 
116 {
117  if(NULL != p_RxPkt)
118  {
119  eo_packet_Delete(p_RxPkt);
120  p_RxPkt = NULL;
121  }
122  if(NULL != hosttxrx)
123  {
124  eo_hosttransceiver_Delete(hosttxrx);
125  hosttxrx = NULL;
126  }
127 
128  // pointers nvset and pc104txrx are just handles retrieved (and deallocated) by object EOhostTransceiver.
129  // thus no _Delete() method is required for them
130  nvset = NULL;
131  pc104txrx = NULL;
132 
133  yTrace();
134 }
135 
136 
137 bool HostTransceiver::init2(AbstractEthResource *owner, yarp::os::Searchable &cfgtotal, eOipv4addressing_t& localIPaddressing, eOipv4addr_t remoteIP, uint16_t rxpktsize)
138 {
139  if(NULL != hosttxrx)
140  {
141  yError() << "HostTransceiver::init(): called but ... its EOhostTransceiver is already created";
142  return false;
143  }
144 
145  if(nullptr == owner)
146  {
147  yError() << "HostTransceiver::init2(): called w/ nullptr";
148  }
149 
150 
151  _owner = owner;
152 
153  // ok. we can go on. assign values of some member variables
154 
155  uint8_t ip4 = 0;
156  eo_common_ipv4addr_to_decimal(remoteIP, NULL, NULL, NULL, &ip4);
157  protboardnumber = ip4;
158  localipaddr = localIPaddressing.addr;
159  remoteipaddr = remoteIP;
160  eo_common_ipv4addr_to_string(remoteipaddr, remoteipstring, sizeof(remoteipstring));
161  ipport = localIPaddressing.port;
162  pktsizerx = rxpktsize;
163 
164 
165  if(false == initProtocol())
166  {
167  yError() << "HostTransceiver::init() -> HostTransceiver::initProtocol() fails";
168  return false;
169  }
170 
171 
172  if(eobool_false == eoprot_board_can_be_managed(protboardnumber))
173  {
174  yError() << "HostTransceiver::init() -> the BOARD w/ IP " << remoteipstring << "cannot be managed by EOprotocol";
175  return false;
176  }
177 
178 
179 
180  if(!prepareTransceiverConfig2(cfgtotal))
181  {
182  yError() << "HostTransceiver::init() -> HostTransceiver::prepareTransceiverConfig2() fails";
183  return false;
184  }
185 
186 
187  // now hosttxrxcfg is ready, thus ...
188  // initialise the transceiver: it creates a EOhostTransceiver and its EOnvSet
189  hosttxrx = eo_hosttransceiver_New(&hosttxrxcfg);
190  if(hosttxrx == NULL)
191  { // it never returns NULL. on allocation failure it calls its error manager. however ...
192  yError() << "HostTransceiver::init(): .... eo_hosttransceiver_New() failed";
193  return false;
194  }
195 
196  // retrieve the transceiver
197  pc104txrx = eo_hosttransceiver_GetTransceiver(hosttxrx);
198  if(pc104txrx == NULL)
199  {
200  return false;
201  }
202 
203  // retrieve the nvset
204  nvset = eo_hosttransceiver_GetNVset(hosttxrx);
205  if(NULL == nvset)
206  {
207  return false;
208  }
209 
210 
211 
212  // build the packet used for reception.
213  p_RxPkt = eo_packet_New(rxpktsize);
214  if(p_RxPkt == NULL)
215  {
216  return false;
217  }
218 
219 
220  return true;
221 }
222 
224 {
225  return remoteipaddr;
226 }
227 
229 {
230  return _owner;
231 }
232 
233 
234 bool HostTransceiver::write(const eOprotID32_t id32, const void* data, bool forcewriteOfReadOnly)
235 {
236  eOresult_t eores = eores_NOK_generic;
237 
238  if(eobool_false == eoprot_id_isvalid(protboardnumber, id32))
239  {
240  char nvinfo[128];
241  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
242  yError() << "HostTransceiver::write() called w/ invalid id on BOARD /w IP" << remoteipstring <<
243  "with id: " << nvinfo;
244  return false;
245  }
246 
247  if(NULL == data)
248  {
249  yError() << "HostTransceiver::write() called w/ with NULL data";
250  return false;
251  }
252 
253 
254  EOnv nv;
255  EOnv* nv_ptr = NULL;
256 
257  nv_ptr = getnvhandler(id32, &nv);
258 
259  if(NULL == nv_ptr)
260  {
261  yError() << "HostTransceiver::write(): Unable to get pointer to desired NV with id32" << id32;
262  return false;
263  }
264 
265 
266  lock_nvs(true);
267  eores = eo_nv_Set(&nv, data, forcewriteOfReadOnly, eo_nv_upd_dontdo);
268  lock_nvs(false);
269 
270  // marco.accame on 09 apr 2014:
271  // we write data into
272  if(eores_OK != eores)
273  {
274  bool ROvariable = (eo_nv_rwmode_RO == eo_nv_GetRWmode(&nv)) ? true : false;
275  char nvinfo[128];
276  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
277  yError() << "HostTransceiver::write(): eo_nv_Set() has failed for IP" << remoteipstring << "and" << nvinfo << "RO mode = " << ((ROvariable) ? "true." : "false.");
278 
279  if((eobool_false == forcewriteOfReadOnly) && (true == ROvariable))
280  {
281  yError() << "HostTransceiver::write(): called with forcewriteOfReadOnly = false for a READ ONLY variable";
282 
283  }
284  return false;
285  }
286 
287  return true;
288 }
289 
290 
291 // if signature is eo_rop_SIGNATUREdummy (0xffffffff) we dont send the signature. if writelocalcache is true we copy data into local ram of the EOnv
292 bool HostTransceiver::addSetROP__(const eOprotID32_t id32, const void* data, const uint32_t signature, bool writelocalrxcache)
293 {
294  eOresult_t eores = eores_NOK_generic;
295  int32_t err = -1;
296  int32_t info0 = -1;
297  int32_t info1 = -1;
298  int32_t info2 = -1;
299 
300  if(eobool_false == eoprot_id_isvalid(protboardnumber, id32))
301  {
302  char nvinfo[128];
303  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
304  yError() << "HostTransceiver::addSetROP__() called w/ invalid id on BOARD /w IP" << remoteipstring <<
305  "with id: " << nvinfo;
306  return false;
307  }
308 
309  if(NULL == data)
310  {
311  yError() << "HostTransceiver::addSetROP__() called w/ with NULL data";
312  return false;
313  }
314 
315  if(true == writelocalrxcache)
316  {
317  EOnv nv;
318  EOnv* nv_ptr = NULL;
319 
320  nv_ptr = getnvhandler(id32, &nv);
321 
322  if(NULL == nv_ptr)
323  {
324  yError() << "HostTransceiver::addSetROP__(): Unable to get pointer to desired NV with id32" << id32;
325  return false;
326  }
327 
328  lock_nvs(true);
329  eores = eo_nv_Set(&nv, data, eobool_false, eo_nv_upd_dontdo);
330  lock_nvs(false);
331 
332  // marco.accame on 09 apr 2014:
333  // we write data into
334  if(eores_OK != eores)
335  {
336  // the nv is not writeable
337  yError() << "HostTransceiver::addSetROP__(): Maybe you are trying to write a read-only variable? (eo_nv_Set failed)";
338  return false;
339  }
340 
341  }
342 
343  eOropdescriptor_t ropdesc = {0};
344 
345  // marco.accame: use eok_ropdesc_basic to have a basic valid descriptor which is modified later
346  memcpy(&ropdesc, &eok_ropdesc_basic, sizeof(eOropdescriptor_t));
347 
348  ropdesc.control.plustime = 1;
349  ropdesc.control.plussign = (eo_rop_SIGNATUREdummy == signature) ? 0 : 1;
350  ropdesc.ropcode = eo_ropcode_set;
351  ropdesc.id32 = id32;
352  ropdesc.size = 0; // marco.accame: the size is internally computed from the id32
353  ropdesc.data = reinterpret_cast<uint8_t *>(const_cast<void*>(data));
354  ropdesc.signature = signature;
355 
356  bool ret = false;
357 
358  for(int i=0; ( (i<maxNumberOfROPloadingAttempts) && (!ret) ); i++)
359  {
360  lock_transceiver(true);
361  eores = eo_transceiver_OccasionalROP_Load(pc104txrx, &ropdesc);
362  lock_transceiver(false);
363 
364  if(eores_OK != eores)
365  {
366  char nvinfo[128];
367  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
368  yWarning() << "HostTransceiver::addSetROP__(): eo_transceiver_OccasionalROP_Load() for BOARD /w IP" << remoteipstring << "unsuccessful at attempt num " << i+1 <<
369  "with id: " << nvinfo;
370 
371  eo_transceiver_lasterror_tx_Get(pc104txrx, &err, &info0, &info1, &info2);
372  yWarning() << "HostTransceiver::addSetROP__(): eo_transceiver_lasterror_tx_Get() detected: err=" << err << "infos = " << info0 << info1 << info2;
373 
374  yarp::os::Time::delay(delayAfterROPloadingFailure);
375  }
376  else
377  {
378  if(i!=0)
379  {
380  char nvinfo[128];
381  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
382  yDebug() << "HostTransceiver::addSetROP__(): eo_transceiver_OccasionalROP_Load() for BOARD /w IP" << remoteipstring << "successful ONLY at attempt num " << i+1 <<
383  "with id: " << nvinfo;
384  }
385 
386  ret = true;
387  }
388  }
389  if(!ret)
390  {
391  char nvinfo[128];
392  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
393  yError() << "HostTransceiver::addSetROP__(): ERROR in eo_transceiver_OccasionalROP_Load() for BOARD w/ IP" << remoteipstring+1 << "after all attempts" <<
394  "with id: " << nvinfo;
395  }
396 
397  return ret;
398 }
399 
400 
401 
402 bool HostTransceiver::addROPset(const eOprotID32_t id32, const void* data, const uint32_t signature)
403 {
404  return(HostTransceiver::addSetROP__(id32, data, signature, false));
405 }
406 
407 
408 bool HostTransceiver::isID32supported(const eOprotID32_t id32)
409 {
410  return (eobool_false == eoprot_id_isvalid(protboardnumber, id32)) ? false : true;
411 }
412 
413 bool HostTransceiver::addROPask(const eOprotID32_t id32, const uint32_t signature)
414 {
415  eOresult_t eores = eores_NOK_generic;
416  int32_t err = -1;
417  int32_t info0 = -1;
418  int32_t info1 = -1;
419  int32_t info2 = -1;
420 
421  if(eobool_false == eoprot_id_isvalid(protboardnumber, id32))
422  {
423  char nvinfo[128];
424  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
425  yError() << "HostTransceiver::addROPask() called w/ invalid protid: BOARD w/ IP" << remoteipstring <<
426  "with id: " << nvinfo;
427  return false;
428  }
429 
430  eOropdescriptor_t ropdesc = {0};
431  // marco.accame: recommend to use eok_ropdesc_basic
432  memcpy(&ropdesc, &eok_ropdesc_basic, sizeof(eOropdescriptor_t));
433  ropdesc.control.plustime = 1;
434  ropdesc.control.plussign = (eo_rop_SIGNATUREdummy == signature) ? 0 : 1;
435  ropdesc.ropcode = eo_ropcode_ask;
436  ropdesc.id32 = id32;
437  ropdesc.size = 0;
438  ropdesc.data = NULL;
439  ropdesc.signature = signature;
440 
441 
442  bool ret = false;
443 
444  for(int i=0; ( (i<maxNumberOfROPloadingAttempts) && (!ret) ); i++)
445  {
446  lock_transceiver(true);
447  eores = eo_transceiver_OccasionalROP_Load(pc104txrx, &ropdesc);
448  lock_transceiver(false);
449 
450  if(eores_OK != eores)
451  {
452  char nvinfo[128];
453  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
454  yWarning() << "HostTransceiver::addROPask(): eo_transceiver_OccasionalROP_Load() for BOARD w/ IP" << remoteipstring<< "unsuccessfull at attempt num " << i+1 <<
455  "with id: " << nvinfo;
456 
457  eo_transceiver_lasterror_tx_Get(pc104txrx, &err, &info0, &info1, &info2);
458  yWarning() << "HostTransceiver::addROPask(): eo_transceiver_lasterror_tx_Get() detected: err=" << err << "infos = " << info0 << info1 << info2;
459 
460  yarp::os::Time::delay(delayAfterROPloadingFailure);
461  }
462  else
463  {
464  if(i!=0)
465  {
466  char nvinfo[128];
467  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
468  yDebug() << "HostTransceiver::addROPask(): eo_transceiver_OccasionalROP_Load() for BOARD /w IP" << remoteipstring << "succesful ONLY at attempt num " << i+1 <<
469  "with id: " << nvinfo;
470 
471  }
472  ret = true;
473  }
474  }
475  if(!ret)
476  {
477  char nvinfo[128];
478  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
479  yError() << "HostTransceiver::addROPask(): ERROR in eo_transceiver_OccasionalROP_Load() for BOARD w/ IP" << remoteipstring << "after all attempts " <<
480  "with id: " << nvinfo;
481  }
482 
483  return ret;
484 }
485 
486 
487 
488 bool HostTransceiver::read(const eOprotID32_t id32, void *data)
489 {
490  if(eobool_false == eoprot_id_isvalid(protboardnumber, id32))
491  {
492  char nvinfo[128];
493  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
494  yError() << "HostTransceiver::read() called w/ invalid protid: BOARD w/ IP" << remoteipstring <<
495  "with id: " << nvinfo;
496  return false;
497  }
498 
499  if(NULL == data)
500  {
501  yError() << "HostTransceiver:read() called w/ NULL data";
502  return false;
503  }
504 
505  EOnv nv;
506  EOnv *nv_ptr = getnvhandler(id32, &nv);
507 
508  if(NULL == nv_ptr)
509  {
510  char nvinfo[128];
511  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
512  yError() << "HostTransceiver::read() Unable to get pointer to desired NV with: " << nvinfo;
513  return false;
514  }
515 
516  uint16_t size = 0;
517  // marco.accame: protection is inside getNVvalue() member function
518  bool ret = getNVvalue(nv_ptr, reinterpret_cast<uint8_t *>(data), &size);
519 
520 
521  return ret;
522 }
523 
524 
525 
526 // somebody passes the received packet - this is used just as an interface
527 bool HostTransceiver::parseUDP(const void *data, const uint16_t size)
528 {
529  if(NULL == data)
530  {
531  yError() << "eo HostTransceiver::parse() called with NULL data";
532  return false;
533  }
534 
535  if(size > pktsizerx)
536  {
537  yError() << "eo HostTransceiver::parse() called too big a packet: max size is" << pktsizerx;
538  return false;
539  }
540 
541  uint16_t numofrops;
542  uint64_t txtime;
543  uint16_t capacityrxpkt = 0;
544 
545  eo_packet_Capacity_Get(p_RxPkt, &capacityrxpkt);
546  if(size > capacityrxpkt)
547  {
548  yError () << "received packet has size " << size << "which is higher than capacity of rx pkt = " << capacityrxpkt << "\n";
549  return false;
550  }
551 
552  eo_packet_Payload_Set(p_RxPkt, reinterpret_cast<uint8_t*>(const_cast<void*>(data)), size);
553  eo_packet_Addressing_Set(p_RxPkt, remoteipaddr, ipport);
554 
555  // the transceiver can receive and transmit in parallel because reception manipulates memory passed externally
556  // and the two operations do not use internal memory shared between the two
557  // that is true unless there is a say<> required upon a received ask<>. in such a case the receiver must put the answer inside a data
558  // structure read by the transmitter. but the host transceiver does not accept ask<>, thus it is not our case.
559 
560  // for the above reason, we could avoid protection.
561  // HOWEVER: it is a good thing to protect the nvs as the receiver writes them and someone else reads them to retrieve values for yarp ports
562  // for this reason, we use eo_trans_protection_enabled and eo_nvset_protection_one_per_endpoint when we initialise the transceiver.
563  // that solves concurrency problems for the transceiver
564  eo_transceiver_Receive(pc104txrx, p_RxPkt, &numofrops, &txtime);
565 
566  return true;
567 }
568 
569 
570 bool HostTransceiver::isEPsupported(const eOprot_endpoint_t ep)
571 {
572  if(eobool_true == eoprot_endpoint_configured_is(get_protBRDnumber(), ep))
573  {
574  return true;
575  }
576 
577  return false;
578 }
579 
580 
581 const void * HostTransceiver::getUDP(size_t &size, uint16_t &numofrops)
582 {
583  const void * udpframe = nullptr;
584  size = 0;
585  numofrops = 0;
586 
587  // marco.accame on 14oct14: as long as this function is called by one thread only, it is possible to limit the protection to
588  // only one function: eo_transceiver_outpacket_Prepare().
589 
590 
591  EOpacket* ptrpkt = NULL;
592  uint8_t *data = NULL;
593  eOresult_t res;
594 
595 
596 #if !defined(HOSTTRANSCEIVER_EmptyROPframesAreTransmitted)
597  // marco.accame: robotInterface uses only occasionals, thus we dont need to pass arguments for replies and regulars
598  // moreover: if we passed those pointers with non-NULL values, we would lock/unlock internal mutex for them, thus we would spend more time
599  uint16_t numofoccasionals = 0;
600  lock_transceiver(true);
601  eo_transceiver_NumberofOutROPs(pc104txrx, NULL, &numofoccasionals, NULL);
602  lock_transceiver(false);
603  if(0 == numofoccasionals)
604  {
605  return nullptr;
606  }
607 #endif
608 
609 
610  uint16_t tmpnumofrops = 0;
611 
612  // it must be protected vs concurrent use of other threads attempting to put rops inside the transceiver.
613  lock_transceiver(true);
614  res = eo_transceiver_outpacket_Prepare(pc104txrx, &tmpnumofrops, NULL);
615  lock_transceiver(false);
616 
617 #if defined(HOSTTRANSCEIVER_EmptyROPframesAreTransmitted)
618  if((eores_OK != res))
619 #else
620  if((eores_OK != res) || (0 == tmpnumofrops)) // transmit only if res is ok and there is at least one rop to send
621 #endif
622  {
623  return nullptr;
624  }
625 
626  // this function does not use data used by concurrent threads, thus it can be left un-protected.
627  res = eo_transceiver_outpacket_Get(pc104txrx, &ptrpkt);
628 
629  if(eores_OK != res)
630  {
631  return nullptr;
632  }
633 
634  // after these two lines, in data, size and numofrops we have what we need
635  uint16_t tmpsize = 0;
636  eo_packet_Payload_Get(ptrpkt, &data, &tmpsize);
637 
638  size = tmpsize;
639  numofrops = tmpnumofrops;
640  udpframe = (tmpnumofrops > 0) ? data : nullptr;
641 
642 
643  return udpframe;
644 }
645 
646 
647 EOnv* HostTransceiver::getnvhandler(eOprotID32_t id32, EOnv* nv)
648 {
649  eOresult_t res;
650  res = eo_nvset_NV_Get(nvset, id32, nv);
651  if(eores_OK != res)
652  {
653  char nvinfo[128];
654  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
655  yError() << "HostTransceiver::getnvhandler() called w/ invalid protid: BOARD w/ IP" << remoteipstring <<
656  "with id: " << nvinfo;
657  return NULL;
658  }
659 
660  return(nv);
661 }
662 
663 
664 bool HostTransceiver::getNVvalue(EOnv *nv, uint8_t* data, uint16_t* size)
665 {
666  bool ret;
667  if (NULL == nv)
668  {
669  yError() << "HostTransceiver::getNVvalue() called w/ NULL nv value: BOARD w/ IP" << remoteipstring;
670  return false;
671  }
672  lock_nvs(true);
673  (eores_OK == eo_nv_Get(nv, eo_nv_strg_volatile, data, size)) ? ret = true : ret = false;
674  lock_nvs(false);
675 
676  if(false == ret)
677  {
678  yError() << "HostTransceiver::getNVvalue() fails in eo_nv_Get(): BOARD w/ IP" << remoteipstring;
679  }
680  return ret;
681 }
682 
683 
684 
685 eOprotBRD_t HostTransceiver::get_protBRDnumber(void)
686 {
687  return(protboardnumber);
688 }
689 
690 
691 eOipv4addr_t HostTransceiver::get_remoteIPaddress(void)
692 {
693  return(remoteipaddr);
694 }
695 
696 
697 bool HostTransceiver::initProtocol()
698 {
699  static bool alreadyinitted = false;
700 
701 // if(false == alreadyinitted)
702 // {
703 // // before using embOBJ we need initialing its system. it is better to init it again in case someone did not do it
704 // // we use the TheEthManager function ... however that was already called
705 // TheEthManager::instance()->initEOYsystem();
706 // }
707 
708  // reserve resources for board # protboardnumber
709  if(eores_OK != eoprot_config_board_reserve(protboardnumber))
710  {
711  yError() << "HostTransceiver::initProtocol(): call to eoprot_config_board_reserve() fails.";
712  return(false);
713  }
714 
715  if(false == alreadyinitted)
716  {
717  // configure all the callbacks of all endpoints.
718 
719  eoprot_override_mn();
720  eoprot_override_mc();
721  eoprot_override_as();
722  eoprot_override_sk();
723 
724  // ok. all is done correctly
725  alreadyinitted = true;
726 
727  }
728  else
729  {
730 
731  }
732 
733  return(true);
734 }
735 
736 
737 
738 void HostTransceiver::eoprot_override_mn(void)
739 {
740  // marco.accame on 22 mar 2016:
741  // i want to keep a minimum of callbacks, thus i have cleaned and put comments about what is needed and why
742 
743  static const eOprot_callbacks_endpoint_descriptor_t mn_callbacks_descriptor_endp =
744  {
745  EO_INIT(.endpoint) eoprot_endpoint_management,
746  EO_INIT(.raminitialise) NULL
747  };
748 
749  static const eOprot_callbacks_variable_descriptor_t mn_callbacks_descriptors_vars[] =
750  { // management
751  { // mn_info_status: used for printing sig<> diagnostics ROPs which have strings
752  EO_INIT(.endpoint) eoprot_endpoint_management,
753  EO_INIT(.entity) eoprot_entity_mn_info,
754  EO_INIT(.tag) eoprot_tag_mn_info_status,
755  EO_INIT(.init) NULL,
756  EO_INIT(.update) eoprot_fun_UPDT_mn_info_status
757  },
758  { // mn_info_status_basic: used for printing sig<> diagnostics ROPs which have compact form (the vast majority)
759  EO_INIT(.endpoint) eoprot_endpoint_management,
760  EO_INIT(.entity) eoprot_entity_mn_info,
761  EO_INIT(.tag) eoprot_tag_mn_info_status_basic,
762  EO_INIT(.init) NULL,
763  EO_INIT(.update) eoprot_fun_UPDT_mn_info_status_basic
764  },
765  { // mn_comm_cmmnds_command_replynumof: used for receiving reply of a command in the form of sig<> ROP
766  EO_INIT(.endpoint) eoprot_endpoint_management,
767  EO_INIT(.entity) eoprot_entity_mn_comm,
768  EO_INIT(.tag) eoprot_tag_mn_comm_cmmnds_command_replynumof,
769  EO_INIT(.init) NULL,
771  },
772  { // mn_comm_cmmnds_command_replyarray: used for receiving reply of a command in the form of sig<> ROP
773  EO_INIT(.endpoint) eoprot_endpoint_management,
774  EO_INIT(.entity) eoprot_entity_mn_comm,
775  EO_INIT(.tag) eoprot_tag_mn_comm_cmmnds_command_replyarray,
776  EO_INIT(.init) NULL,
778  },
779  { // mn_service_status_commandresult: used for receiving reply of a command in the form of sig<> ROP
780  EO_INIT(.endpoint) eoprot_endpoint_management,
781  EO_INIT(.entity) eoprot_entity_mn_service,
782  EO_INIT(.tag) eoprot_tag_mn_service_status_commandresult,
783  EO_INIT(.init) NULL,
785  }
786  };
787 
788 
789  // -----------------------------------------------------------------------------------------------------------------------------------
790  // -- initialisation of onsay() function common in MN endpoint for every board
791 
792  // function eoprot_fun_ONSAY_mn() is called by any say<> ROP which is received related to the MN endpoint
793  // it is used to unlock a waiting mutex
794  eoprot_config_onsay_endpoint_set(eoprot_endpoint_management, eoprot_fun_ONSAY_mn);
795 
796 
797  // ------------------------------------------------------------------------------------------------------------------------------------
798  // -- override of the callbacks of variables of MN. common to every board. they perform an action or reception of a specific sig<> ROP.
799 
800  int number = sizeof(mn_callbacks_descriptors_vars)/sizeof(mn_callbacks_descriptors_vars[0]);
801  for(int i=0; i<number; i++)
802  {
803  eoprot_config_callbacks_variable_set(&mn_callbacks_descriptors_vars[i]);
804  }
805 
806 }
807 
808 
809 void HostTransceiver::eoprot_override_mc(void)
810 {
811  // marco.accame on 22 mar 2016:
812  // i want to keep a minimum of callbacks, thus i have cleaned and put comments about what is needed and why
813 
814  static const eOprot_callbacks_endpoint_descriptor_t mc_callbacks_descriptor_endp =
815  {
816  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
817  EO_INIT(.raminitialise) NULL
818  };
819 
820  static const eOprot_callbacks_variable_descriptor_t mc_callbacks_descriptors_vars[] =
821  {
822  // joint
823  { // joint_status: used to inform the motioncontrol device that a sig<> ROP about joint status has arrived. for .. updating timestamps
824  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
825  EO_INIT(.entity) eoprot_entity_mc_joint,
826  EO_INIT(.tag) eoprot_tag_mc_joint_status,
827  EO_INIT(.init) NULL,
828  EO_INIT(.update) eoprot_fun_UPDT_mc_joint_status
829  },
830  { // joint_status_basic: used to inform the motioncontrol device that a sig<> ROP about joint status has arrived. for .. updating the same timestamps as above
831  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
832  EO_INIT(.entity) eoprot_entity_mc_joint,
833  EO_INIT(.tag) eoprot_tag_mc_joint_status_core,
834  EO_INIT(.init) NULL,
835  EO_INIT(.update) eoprot_fun_UPDT_mc_joint_status_core
836  },
837  { // joint_status_debug:
838  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
839  EO_INIT(.entity) eoprot_entity_mc_joint,
840  EO_INIT(.tag) eoprot_tag_mc_joint_status_debug,
841  EO_INIT(.init) NULL,
843  },
844  { // joint_status_basic: used to inform the motioncontrol device that a sig<> ROP about joint status has arrived. for .. updating the same timestamps as above
845  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
846  EO_INIT(.entity) eoprot_entity_mc_joint,
847  EO_INIT(.tag) eoprot_tag_mc_joint_status_addinfo_multienc,
848  EO_INIT(.init) NULL,
850  },
851  { // joint_status_basic: used to inform the motioncontrol device that a sig<> ROP about joint status has arrived. for .. updating the same timestamps as above
852  EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
853  EO_INIT(.entity) eoprot_entity_mc_motor,
854  EO_INIT(.tag) eoprot_tag_mc_motor_status,
855  EO_INIT(.init) NULL,
856  EO_INIT(.update) eoprot_fun_UPDT_mc_motor_status
857  }
858  // motor
859  // nothing so far
860 
861  // comment: the functions eoprot_fun_UPDT_mc_joint_status_core() and eoprot_fun_UPDT_mc_joint_status() update the same _encodersStamp[]
862  // variables. only one of those two id32 variables are regularly sig<>-led.
863  // on the other hand, the same _encodersStamp[] is used for motor encoders ... thus maybe we miss something.
864  };
865 
866 
867 
868  // -----------------------------------------------------------------------------------------------------------------------------------
869  // -- initialisation of onsay() function common in MC endpoint for every board
870 
871  // function eoprot_fun_ONSAY_mc() is called by any say<> ROP which is received related to the MC endpoint
872  // it is used to unlock a waiting mutex
873 
874  eoprot_config_onsay_endpoint_set(eoprot_endpoint_motioncontrol, eoprot_fun_ONSAY_mc);
875 
876 
877  // ------------------------------------------------------------------------------------------------------------------------------------
878  // -- override of the callbacks of variables of MC. common to every board. they perform an action or reception of a specific sig<> ROP.
879 
880  int number = sizeof(mc_callbacks_descriptors_vars)/sizeof(mc_callbacks_descriptors_vars[0]);
881  for(int i=0; i<number; i++)
882  {
883  eoprot_config_callbacks_variable_set(&mc_callbacks_descriptors_vars[i]);
884  }
885 }
886 
887 
888 void HostTransceiver::eoprot_override_as(void)
889 {
890  // marco.accame on 22 mar 2016:
891  // i want to keep a minimum of callbacks, thus i have cleaned and put comments about what is needed and why
892 
893  static const eOprot_callbacks_endpoint_descriptor_t as_callbacks_descriptor_endp =
894  {
895  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
896  EO_INIT(.raminitialise) NULL
897  };
898 
899  static const eOprot_callbacks_variable_descriptor_t as_callbacks_descriptors_vars[] =
900  {
901  // strain
902  { // strain_status_calibratedvalues: it gives data from strain to the device, so that it writes it in the relevant yarp port
903  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
904  EO_INIT(.entity) eoprot_entity_as_strain,
905  EO_INIT(.tag) eoprot_tag_as_strain_status_calibratedvalues,
906  EO_INIT(.init) NULL,
908  },
909  { // strain_status_uncalibratedvalues: it gives data from strain to the device, so that it writes it in the relevant yarp port
910  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
911  EO_INIT(.entity) eoprot_entity_as_strain,
912  EO_INIT(.tag) eoprot_tag_as_strain_status_uncalibratedvalues,
913  EO_INIT(.init) NULL,
915  },
916  // mais
917  { // mais_status_the15values: it gives data from mais to the device, so that it writes it in the relevant yarp port
918  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
919  EO_INIT(.entity) eoprot_entity_as_mais,
920  EO_INIT(.tag) eoprot_tag_as_mais_status_the15values,
921  EO_INIT(.init) NULL,
923  },
924  // inertial3
925  { // eoprot_tag_as_inertial3_status: ...
926  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
927  EO_INIT(.entity) eoprot_entity_as_inertial3,
928  EO_INIT(.tag) eoprot_tag_as_inertial3_status,
929  EO_INIT(.init) NULL,
930  EO_INIT(.update) eoprot_fun_UPDT_as_inertial3_status
931  },
932  { // eoprot_tag_as_temperature_status: ...
933  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
934  EO_INIT(.entity) eoprot_entity_as_temperature,
935  EO_INIT(.tag) eoprot_tag_as_temperature_status,
936  EO_INIT(.init) NULL,
938  },
939  { // eoprot_tag_as_psc_status: ...
940  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
941  EO_INIT(.entity) eoprot_entity_as_psc,
942  EO_INIT(.tag) eoprot_tag_as_psc_status,
943  EO_INIT(.init) NULL,
944  EO_INIT(.update) eoprot_fun_UPDT_as_psc_status
945  },
946  { // eoprot_tag_as_pos_status: ...
947  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
948  EO_INIT(.entity) eoprot_entity_as_pos,
949  EO_INIT(.tag) eoprot_tag_as_pos_status,
950  EO_INIT(.init) NULL,
951  EO_INIT(.update) eoprot_fun_UPDT_as_pos_status
952  },
953  { // eoprot_tag_as_ft_status_timedvalue: ...
954  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
955  EO_INIT(.entity) eoprot_entity_as_ft,
956  EO_INIT(.tag) eoprot_tag_as_ft_status_timedvalue,
957  EO_INIT(.init) NULL,
959  },
960  { // eoprot_tag_as_battery_status_timedvalue: ...
961  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
962  EO_INIT(.entity) eoprot_entity_as_battery,
963  EO_INIT(.tag) eoprot_tag_as_battery_status_timedvalue,
964  EO_INIT(.init) NULL,
966  },
967 
968 #if 0 // marco.accame: i keep the code just for the debug phase.
969  ,{ // eoprot_tag_as_inertial_status_accelerometer
970  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
971  EO_INIT(.entity) eoprot_entity_as_inertial,
972  EO_INIT(.tag) eoprot_tag_as_inertial_status_accelerometer,
973  EO_INIT(.init) NULL,
974  EO_INIT(.update) eoprot_fun_UPDT_as_inertial_status_accelerometer
975  },
976  { // eoprot_tag_as_inertial_status_gyroscope
977  EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
978  EO_INIT(.entity) eoprot_entity_as_inertial,
979  EO_INIT(.tag) eoprot_tag_as_inertial_status_gyroscope,
980  EO_INIT(.init) NULL,
981  EO_INIT(.update) eoprot_fun_UPDT_as_inertial_status_gyroscope
982  }
983 #endif
984  };
985 
986 
987  // -----------------------------------------------------------------------------------------------------------------------------------
988  // -- initialisation of onsay() function common in AS endpoint for every board
989 
990  // function eoprot_fun_ONSAY_as() is called by any say<> ROP which is received related to the AS endpoint
991  // it is used to unlock a waiting mutex
992 
993  eoprot_config_onsay_endpoint_set(eoprot_endpoint_analogsensors, eoprot_fun_ONSAY_as);
994 
995 
996  // ------------------------------------------------------------------------------------------------------------------------------------
997  // -- override of the callbacks of variables of AS. common to every board. they perform an action or reception of a specific sig<> ROP.
998 
999  int number = sizeof(as_callbacks_descriptors_vars)/sizeof(as_callbacks_descriptors_vars[0]);
1000  for(int i=0; i<number; i++)
1001  {
1002  eoprot_config_callbacks_variable_set(&as_callbacks_descriptors_vars[i]);
1003  }
1004 
1005 }
1006 
1007 
1008 void HostTransceiver::eoprot_override_sk(void)
1009 {
1010  // marco.accame on 22 mar 2016:
1011  // i want to keep a minimum of callbacks, thus i have cleaned and put comments about what is needed and why
1012 
1013 // static const eOprot_callbacks_endpoint_descriptor_t sk_callbacks_descriptor_endp =
1014 // {
1015 // EO_INIT(.endpoint) eoprot_endpoint_skin,
1016 // EO_INIT(.raminitialise) NULL
1017 // };
1018 
1019  static const eOprot_callbacks_variable_descriptor_t sk_callbacks_descriptors_vars[] =
1020  {
1021  // skin
1022  { // skin_status_arrayof10canframes: it gives data from mtb to the device, so that it writes it in the relevant yarp port
1023  EO_INIT(.endpoint) eoprot_endpoint_skin,
1024  EO_INIT(.entity) eoprot_entity_sk_skin,
1025  EO_INIT(.tag) eoprot_tag_sk_skin_status_arrayofcandata,
1026  EO_INIT(.init) NULL,
1028  }
1029  };
1030 
1031 
1032  // -----------------------------------------------------------------------------------------------------------------------------------
1033  // -- initialisation of onsay() function common in SK endpoint for every board
1034 
1035  // function eoprot_fun_ONSAY_mc() is called by any say<> ROP which is received related to the SK endpoint
1036  // it is used to unlock a waiting mutex
1037 
1038  eoprot_config_onsay_endpoint_set(eoprot_endpoint_skin, eoprot_fun_ONSAY_sk);
1039 
1040 
1041  // ------------------------------------------------------------------------------------------------------------------------------------
1042  // -- override of the callbacks of variables of SK. common to every board. they perform an action or reception of a specific sig<> ROP.
1043 
1044  int number = sizeof(sk_callbacks_descriptors_vars)/sizeof(sk_callbacks_descriptors_vars[0]);
1045  for(int i=0; i<number; i++)
1046  {
1047  eoprot_config_callbacks_variable_set(&sk_callbacks_descriptors_vars[i]);
1048  }
1049 
1050 }
1051 
1052 
1054 {
1055  const eOreceiver_seqnum_error_t * err = eo_receiver_GetSequenceNumberError(r);
1056  long long unsigned int exp = err->exp_seqnum;
1057  long long unsigned int rec = err->rec_seqnum;
1058  long long unsigned int timeoftxofcurrent = err->timeoftxofcurrent;
1059  long long unsigned int timeoftxofprevious = err->timeoftxofprevious;
1060  char *ipaddr = (char*)&err->remipv4addr;
1061  //printf("\nERROR in sequence number from IP = %d.%d.%d.%d\t Expected: \t%llu,\t received: \t%llu\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], exp, rec);
1062  char errmsg[256] = {0};
1063  snprintf(errmsg, sizeof(errmsg), "hostTransceiver()::parse() detected an ERROR in sequence number from IP = %d.%d.%d.%d. Expected: %llu, Received: %llu, Missing: %llu, Prev Frame TX at %llu us, This Frame TX at %llu us",
1064  ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
1065  exp, rec, rec-exp,
1066  timeoftxofprevious, timeoftxofcurrent);
1067  yError() << errmsg;
1068 }
1069 
1070 
1071 typedef struct
1072 {
1073  uint32_t startofframe;
1074  uint16_t ropssizeof;
1075  uint16_t ropsnumberof;
1076  uint64_t ageofframe;
1077  uint64_t sequencenumber;
1079 
1080 
1082 {
1083  const eOreceiver_invalidframe_error_t * err = eo_receiver_GetInvalidFrameError(r);
1084  char errmsg[256] = {0};
1085  char *ipaddr = (char*)&err->remipv4addr;
1086  tmpStructROPframeHeader_t *header = (tmpStructROPframeHeader_t*)err->ropframe;
1087  long long unsigned int ageofframe = header->ageofframe;
1088  long long unsigned int sequencenumber = header->sequencenumber;
1089  uint16_t ropframesize = 0;
1090  eo_ropframe_Size_Get(err->ropframe, &ropframesize);
1091  //snprintf(errmsg, sizeof(errmsg), "hostTransceiver()::parse() detected an ERROR of type INVALID FRAME from IP = TBD");
1092  snprintf(errmsg, sizeof(errmsg), "hostTransceiver()::parse() detected an ERROR of type INVALID FRAME from IP = %d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
1093  yError() << errmsg;
1094  snprintf(errmsg, sizeof(errmsg), "hostTransceiver()::parse() detected: ropframesize = %d, ropsizeof = %d, ropsnumberof = %d, ageoframe = %llu, sequencenumber = %llu", ropframesize, header->ropssizeof, header->ropsnumberof, ageofframe, sequencenumber);
1095  yDebug() << errmsg;
1096 
1097 }
1098 
1099 
1100 bool HostTransceiver::prepareTransceiverConfig2(yarp::os::Searchable &cfgtotal)
1101 {
1102  memcpy(&hosttxrxcfg, &eo_hosttransceiver_cfg_default, sizeof(eOhosttransceiver_cfg_t));
1103  hosttxrxcfg.remoteboardipv4addr = remoteipaddr;
1104  hosttxrxcfg.remoteboardipv4port = ipport;
1105 
1106 
1107  eth::parser::pc104Data pc104data;
1108  eth::parser::read(cfgtotal, pc104data);
1109 // eth::parser::print(pc104data);
1110 
1111 
1112  eth::parser::boardData brddata;
1113  eth::parser::read(cfgtotal, brddata);
1114 // eth::parser::print(brddata);
1115 
1116  capacityofTXpacket = brddata.properties.maxSizeRXpacket;
1117  maxSizeOfROP = brddata.properties.maxSizeROP;
1118 
1119 
1120 
1121  // we build the hosttransceiver so that:
1122  // 1. it can send a packet which can always be received by the board (max tx size = max rx size of remote board)
1123  // 2. it has the same maxsize of rop as remote board
1124  // 3. it has no regulars, no space for replies, and maximum space for occasionals.
1125  // the properties of remote board are inside remoteTransceiverProperties and are taken from the xml file.
1126  // after the transceiver is built and communication can happen, we shall verify if remoteTransceiverProperties has the same values
1127  // of what is read from remote board. see funtion ethResources::verifyBoardTransceiver().
1128 
1129  hosttxrxcfg.sizes.capacityoftxpacket = capacityofTXpacket;
1130  hosttxrxcfg.sizes.capacityofrop = maxSizeOfROP;
1131  hosttxrxcfg.sizes.capacityofropframeregulars = eo_ropframe_sizeforZEROrops;
1132  hosttxrxcfg.sizes.capacityofropframereplies = eo_ropframe_sizeforZEROrops;
1133  hosttxrxcfg.sizes.capacityofropframeoccasionals = (hosttxrxcfg.sizes.capacityoftxpacket - eo_ropframe_sizeforZEROrops) - hosttxrxcfg.sizes.capacityofropframeregulars - hosttxrxcfg.sizes.capacityofropframereplies;
1134  hosttxrxcfg.sizes.maxnumberofregularrops = 0;
1135 
1136 
1137  // ok, now the nvset ... we use maximum capabilities so that we can manage communication of up to 12 jomos
1138  const eOnvset_BRDcfg_t* brdcf2use = &eonvset_BRDcfgMax;
1139 
1140 
1141  memcpy(&nvsetbrdconfig, brdcf2use, sizeof(eOnvset_BRDcfg_t));
1142  nvsetbrdconfig.boardnum = get_protBRDnumber();
1143 
1144  hosttxrxcfg.nvsetbrdcfg = &nvsetbrdconfig;
1145  hosttxrxcfg.extfn.onerrorseqnumber = cpp_protocol_callback_incaseoferror_in_sequencenumberReceived;
1146  hosttxrxcfg.extfn.onerrorinvalidframe = cpp_protocol_callback_incaseoferror_invalidFrame;
1147 
1148 
1149 #if !defined(HOSTTRANSCEIVER_USE_INTERNAL_MUTEXES)
1150  hosttxrxcfg.mutex_fn_new = NULL;
1151  hosttxrxcfg.transprotection = eo_trans_protection_none;
1152  hosttxrxcfg.nvsetprotection = eo_nvset_protection_none;
1153 #else
1154  // mutex protection inside transceiver
1155  hosttxrxcfg.mutex_fn_new = (eov_mutex_fn_mutexderived_new) eoy_mutex_New;
1156  hosttxrxcfg.transprotection = eo_trans_protection_enabled; // eo_trans_protection_none
1157  hosttxrxcfg.nvsetprotection = eo_nvset_protection_one_per_endpoint; // eo_nvset_protection_one_per_object // eo_nvset_protection_none
1158 #endif
1159 
1160  return(true);
1161 }
1162 
1163 
1164 
1165 // eof
1166 
1167 
1168 
void eoprot_fun_UPDT_as_strain_status_calibratedvalues(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_strain_status_uncalibratedvalues(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_ft_status_timedvalue(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_ONSAY_as(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_inertial3_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_pos_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_psc_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_temperature_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_mais_status_the15values(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_battery_status_timedvalue(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_ONSAY_mc(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_joint_status_core(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_joint_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_joint_status_debug(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_motor_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_joint_status_addinfo_multienc(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_ONSAY_mn(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mn_comm_cmmnds_command_replynumof(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mn_info_status_basic(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mn_comm_cmmnds_command_replyarray(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mn_service_status_commandresult(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mn_info_status(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_sk_skin_status_arrayofcandata(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_ONSAY_sk(const EOnv *nv, const eOropdescriptor_t *rd)
@ data
exp(-x3 *T)]
ACE_UINT64 txtime
bool addROPask(const eOprotID32_t id32, const uint32_t signature=eo_rop_SIGNATUREdummy)
bool write(const eOprotID32_t id32, const void *data, bool forcewriteOfReadOnly)
bool addROPset(const eOprotID32_t id32, const void *data, const uint32_t signature=eo_rop_SIGNATUREdummy)
bool isEPsupported(const eOprot_endpoint_t ep)
bool init2(AbstractEthResource *owner, yarp::os::Searchable &cfgtotal, eOipv4addressing_t &localIPaddressing, eOipv4addr_t remoteIP, uint16_t rxpktsize=maxSizeOfRXpacket)
const void * getUDP(size_t &size, uint16_t &numofrops)
bool parseUDP(const void *data, const uint16_t size)
bool isID32supported(const eOprotID32_t id32)
AbstractEthResource * getResource()
bool read(const eOprotID32_t id32, void *data)
void cpp_protocol_callback_incaseoferror_invalidFrame(EOreceiver *r)
void cpp_protocol_callback_incaseoferror_in_sequencenumberReceived(EOreceiver *r)
bool read(yarp::os::Searchable &cfgtotal, pc104Data &pc104data)
Definition: ethParser.cpp:92
grid on
Definition: show_eyes_axes.m:5
boardProperties properties
Definition: ethParser.h:86
std::uint16_t maxSizeRXpacket
Definition: ethParser.h:40
std::uint16_t maxSizeROP
Definition: ethParser.h:41
uint16_t ropssizeof
tells how many bytes are reserved for the rops: its value can be 0 to ...
uint16_t ropsnumberof
tells how many rops are inside: its value can be 0 to ...
uint64_t sequencenumber
contains a sequence number
uint32_t startofframe
it is the start of the frame: it is EOFRAME_START
uint64_t ageofframe
tells the time (in usec) of creation of the frame