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