iCub-main
Loading...
Searching...
No Matches
ethResource.cpp
Go to the documentation of this file.
1// -*- Mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
3/*
4 * Copyright (C) 2012 iCub Facility, Istituto Italiano di Tecnologia
5 * Author: Alberto Cardellino, Marco Accame
6 * email: alberto.cardellino@iit.it, marco.accame@iit.it
7 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
8 *
9 */
10
11#include "ethResource.h"
12#include <ethManager.h>
13#include <yarp/os/Time.h>
14#include <yarp/os/Network.h>
15#include <yarp/conf/environment.h>
16#include <yarp/os/NetType.h>
17
18// embobj
19#include "EOropframe_hid.h"
20#include "EOarray.h"
21#include "EoProtocol.h"
22#include "EoManagement.h"
23#include "EoProtocolMN.h"
24#include "can_string_eth.h"
25
26using namespace yarp::os;
27using namespace yarp::os::impl;
28
29#include <theNVmanager.h>
30#include "ethParser.h"
31using namespace eth;
32
33
34
35
36
37// - class EthResource
38
40{
41 ethManager = NULL;
42 isInRunningMode = false;
43
44 verifiedBoardPresence = false;
45 askedBoardVersion = false;
46 verifiedBoardTransceiver = false;
47 txrateISset = false;
48 cleanedBoardBehaviour = false;
49
50 boardMNprotocolversion.major = boardMNprotocolversion.minor;
51
52
53 txconfig.cycletime = defcycletime;
54 txconfig.txratedivider = defTXrateOfRegularROPs;
55 txconfig.maxtimeRX = defmaxtimeRX;
56 txconfig.maxtimeDO = defmaxtimeDO;
57 txconfig.maxtimeTX = defmaxtimeTX;
58 txconfig.logging.flags = (0x0001 << eomn_appl_log_asynchro_exectime_overflow);
59 txconfig.logging.period10ms = 0;
60
61 memset(verifiedEPprotocol, 0, sizeof(verifiedEPprotocol));
62
63 usedNumberOfRegularROPs = 0;
64
65 for(int i = 0; i<16; i++)
66 {
67 c_string_handler[i] = NULL;
68 }
69
70 std::string tmp = yarp::conf::environment::get_string("ETH_VERBOSEWHENOK");
71 if (tmp != "")
72 {
73 verbosewhenok = (bool)(yarp::conf::numeric::from_string(tmp, 0U));
74 }
75 else
76 {
77 verbosewhenok = false;
78 }
79
80 verbosewhenok = true;
81
82 regularsAreSet = false;
83}
84
85
87{
88 ethManager = NULL;
89
90 // Delete every initialized can_string_eth object
91 for(int i=0; i<16; i++)
92 {
93 if (c_string_handler[i] != NULL)
94 {
95 delete c_string_handler[i];
96 c_string_handler[i] = NULL;
97 }
98 }
99}
100
101bool EthResource::lock(bool on)
102{
103 if(true == on)
104 objLock.lock();
105 else
106 objLock.unlock();
107
108 return true;
109}
110
111
112bool EthResource::open2(eOipv4addr_t remIP, yarp::os::Searchable &cfgtotal)
113{
114 ethManager = eth::TheEthManager::instance();
115
116 eth::parser::pc104Data pc104data;
117 eth::parser::read(cfgtotal, pc104data);
118// eth::parser::print(pc104data);
119
120
122 eth::parser::read(cfgtotal, brddata);
123 eth::parser::print(brddata);
124
125 txconfig = brddata.settings.txconfig;
126
127 properties.ipv4addr = remIP;
128 properties.ipv4addressing = brddata.properties.ipv4addressing;
129 properties.boardtype = brddata.properties.type;
130 properties.ipv4addrString = brddata.properties.ipv4string;
132 properties.boardtypeString = brddata.properties.typestring;
133 properties.boardnameString = brddata.settings.name;
134 properties.txROPratedivider = txconfig.txratedivider;
135
136
138
139 // default values ...
140 mpConfig.enabled = brddata.actions.monitorpresence_enabled;
141 mpConfig.timeout = brddata.actions.monitorpresence_timeout;
143 mpConfig.name = brddata.properties.ipv4string + " (" + brddata.settings.name + ")";
144
145
146
147 // now i init objects
148
149 lock(true);
150
151 // 1. init transceiver
152
153 eOipv4addressing_t localIPv4 = ethManager->getLocalIPV4addressing();
154
155
156 if(false == transceiver.init2(this, cfgtotal, localIPv4, remIP))
157 {
158 yError() << "EthResource::open2() cannot init transceiver w/ HostTransceiver::init2() for BOARD" << properties.boardnameString << "IP" << properties.ipv4addrString;
159 lock(false);
160 return false;
161 }
162
163 // 2. init monitor presence
164
165 monitorpresence.config(mpConfig);
166 monitorpresence.tick();
167
168
169 lock(false);
170
171 return true;
172}
173
174
175
177{
178 yTrace();
179 return false;
180}
181
182
183const void * EthResource::getUDPtransmit(eOipv4addressing_t &destination, size_t &sizeofpacket, uint16_t &numofrops)
184{
185 destination = properties.ipv4addressing;
186 const void * udp = transceiver.getUDP(sizeofpacket, numofrops);
187
188// const EOropframeHeader_t * header = reinterpret_cast<const EOropframeHeader_t *>(udp);
189
190// if(nullptr != header)
191// {
192// yDebug() << "EthResource::getUDPtransmit(): the header has: sequencenumber = " << header->sequencenumber << "numofrops = " << header->ropsnumberof << "sizeofrops = " << header->ropssizeof;
193// }
194// else
195// {
196
197// }
198
199 return udp;
200}
201
202
204{
205 monitorpresence.tick();
206 return true;
207}
208
209
211{
212 if(false == regularsAreSet)
213 { // we dont comply if the regulars are not set because ... poor board: it does not regularly transmit
214 return true;
215 }
216
217 return monitorpresence.check();
218}
219
220
221
222bool EthResource::processRXpacket(const void *data, const size_t size)
223{
224 return transceiver.parseUDP(data, size);
225}
226
227
229{
230 return properties;
231}
232
233
234
235//bool EthResource::isID32supported(eOprotID32_t id32)
236//{
237// return transceiver.isID32supported(id32);
238//}
239
240
241
242bool EthResource::isRunning(void)
243{
244 return(isInRunningMode);
245}
246
247
248
249bool EthResource::verifyBoardTransceiver()
250{
251 // the transceiver is verified if we have the same mn protocol version inside eOmn_comm_status_t::managementprotocolversion
252
253 if(verifiedBoardTransceiver)
254 {
255 return(true);
256 }
257
258 // we dont ask anything to the board ...
259#define DONT_ASK_COMM_STATUS
260
261#if defined(DONT_ASK_COMM_STATUS)
262
263 const eoprot_version_t * pc104versionMN = eoprot_version_of_endpoint_get(eoprot_endpoint_management);
264 const eoprot_version_t * brdversionMN = &boardMNprotocolversion;
265
266#else
267
269
270
271 // step 1: we ask the remote board the eoprot_tag_mn_comm_status variable and then we verify vs mn protocol version
272
273 const eoprot_version_t * pc104versionMN = eoprot_version_of_endpoint_get(eoprot_endpoint_management);
274 const double timeout = 0.100; // now the timeout can be reduced because the board is already connected.
275
276 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_comm, 0, eoprot_tag_mn_comm_status);
277 eOmn_comm_status_t brdstatus = {0};
278 uint16_t size = 0;
279
280 bool rr = nvman.ask(ipv4addr, id32, &brdstatus, timeout);
281
282 if(false == rr)
283 {
284 yError() << "EthResource::verifyBoardTransceiver() cannot read brdstatus w/ theNVmanager for BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": cannot proceed any further";
285 return(false);
286 }
287
288 eoprot_version_t * brdversionMN = (eoprot_version_t*)&brdstatus.managementprotocolversion;
289
290#endif
291
292 if(pc104versionMN->major != brdversionMN->major)
293 {
294 yError() << "EthResource::verifyBoardTransceiver() detected different mn protocol major versions: local =" << pc104versionMN->major << ", remote =" << brdversionMN->major << ": cannot proceed any further";
295 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update.";
296 return(false);
297 }
298
299 if(pc104versionMN->minor != brdversionMN->minor)
300 {
301 yError() << "EthResource::verifyBoardTransceiver() detected different mn protocol minor versions: local =" << pc104versionMN->minor << ", remote =" << brdversionMN->minor << ": cannot proceed any further.";
302 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update.";
303 return(false);
304 }
305
306
307 if(verbosewhenok)
308 {
309 yDebug() << "EthResource::verifyBoardTransceiver() has validated the transceiver of BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString;
310 }
311
312 verifiedBoardTransceiver = true;
313
314 return(true);
315}
316
317
318
319bool EthResource::setTimingOfRunningCycle()
320{
321
322 if(txrateISset)
323 {
324 return(true);
325 }
326
327 // step 1: we send the remote board a message of type eoprot_tag_mn_appl_config with the value read from the proper section
328 // if does find the section we use default values
329
330 // call a set until verified
331
332 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_appl, 0, eoprot_tag_mn_appl_config);
333
335
336 if(false == nvman.setcheck(properties.ipv4addr, id32, &txconfig, 5, 0.010, 2.0))
337 {
338 yWarning() << "EthResource::setTimingOfRunningCycle() for BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "could not configure: cycletime =" << txconfig.cycletime << "usec, RX DO TX = (" << txconfig.maxtimeRX << txconfig.maxtimeDO << txconfig.maxtimeTX << ") usec and TX rate =" << txconfig.txratedivider << " every cycle";
339 return false;
340 }
341 else
342 {
343 if(verbosewhenok)
344 {
345 yDebug() << "EthResource::setTimingOfRunningCycle() for BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "has succesfully set: cycletime =" << txconfig.cycletime << "usec, RX DO TX = (" << txconfig.maxtimeRX << txconfig.maxtimeDO << txconfig.maxtimeTX << ") usec and TX rate =" << txconfig.txratedivider << " every cycle";
346 }
347 }
348
349 txrateISset = true;
350
351
352 return(true);
353}
354
355
356bool EthResource::cleanBoardBehaviour(void)
357{
358 if(cleanedBoardBehaviour)
359 {
360 return(true);
361 }
362
363 // send a ...
364 if(false == serviceStop(eomn_serv_category_all))
365 {
366 yError() << "EthResource::cleanBoardBehaviour() cannot stop services for BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": cannot proceed any further";
367 return(false);
368 }
369
370 regularsAreSet = false;
371
372
373 if(verbosewhenok)
374 {
375 yDebug() << "EthResource::cleanBoardBehaviour() has cleaned the application in BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": config mode + cleared all its regulars";
376 }
377
378 cleanedBoardBehaviour = true;
379
380 return(true);
381
382}
383
384bool EthResource::testMultipleASK()
385{
386#if 1
387 return true;
388#else
389
390
391 // i ask multiple values such as:
392 eOprotID32_t id32_commstatus = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_comm, 0, eoprot_tag_mn_comm_status);
393 eOmn_comm_status_t value_commstatus = {0};
394
395 eOprotID32_t id32_applconfig = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_appl, 0, eoprot_tag_mn_appl_config);
396 eOmn_appl_config_t value_applconfig = {0};
397
398 eOprotID32_t id32_applconfig_txratedivider = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_appl, 0, eoprot_tag_mn_appl_config_txratedivider);
399 uint8_t txratedivider = 0;
400
401 std::vector<eOprotID32_t> id32s;
402 std::vector<void*> values;
403
404 id32s.push_back(id32_commstatus);
405 values.push_back(&value_commstatus);
406
407 id32s.push_back(id32_applconfig);
408 values.push_back(&value_applconfig);
409
410 id32s.push_back(id32_applconfig_txratedivider);
411 values.push_back(&txratedivider);
412
413 id32s.push_back(id32_applconfig_txratedivider);
414 values.push_back(&txratedivider);
415
416 id32s.push_back(id32_applconfig_txratedivider);
417 values.push_back(&txratedivider);
418
419 id32s.push_back(id32_applconfig_txratedivider);
420 values.push_back(&txratedivider);
421
422 id32s.push_back(id32_applconfig_txratedivider);
423 values.push_back(&txratedivider);
424
425 id32s.push_back(id32_applconfig_txratedivider);
426 values.push_back(&txratedivider);
427
428 id32s.push_back(id32_applconfig_txratedivider);
429 values.push_back(&txratedivider);
430
431 id32s.push_back(id32_applconfig_txratedivider);
432 values.push_back(&txratedivider);
433
435
436 double tprev = SystemClock::nowSystem();
437 double tcurr = SystemClock::nowSystem();
438
439 double delta = tcurr - tprev;
440
441 yDebug() << "before";
442 yDebug() << "value_commstatus.managementprotocolversion.major = " << value_commstatus.managementprotocolversion.major << "value_commstatus.managementprotocolversion.minor = " << value_commstatus.managementprotocolversion.minor;
443 yDebug() << "value_applconfig.cycletime = " << value_applconfig.cycletime << "value_applconfig.txratedivider" << value_applconfig.txratedivider << "etc";
444 yDebug() << "txratedivider = " << txratedivider;
445
446 tprev = SystemClock::nowSystem();
447 //bool ok = nvman.ask(&transceiver, id32s, values, 3.0);
448 bool ok = getRemoteValues(id32s, values, 3.0);
449 delta = SystemClock::nowSystem() - tprev;
450
451 yDebug() << "parallel mode: after" << delta << "seconds";
452 yDebug() << "value_commstatus.managementprotocolversion.major = " << value_commstatus.managementprotocolversion.major << "value_commstatus.managementprotocolversion.minor = " << value_commstatus.managementprotocolversion.minor;
453 yDebug() << "value_applconfig.cycletime = " << value_applconfig.cycletime << "value_applconfig.txratedivider" << value_applconfig.txratedivider << "etc";
454 yDebug() << "txratedivider = " << txratedivider;
455
456 memset(&value_commstatus, 0, sizeof(value_commstatus));
457 memset(&value_applconfig, 0, sizeof(value_applconfig));
458 txratedivider = 0;
459
460
461 tprev = SystemClock::nowSystem();
462 nvman.ask(&transceiver, id32_commstatus, &value_commstatus, 3.0);
463 nvman.ask(&transceiver, id32_applconfig, &value_applconfig, 3.0);
464 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
465 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
466 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
467 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
468 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
469 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
470 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
471 nvman.ask(&transceiver, id32_applconfig_txratedivider, &txratedivider, 3.0);
472 delta = SystemClock::nowSystem() - tprev;
473
474 yDebug() << "serial mode: after" << delta << "seconds";
475 yDebug() << "value_commstatus.managementprotocolversion.major = " << value_commstatus.managementprotocolversion.major << "value_commstatus.managementprotocolversion.minor = " << value_commstatus.managementprotocolversion.minor;
476 yDebug() << "value_applconfig.cycletime = " << value_applconfig.cycletime << "value_applconfig.txratedivider" << value_applconfig.txratedivider << "etc";
477 yDebug() << "txratedivider = " << txratedivider;
478
479 for(;;);
480
481
482 return true;
483
484#endif
485}
486
487bool EthResource::verifyEPprotocol(eOprot_endpoint_t ep)
488{
489 if((uint8_t)ep >= eoprot_endpoints_numberof)
490 {
491 yError() << "EthResource::verifyEPprotocol() called with wrong ep = " << ep << ": cannot proceed any further";
492 return(false);
493 }
494
495 if(true == verifiedEPprotocol[ep])
496 {
497 return(true);
498 }
499
500 if(false == verifyBoard())
501 {
502 yError() << "EthResource::verifyEPprotocol() cannot verify BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": cannot proceed any further";
503 return(false);
504 }
505
506 if(false == askBoardVersion())
507 {
508 yError() << "EthResource::verifyEPprotocol() cannot ask the version to BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": cannot proceed any further";
509 return(false);
510 }
511
512 testMultipleASK();
513
514
515 // 1. send a set<eoprot_tag_mn_comm_cmmnds_command_queryarray> and wait for the arrival of a sig<eoprot_tag_mn_comm_cmmnds_command_replyarray>
516 // the opc to send is eomn_opc_query_array_EPdes which will trigger a opc in reception eomn_opc_reply_array_EPdes
517 // 2. the resulting array will contains a eoprot_endpoint_descriptor_t item for the specifeid ep with the protocol version of the ems.
518
519
520
521 const double timeout = 0.100;
522
523 eOprotID32_t id2send = eo_prot_ID32dummy;
524 eOprotID32_t id2wait = eo_prot_ID32dummy;
525 eOmn_command_t command = {0};
526
527
528 // step 1: ask all the EP descriptors. from them we can extract protocol version of MN and of the target ep
529 id2send = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_comm, 0, eoprot_tag_mn_comm_cmmnds_command_queryarray);
530 memset(&command, 0, sizeof(command));
531 command.cmd.opc = eomn_opc_query_array_EPdes;
532 command.cmd.queryarray.opcpar.opc = eomn_opc_query_array_EPdes;
533 command.cmd.queryarray.opcpar.endpoint = eoprot_endpoint_all;
534 command.cmd.queryarray.opcpar.setnumber = 0;
535 command.cmd.queryarray.opcpar.setsize = 0;
536
537 // the semaphore must be retrieved using the id of the variable which is waited. in this case, it is the array of descriptors
538 id2wait = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_comm, 0, eoprot_tag_mn_comm_cmmnds_command_replyarray);
539
541
542 if(false == nvman.command(properties.ipv4addr, id2send, &command, id2wait, &command, timeout))
543 {
544 yError() << "EthResource::verifyEPprotocol() retrieve the endpoint descriptors from BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << ": cannot proceed any further";
545 return(false);
546 }
547
548 // the array is ...
549 eOmn_cmd_replyarray_t* cmdreplyarray = (eOmn_cmd_replyarray_t*)&command.cmd.replyarray;
550 EOarray* array = (EOarray*)cmdreplyarray->array;
551
552
553 uint8_t sizeofarray = eo_array_Size(array);
554
555
556 for(int i=0; i<sizeofarray; i++)
557 {
558 eoprot_endpoint_descriptor_t *epd = (eoprot_endpoint_descriptor_t*)eo_array_At(array, i);
559
560 if(epd->endpoint == eoprot_endpoint_management)
561 {
562 const eoprot_version_t * pc104versionMN = eoprot_version_of_endpoint_get(eoprot_endpoint_management);
563 if(pc104versionMN->major != epd->version.major)
564 {
565 yError() << "EthResource::verifyEPprotocol() for ep =" << eoprot_EP2string(epd->endpoint) << "detected: pc104.version.major =" << pc104versionMN->major << "and board.version.major =" << epd->version.major;
566 yError() << "EthResource::verifyEPprotocol() detected mismatching protocol version.major in BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "for eoprot_endpoint_management: cannot proceed any further.";
567 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update.";
568 return(false);
569 }
570 if(pc104versionMN->minor != epd->version.minor)
571 {
572 yError() << "EthResource::verifyEPprotocol() for ep =" << eoprot_EP2string(epd->endpoint) << "detected: pc104.version.minor =" << pc104versionMN->minor << "and board.version.minor =" << epd->version.minor;
573 yError() << "EthResource::verifyEPprotocol() detected mismatching protocol version.minor BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "for eoprot_endpoint_management: cannot proceed any further.";
574 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update.";
575 return false;
576 }
577 }
578 if(epd->endpoint == ep)
579 {
580 const eoprot_version_t * pc104versionEP = eoprot_version_of_endpoint_get(ep);
581 if(pc104versionEP->major != epd->version.major)
582 {
583 yError() << "EthResource::verifyEPprotocol() for ep =" << eoprot_EP2string(epd->endpoint) << "detected: pc104.version.major =" << pc104versionEP->major << "and board.version.major =" << epd->version.major;
584 yError() << "EthResource::verifyEPprotocol() detected mismatching protocol version.major in BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << " for" << eoprot_EP2string(ep) << ": cannot proceed any further.";
585 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update to offer services for" << eoprot_EP2string(ep);
586 return(false);
587 }
588 if(pc104versionEP->minor != epd->version.minor)
589 {
590 yError() << "EthResource::verifyEPprotocol() for ep =" << eoprot_EP2string(epd->endpoint) << "detected: pc104.version.minor =" << pc104versionEP->minor << "and board.version.minor =" << epd->version.minor;
591 yError() << "EthResource::verifyEPprotocol() detected mismatching protocol version.minor in BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << " for" << eoprot_EP2string(ep) << ": annot proceed any further";
592 yError() << "ACTION REQUIRED: BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "needs a FW update to offer services for" << eoprot_EP2string(ep);
593 return(false);
594 }
595 }
596 }
597
598 verifiedEPprotocol[ep] = true;
599
600 return(true);
601
602}
603
604
605
606bool EthResource::verifyBoard(void)
607{
608 if((true == verifyBoardPresence()) &&
609 (true == verifyBoardTransceiver()) &&
610 (true == cleanBoardBehaviour()) &&
611 (true == setTimingOfRunningCycle()) )
612 {
613 return(true);
614 }
615
616 return(false);
617}
618
619
620bool EthResource::verifyBoardPresence(void)
621{
622 if(verifiedBoardPresence)
623 {
624 return(true);
625 }
626
627 const double timeout = 1.00; // 1 sec is more than enough if board is present. if link is not on it is a good time to wait
628 const int retries = 20; // the number of retries depends on the above timeout and on link-up time of the EMS.
629
630 double start_time = yarp::os::Time::now();
631
633 verifiedBoardPresence = nvman.ping(properties.ipv4addr, boardMNprotocolversion, timeout, retries);
634
635 double end_time = yarp::os::Time::now();
636
637 if(true == verifiedBoardPresence)
638 {
639 verifiedBoardPresence = true;
640 if(verbosewhenok)
641 {
642 yDebug() << "EthResource::verifyBoardPresence() found BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "after" << end_time-start_time << "seconds";
643 }
644 }
645 else
646 {
647 yError() << "EthResource::verifyBoardPresence() DID NOT have replies from BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "after" << end_time-start_time << "seconds: CANNOT PROCEED ANY FURTHER";
648 }
649
650 return(verifiedBoardPresence);
651}
652
653
654bool EthResource::askBoardVersion(void)
655{
656
657 if(askedBoardVersion)
658 {
659 return(true);
660 }
661
662 const double timeout = 0.500; // 500 ms is more than enough if board is present. if link is not on it is a good time to wait
663
664 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_appl, 0, eoprot_tag_mn_appl_status);
665 eOmn_appl_status_t applstatus = {0};
666
668
669 askedBoardVersion = nvman.ask(properties.ipv4addr, id32, &applstatus, timeout);
670
671 if(false == askedBoardVersion)
672 {
673 yError() << "EthResource::askBoardVersion() cannot reach BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "w/ timeout of" << timeout << "seconds";
674 return false;
675 }
676
677
678 // now i store the ....
679
680 properties.firmwareversion.major = applstatus.version.major;
681 properties.firmwareversion.minor = applstatus.version.minor;
682
683
684 properties.firmwaredate.year = applstatus.buildate.year;
685 properties.firmwaredate.month = applstatus.buildate.month;
686 properties.firmwaredate.day = applstatus.buildate.day;
687 properties.firmwaredate.hour = applstatus.buildate.hour;
688 properties.firmwaredate.min = applstatus.buildate.min;
689
690 char versstr[32] = {0};
691 snprintf(versstr, sizeof(versstr), "ver %d.%d built on ", properties.firmwareversion.major, properties.firmwareversion.minor);
692 char datestr[32] = {0};
693 eo_common_date_to_string(properties.firmwaredate, datestr, sizeof(datestr));
694
695 properties.firmwareString = string(versstr) + string(datestr);
696
697
698 if(eobool_true == eoboards_is_eth((eObrd_type_t)applstatus.boardtype))
699 {
700 detectedBoardType = (eObrd_ethtype_t) applstatus.boardtype;
701 }
702 else
703 {
704 detectedBoardType = eobrd_ethtype_unknown;
705 }
706
707 if(detectedBoardType != properties.boardtype)
708 {
709 yWarning() << "EthResource::askBoardVersion(): detected wrong board. expecting" << properties.boardtypeString << "and detected" << eoboards_type2string2(eoboards_ethtype2type(detectedBoardType), eobool_true);
710 }
711
712
713 yInfo() << "EthResource::askBoardVersion() found BOARD" << properties.boardnameString << "@ IP" << properties.ipv4addrString << "of type" << properties.boardtypeString<< "with FW =" << properties.firmwareString;
714
715
716 return(askedBoardVersion);
717}
718
719
720bool EthResource::getRemoteValue(const eOprotID32_t id32, void *value, const double timeout, const unsigned int retries)
721{
722 bool replied = false;
723
724 double start_time = yarp::os::Time::now();
725
727
728 for(unsigned int numOfattempts=0; numOfattempts<(retries+1); numOfattempts++)
729 {
730 if(true == nvman.ask(&transceiver, id32, value, timeout))
731 {
732 replied = true;
733 // stop attempts
734 break;
735 }
736
737 if(!replied)
738 {
739 yWarning() << "EthResource::getRemoteValue() cannot have a reply from BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "at attempt #" << numOfattempts+1 << "w/ timeout of" << timeout << "seconds";
740 }
741
742 }
743
744 double end_time = yarp::os::Time::now();
745
746 if(false == replied)
747 {
748 yError() << " FATAL: EthResource::getRemoteValue() DID NOT have replies from BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << " even after" << end_time-start_time << "seconds: CANNOT PROCEED ANY FURTHER";
749 }
750
751 return replied;
752}
753
754
755bool EthResource::getRemoteValues(const std::vector<eOprotID32_t> &id32s, const std::vector<void*> &values, const double timeout)
756{
758
759 double start_time = yarp::os::Time::now();
760
761 bool replied = nvman.ask(&transceiver, id32s, values, timeout);
762
763 double end_time = yarp::os::Time::now();
764
765 if(false == replied)
766 {
767 yError() << " FATAL: EthResource::getRemoteValues() DID NOT have replies from BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << " even after" << end_time-start_time << "seconds: CANNOT PROCEED ANY FURTHER";
768 }
769
770 return replied;
771}
772
773
774bool EthResource::setRemoteValue(const eOprotID32_t id32, void *value)
775{
777 return nvman.set(properties.ipv4addr, id32, value);
778}
779
780bool EthResource::setcheckRemoteValue(const eOprotID32_t id32, void *value, const unsigned int retries, const double waitbeforecheck, const double timeout)
781{
783 return nvman.setcheck(properties.ipv4addr, id32, value, retries, waitbeforecheck, timeout);
784}
785
786bool EthResource::CANPrintHandler(eOmn_info_basic_t *infobasic)
787{
788 char str[256];
789 char canfullmessage[128];
790
791 static const char * sourcestrings[] =
792 {
793 "LOCAL",
794 "CAN1",
795 "CAN2",
796 "UNKNOWN"
797 };
798 int source = EOMN_INFO_PROPERTIES_FLAGS_get_source(infobasic->properties.flags);
799 const char * str_source = (source > eomn_info_source_can2) ? (sourcestrings[3]) : (sourcestrings[source]);
800 uint16_t address = EOMN_INFO_PROPERTIES_FLAGS_get_address(infobasic->properties.flags);
801 uint8_t *p64 = (uint8_t*)&(infobasic->properties.par64);
802
803 int msg_id = (p64[1]&0xF0) >> 4;
804
805 uint32_t sec = infobasic->timestamp / 1000000;
806 uint32_t msec = (infobasic->timestamp % 1000000) / 1000;
807 uint32_t usec = infobasic->timestamp % 1000;
808
809 const char *boardstr = properties.boardnameString.c_str();
810
811 // Validity check
812 if(address > 15)
813 {
814 snprintf(canfullmessage, sizeof(canfullmessage), "Error while parsing the message: CAN address detected is out of allowed range");
815 snprintf(str, sizeof(str), "from BOARD %s (%s), src %s, adr %d, time %ds %dm %du: CAN PRINT MESSAGE[id %d] -> %s",
816 properties.ipv4addrString.c_str(),
817 boardstr,
818 str_source,
819 address,
820 sec,
821 msec,
822 usec,
823 msg_id,
824 canfullmessage
825 );
826 feat_PrintError(str);
827 }
828 else
829 {
830 // Initialization needed?
831 if (c_string_handler[address] == NULL)
832 c_string_handler[address] = new can_string_eth();
833
834 CanFrame can_msg;
835 can_msg.setCanData(infobasic->properties.par64);
836 can_msg.setId(msg_id);
837 can_msg.setSize(infobasic->properties.par16);
838 int ret = c_string_handler[address]->add_string(&can_msg);
839
840 // String finished?
841 if (ret != -1)
842 {
843 char* themsg = c_string_handler[address]->get_string(ret);
844 memcpy(canfullmessage, themsg, sizeof(canfullmessage));
845 canfullmessage[63] = 0;
846 c_string_handler[address]->clear_string(ret);
847
848 snprintf(str,sizeof(str), "from BOARD %s (%s), src %s, adr %d, time %ds %dm %du: CAN PRINT MESSAGE[id %d] -> %s",
849 properties.ipv4addrString.c_str(),
850 boardstr,
851 str_source,
852 address,
853 sec,
854 msec,
855 usec,
856 msg_id,
857 canfullmessage
858 );
859 feat_PrintInfo(str);
860 }
861 }
862 return true;
863}
864
865
866bool EthResource::serviceCommand(eOmn_serv_operation_t operation, eOmn_serv_category_t category, const eOmn_serv_parameter_t* param, double timeout, int times)
867{
868 eOprotID32_t id2send = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_service, 0, eoprot_tag_mn_service_cmmnds_command);
869 eOprotID32_t id2wait = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_service, 0, eoprot_tag_mn_service_status_commandresult);
870
871 eOmn_service_cmmnds_command_t command = {0};
872 eOmn_service_command_result_t result = {0};
873
874 command.operation = operation;
875 command.category = category;
876 if(NULL != param)
877 {
878 memcpy(&command.parameter, param, sizeof(eOmn_serv_parameter_t));
879 }
880 else
881 {
882 memset(&command.parameter, 0, sizeof(eOmn_serv_parameter_t));
883 if((eomn_serv_operation_regsig_load == operation) || ((eomn_serv_operation_regsig_clear == operation)))
884 { // we send an empty array
885 eo_array_New(eOmn_serv_capacity_arrayof_id32, 4, &command.parameter.arrayofid32);
886 }
887 else
888 {
889 command.parameter.configuration.type = eomn_serv_NONE;
890 }
891 }
892
894
895
896 bool replied = false;
897 for(int i=0; i<times; i++)
898 {
899 if(true == nvman.command(properties.ipv4addr, id2send, &command, id2wait, &result, timeout))
900 {
901 replied = true;
902 break;
903 }
904 }
905
906 if(false == replied)
907 {
908 yError() << "EthResource::serviceCommand() failed an acked activation request to BOARD" << getProperties().boardnameString << "with IP" << getProperties().ipv4addrString << "after" << times << "attempts" << "each with waiting timeout of" << timeout << "seconds";
909 return false;
910 }
911
912 //yDebug() << "result is:" << result.latestcommandisok;
913
914 return(result.latestcommandisok);
915}
916
917
918bool EthResource::serviceVerifyActivate(eOmn_serv_category_t category, const eOmn_serv_parameter_t* param, double timeout)
919{
920 return(serviceCommand(eomn_serv_operation_verifyactivate, category, param, timeout, 3));
921}
922
923
924bool EthResource::serviceSetRegulars(eOmn_serv_category_t category, vector<eOprotID32_t> &id32vector, double timeout)
925{
926 eOmn_serv_parameter_t param = {0};
927 EOarray *array = eo_array_New(eOmn_serv_capacity_arrayof_id32, 4, &param.arrayofid32);
928 for(int i=0; i<id32vector.size(); i++)
929 {
930 eOprotID32_t id32 = id32vector.at(i);
931 eo_array_PushBack(array, &id32);
932 }
933
934 regularsAreSet = serviceCommand(eomn_serv_operation_regsig_load, category, &param, timeout, 3);
935
936 return regularsAreSet;
937}
938
939
940
941bool EthResource::serviceStart(eOmn_serv_category_t category, double timeout)
942{
943 bool ret = serviceCommand(eomn_serv_operation_start, category, NULL, timeout, 3);
944
945 if(ret)
946 {
947 isInRunningMode = true;
948 }
949
950 return ret;
951}
952
953
954bool EthResource::serviceStop(eOmn_serv_category_t category, double timeout)
955{
956 bool ret = serviceCommand(eomn_serv_operation_stop, category, NULL, timeout, 3);
957
958 if(ret && (category == eomn_serv_category_all))
959 {
960 regularsAreSet = false;
961 }
962
963 //#warning TODO: the result for command stop shall also tell if the the board is in running mode or not.
964 return ret;
965}
966
967
968// new methods from host transceiver
969
970bool EthResource::getLocalValue(const eOprotID32_t id32, void *data)
971{
972 return transceiver.read(id32, data);
973}
974
975
976bool EthResource::setLocalValue(eOprotID32_t id32, const void *value, bool overrideROprotection)
977{
978 return transceiver.write(id32, value, overrideROprotection);
979}
980
981
983{
984 return false;
985}
986
988{
989 return &transceiver;
990}
991
992// eof
993
994
995
996
997
998
999
@ data
void setSize(uint8_t size)
void setId(uint16_t id)
void setCanData(uint64_t data)
char * get_string(int buffer_num)
int add_string(CanFrame *can_packet)
Process a string can packet.
void clear_string(int buffer_num)
Resets the string buffer.
void config(const Config &cfg)
bool getRemoteValues(const std::vector< eOprotID32_t > &id32s, const std::vector< void * > &values, const double timeout=0.500)
const void * getUDPtransmit(eOipv4addressing_t &destination, size_t &sizeofpacket, uint16_t &numofrops)
bool processRXpacket(const void *data, size_t size)
HostTransceiver * getTransceiver()
bool getLocalValue(const eOprotID32_t id32, void *value)
bool serviceSetRegulars(eOmn_serv_category_t category, vector< eOprotID32_t > &id32vector, double timeout=0.500)
bool open2(eOipv4addr_t remIP, yarp::os::Searchable &cfgtotal)
bool serviceStop(eOmn_serv_category_t category, double timeout=0.500)
bool verifyEPprotocol(eOprot_endpoint_t ep)
bool getRemoteValue(const eOprotID32_t id32, void *value, const double timeout=0.100, const unsigned int retries=0)
bool setLocalValue(eOprotID32_t id32, const void *value, bool overrideROprotection=false)
bool setRemoteValue(const eOprotID32_t id32, void *value)
bool setcheckRemoteValue(const eOprotID32_t id32, void *value, const unsigned int retries=10, const double waitbeforecheck=0.001, const double timeout=0.050)
bool serviceVerifyActivate(eOmn_serv_category_t category, const eOmn_serv_parameter_t *param, double timeout=0.500)
const Properties & getProperties()
bool serviceStart(eOmn_serv_category_t category, double timeout=0.500)
bool CANPrintHandler(eOmn_info_basic_t *infobasic)
static TheEthManager * instance()
const eOipv4addressing_t & getLocalIPV4addressing(void)
static theNVmanager & getInstance()
bool setcheck(const eOprotIP_t ipv4, const eOprotID32_t id32, const void *value, const unsigned int retries=10, double waitbeforecheck=0.001, double timeout=0.5)
bool ask(const eOprotIP_t ipv4, const eOprotID32_t id32, void *value, const double timeout=0.5)
bool command(const eOprotIP_t ipv4, const eOprotID32_t id32cmd, const void *cmd, const eOprotID32_t id32rep, void *rep, double timeout=0.5)
bool ping(const eOprotIP_t ipv4, eoprot_version_t &mnprotversion, const double timeout=0.5, const unsigned int retries=20)
bool set(const eOprotIP_t ipv4, const eOprotID32_t id32, const void *value)
bool write(const eOprotID32_t id32, const void *data, bool forcewriteOfReadOnly)
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 read(const eOprotID32_t id32, void *data)
void feat_PrintInfo(char *string)
void feat_PrintError(char *string)
bool read(yarp::os::Searchable &cfgtotal, pc104Data &pc104data)
Definition ethParser.cpp:92
bool print(const pc104Data &pc104data)
Definition ethParser.cpp:57
grid on
double monitorpresence_periodofmissingreport
Definition ethParser.h:74
boardActions actions
Definition ethParser.h:89
boardProperties properties
Definition ethParser.h:87
boardSettings settings
Definition ethParser.h:88
eOipv4addressing_t ipv4addressing
Definition ethParser.h:39
std::string ipv4addressingstring
Definition ethParser.h:43
eOmn_appl_config_t txconfig
Definition ethParser.h:59