iCub-main
Loading...
Searching...
No Matches
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
23using 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
60using namespace eth;
61
62bool 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
76bool 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
89HostTransceiver::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
137bool 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
234bool 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
292bool 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
402bool 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
408bool HostTransceiver::isID32supported(const eOprotID32_t id32)
409{
410 return (eobool_false == eoprot_id_isvalid(protboardnumber, id32)) ? false : true;
411}
412
413bool 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
488bool 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
527bool 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
570bool 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
581const 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
647EOnv* 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
664bool 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
685eOprotBRD_t HostTransceiver::get_protBRDnumber(void)
686{
687 return(protboardnumber);
688}
689
690
691eOipv4addr_t HostTransceiver::get_remoteIPaddress(void)
692{
693 return(remoteipaddr);
694}
695
696
697bool 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
738void 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,
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
809void 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,
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
888void 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,
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
1008void 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
1071typedef struct
1072{
1073 uint32_t startofframe;
1074 uint16_t ropssizeof;
1075 uint16_t ropsnumberof;
1076 uint64_t ageofframe;
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
1100bool 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
boardProperties properties
Definition ethParser.h:87
std::uint16_t maxSizeRXpacket
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