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  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 
86 EthResource::~EthResource()
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 
101 bool EthResource::lock(bool on)
102 {
103  if(true == on)
104  objLock.lock();
105  else
106  objLock.unlock();
107 
108  return true;
109 }
110 
111 
112 bool 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 
121  eth::parser::boardData brddata;
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;
131  properties.ipv4addressingString = brddata.properties.ipv4addressingstring;
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 
176 bool EthResource::close()
177 {
178  yTrace();
179  return false;
180 }
181 
182 
183 const 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 
203 bool EthResource::Tick()
204 {
205  monitorpresence.tick();
206  return true;
207 }
208 
209 
210 bool EthResource::Check()
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 
222 bool EthResource::processRXpacket(const void *data, const size_t size)
223 {
224  return transceiver.parseUDP(data, size);
225 }
226 
227 
228 const AbstractEthResource::Properties & EthResource::getProperties()
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 
242 bool EthResource::isRunning(void)
243 {
244  return(isInRunningMode);
245 }
246 
247 
248 
249 bool 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 
268  theNVmanager& nvman = theNVmanager::getInstance();
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 
319 bool 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 
334  theNVmanager& nvman = theNVmanager::getInstance();
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 
356 bool 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 
384 bool 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 
434  theNVmanager& nvman = theNVmanager::getInstance();
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 
487 bool 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 
540  theNVmanager& nvman = theNVmanager::getInstance();
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 
606 bool 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 
620 bool 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 
632  theNVmanager& nvman = theNVmanager::getInstance();
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 
654 bool 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 
667  theNVmanager& nvman = theNVmanager::getInstance();
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 
720 bool 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 
726  theNVmanager& nvman = theNVmanager::getInstance();
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 
755 bool EthResource::getRemoteValues(const std::vector<eOprotID32_t> &id32s, const std::vector<void*> &values, const double timeout)
756 {
757  theNVmanager& nvman = theNVmanager::getInstance();
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 
774 bool EthResource::setRemoteValue(const eOprotID32_t id32, void *value)
775 {
776  theNVmanager& nvman = theNVmanager::getInstance();
777  return nvman.set(properties.ipv4addr, id32, value);
778 }
779 
780 bool EthResource::setcheckRemoteValue(const eOprotID32_t id32, void *value, const unsigned int retries, const double waitbeforecheck, const double timeout)
781 {
782  theNVmanager& nvman = theNVmanager::getInstance();
783  return nvman.setcheck(properties.ipv4addr, id32, value, retries, waitbeforecheck, timeout);
784 }
785 
786 bool 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 
866 bool 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 
893  theNVmanager& nvman = theNVmanager::getInstance();
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 
918 bool 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 
924 bool 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 
941 bool 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 
954 bool 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 
970 bool EthResource::getLocalValue(const eOprotID32_t id32, void *data)
971 {
972  return transceiver.read(id32, data);
973 }
974 
975 
976 bool EthResource::setLocalValue(eOprotID32_t id32, const void *value, bool overrideROprotection)
977 {
978  return transceiver.write(id32, value, overrideROprotection);
979 }
980 
981 
982 bool EthResource::isFake()
983 {
984  return false;
985 }
986 
987 HostTransceiver * EthResource::getTransceiver()
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)
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:74
boardActions actions
Definition: ethParser.h:89
boardProperties properties
Definition: ethParser.h:87
boardSettings settings
Definition: ethParser.h:88
eObrd_ethtype_t type
Definition: ethParser.h:40
eOipv4addressing_t ipv4addressing
Definition: ethParser.h:39
std::string ipv4addressingstring
Definition: ethParser.h:43
eOmn_appl_config_t txconfig
Definition: ethParser.h:59