iCub-main
ethParser.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 /*
5  * Copyright (C) 2017 iCub Facility - Istituto Italiano di Tecnologia
6  * Author: Marco Accame
7  * email: marco.accame@iit.it
8  * website: www.robotcub.org
9  * Permission is granted to copy, distribute, and/or modify this program
10  * under the terms of the GNU General Public License, version 2 or any
11  * later version published by the Free Software Foundation.
12  *
13  * A copy of the license can be found at
14  * http://www.robotcub.org/icub/license/gpl.txt
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
19  * Public License for more details
20 */
21 
22 
23 // --------------------------------------------------------------------------------------------------------------------
24 // - public interface
25 // --------------------------------------------------------------------------------------------------------------------
26 
27 #include "ethParser.h"
28 
29 
30 
31 // --------------------------------------------------------------------------------------------------------------------
32 // - external dependencies
33 // --------------------------------------------------------------------------------------------------------------------
34 
35 
36 #include <yarp/os/Log.h>
37 #include <yarp/os/LogStream.h>
38 using yarp::os::Log;
39 
40 #include <yarp/os/Bottle.h>
41 #include <yarp/os/Value.h>
42 
43 using namespace yarp::os;
44 
45 
46 // --------------------------------------------------------------------------------------------------------------------
47 // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++
48 // --------------------------------------------------------------------------------------------------------------------
49 
50 
51 
52 // --------------------------------------------------------------------------------------------------------------------
53 // - the class
54 // --------------------------------------------------------------------------------------------------------------------
55 
56 
57 bool eth::parser::print(const pc104Data &pc104data)
58 {
59 
60  yDebug() << "eth::parser::print(pc104Data) for PC104:";
61 
62  yDebug() << "PC104/PC104IpAddress:PC104IpPort = " << pc104data.addressingstring;
63  yDebug() << "PC104/PC104TXrate = " << pc104data.txrate;
64  yDebug() << "PC104/PC104RXrate = " << pc104data.rxrate;
65 
66  return true;
67 }
68 
69 bool eth::parser::print(const boardData &boarddata)
70 {
71 
72  yDebug() << "eth::parser::print(boardData) for BOARD" << boarddata.settings.name;
73 
74  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES:";
75  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES/IpAddress = " << boarddata.properties.ipv4string;
76  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES/IpPort = " << boarddata.properties.ipv4addressing.port;
77  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES/Type = " << boarddata.properties.typestring;
78  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES/maxSizeRXpacket = " << boarddata.properties.maxSizeRXpacket;
79  yDebug() << "ETH_BOARD/ETH_BOARD_PROPERTIES/maxSizeROP = " << boarddata.properties.maxSizeROP;
80 
81  yDebug() << "ETH_BOARD/ETH_BOARD_SETTINGS:";
82  yDebug() << "ETH_BOARD/ETH_BOARD_SETTINGS/Name = " << boarddata.settings.name;
83  yDebug() << "ETH_BOARD/ETH_BOARD_SETTINGS/RUNNINGMODE/(period, maxTimeOfRXactivity, maxTimeOfDOactivity, maxTimeOfTXactivity, TXrateOfRegularROPs) = " <<
84  boarddata.settings.txconfig.cycletime << boarddata.settings.txconfig.maxtimeRX << boarddata.settings.txconfig.maxtimeDO << boarddata.settings.txconfig.maxtimeTX << boarddata.settings.txconfig.txratedivider;
85  yDebug() << "ETH_BOARD/ETH_BOARD_ACTIONS/MONITOR_ITS_PRESENCE";
86  yDebug() << "ETH_BOARD/ETH_BOARD_ACTIONS/MONITOR_ITS_PRESENCE/(enabled, timeout, periodOfMissingReport) = " <<
88 
89  return true;
90 }
91 
92 bool eth::parser::read(yarp::os::Searchable &cfgtotal, pc104Data &pc104data)
93 {
94  pc104data.setdefault();
95 
96  Bottle groupDEBUG = cfgtotal.findGroup("DEBUG");
97  if ((! groupDEBUG.isNull()) && (groupDEBUG.check("embBoardsConnected")))
98  {
99  pc104data.embBoardsConnected = groupDEBUG.find("embBoardsConnected").asBool();
100  }
101 
102  if(!pc104data.embBoardsConnected)
103  {
104  yDebug() << "ATTENTION: NO EMBEDDED BOARDS CONNECTED. YOU ARE IN DEBUG MODE";
105  }
106 
107  // localaddress
108 
109  Bottle groupPC104 = Bottle(cfgtotal.findGroup("PC104"));
110  if (groupPC104.isNull())
111  {
112  yError() << "eth::parser::read() cannot find PC104 group in config files";
113  return false;
114  }
115 
116  Value *value;
117 
118  if (!groupPC104.check("PC104IpAddress", value))
119  {
120  yError() << "eth::parser::read(): missing PC104/PC104IpAddress in config files";
121  return false;
122  }
123  if (!groupPC104.check("PC104IpPort", value))
124  {
125  yError() << "eth::parser::read(): missing PC104/PC104IpPort in config files";
126  return false;
127  }
128 
129  Bottle paramIPaddress(groupPC104.find("PC104IpAddress").asString());
130  uint16_t port = groupPC104.find("PC104IpPort").asInt32(); // .get(1).asInt32();
131  char strIP[64] = {0};
132 
133 
134  snprintf(strIP, sizeof(strIP), "%s", paramIPaddress.toString().c_str());
135  // strIP is now "10.0.1.104" ... i want to remove the "".... VERY IMPORTANT: use \" in sscanf
136  int ip1, ip2, ip3, ip4;
137  sscanf(strIP, "\"%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
138 
139  pc104data.localaddressing.addr = eo_common_ipv4addr(ip1, ip2, ip3, ip4);
140  pc104data.localaddressing.port = port;
141 
142  char ss[30];
143  snprintf(ss, sizeof(ss), "%d.%d.%d.%d:%d", ip1, ip2, ip3, ip4, port);
144 
145  pc104data.addressingstring = ss;
146 
147 
148  // txrate
149  if(cfgtotal.findGroup("PC104").check("PC104TXrate"))
150  {
151  int value = cfgtotal.findGroup("PC104").find("PC104TXrate").asInt32();
152  if(value > 0)
153  {
154  pc104data.txrate = value;
155  }
156  }
157  else
158  {
159  yWarning () << "eth::parser::read() cannot find ETH/PC104TXrate. thus using default value" << pc104data.txrate;
160  }
161 
162  // rxrate
163  if(cfgtotal.findGroup("PC104").check("PC104RXrate"))
164  {
165  int value = cfgtotal.findGroup("PC104").find("PC104RXrate").asInt32();
166  if(value > 0)
167  {
168  pc104data.rxrate = value;
169  }
170  }
171  else
172  {
173  yWarning () << "eth::parser::read() cannot find ETH/PC104RXrate. thus using default value" << pc104data.rxrate;
174  }
175 
176  // now i print all the found values
177 
178  //print(pc104data);
179 
180  return true;
181 }
182 
183 
184 bool eth::parser::read(yarp::os::Searchable &cfgtotal, boardData &boarddata)
185 {
186  Bottle groupEthBoard = Bottle(cfgtotal.findGroup("ETH_BOARD"));
187  if(groupEthBoard.isNull())
188  {
189  yError() << "eth::parser::read() cannot find ETH_BOARD group in config files";
190  return false;
191  }
192  Bottle groupEthBoardProps = Bottle(groupEthBoard.findGroup("ETH_BOARD_PROPERTIES"));
193  if(groupEthBoardProps.isNull())
194  {
195  yError() << "eth::parser::read() cannot find ETH_BOARD_PROPERTIES group in config files";
196  return false;
197  }
198  Bottle groupEthBoardSettings = Bottle(groupEthBoard.findGroup("ETH_BOARD_SETTINGS"));
199  if(groupEthBoardSettings.isNull())
200  {
201  yError() << "eth::parser::read() cannot find ETH_BOARD_PROPERTIES group in config files";
202  return false;
203  }
204 
205  // -> ETH_BOARD/ETH_BOARD_PROPERTIES
206 
207  boarddata.properties.reset();
208 
209  // IpAddress:
210  if(true == groupEthBoardProps.check("IpAddress"))
211  {
212  Bottle paramIPboard(groupEthBoardProps.find("IpAddress").asString());
213  char str[64] = {0};
214  strcpy(str, paramIPboard.toString().c_str());
215  int ip1, ip2, ip3, ip4;
216  sscanf(str, "\"%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
217  boarddata.properties.ipv4addressing.addr = eo_common_ipv4addr(ip1, ip2, ip3, ip4);
218  }
219  else
220  {
221  yError() << "eth::parser::read() cannot find ETH_BOARD_PROPERTIES/IpAddress group in config files";
222  return false;
223  }
224 
225  char ipinfo[20] = {0};
226  eo_common_ipv4addr_to_string(boarddata.properties.ipv4addressing.addr, ipinfo, sizeof(ipinfo));
227  boarddata.properties.ipv4string = ipinfo;
228 
229 
230  // IpPort:
231  if(true == groupEthBoardProps.check("IpPort"))
232  {
233  boarddata.properties.ipv4addressing.port = groupEthBoardProps.find("IpPort").asInt32();;
234  }
235  else
236  {
237  boarddata.properties.ipv4addressing.port = 12345;
238  yWarning() << "eth::parser::read() cannot find ETH_BOARD_PROPERTIES/IpPort group in config files." << " using:" << boarddata.properties.ipv4addressing.port;
239  }
240 
241  snprintf(ipinfo, sizeof(ipinfo), ":%d", boarddata.properties.ipv4addressing.port);
242  boarddata.properties.ipv4addressingstring = boarddata.properties.ipv4string + ipinfo;
243 
244 
245  // Type:
246  Bottle b_ETH_BOARD_PROPERTIES_Type = groupEthBoardProps.findGroup("Type");
247  std::string Type = b_ETH_BOARD_PROPERTIES_Type.get(1).asString();
248  const char *strType = Type.c_str();
249  // 1. compare with the exceptions which may be in some old xml files ("EMS4", "MC4PLUS", "MC2PLUS"), and then then call proper functions
250  if(0 == strcmp(strType, "EMS4"))
251  {
252  boarddata.properties.type = eobrd_ethtype_ems4;
253  }
254  else if(0 == strcmp(strType, "MC4PLUS"))
255  {
256  boarddata.properties.type = eobrd_ethtype_mc4plus;
257  }
258  else if(0 == strcmp(strType, "MC2PLUS"))
259  {
260  boarddata.properties.type = eobrd_ethtype_mc2plus;
261  }
262  else
263  {
264  eObrd_type_t brd = eobrd_unknown;
265  if(eobrd_unknown == (brd = eoboards_string2type2(strType, eobool_true)))
266  {
267  brd = eoboards_string2type2(strType, eobool_false);
268  }
269 
270  // if not found in compact or extended string format, we accept that the board is unknown
271 
272  boarddata.properties.type = eoboards_type2ethtype(brd);
273  }
274  char boardTypeString[30];
275  snprintf(boardTypeString, sizeof(boardTypeString), "%s", eoboards_type2string2(eoboards_ethtype2type(boarddata.properties.type), eobool_true));
276 
277  boarddata.properties.typestring = boardTypeString;
278 
279  // maxSizeRXpacket:
280  if(true == groupEthBoardProps.check("maxSizeRXpacket"))
281  {
282  boarddata.properties.maxSizeRXpacket = groupEthBoardProps.find("maxSizeRXpacket").asInt32();
283  //yDebug() << "eth::parser::read() has detected capacityofTXpacket =" << boarddata.properties.maxSizeRXpacket << "for BOARD w/ IP" << boarddata.properties.ipv4string;
284  }
285  else
286  {
287  boarddata.properties.maxSizeRXpacket = 768;
288  yWarning() << "eth::parser::read() in BOARD w/ IP" << boarddata.properties.ipv4string << "cannot find: capacityofTXpacket. using:" << boarddata.properties.maxSizeRXpacket;
289  }
290 
291  // maxSizeROP:
292  if(true == groupEthBoardProps.check("maxSizeROP"))
293  {
294  boarddata.properties.maxSizeROP = groupEthBoardProps.find("maxSizeROP").asInt32();
295  //yDebug() << "eth::parser::read() has detected maxSizeOfROP =" << boarddata.properties.maxSizeROP << "for BOARD w/ IP" << boarddata.properties.ipv4string;
296  }
297  else
298  {
299  boarddata.properties.maxSizeROP = 384;
300  yWarning() << "eth::parser::read() in BOARD w/ IP" << boarddata.properties.ipv4string << "cannot find: maxSizeROP. using:" << boarddata.properties.maxSizeROP;
301  }
302 
303 
304 
305  // <- ETH_BOARD/ETH_BOARD_PROPERTIES
306 
307 
308  // -> ETH_BOARD/ETH_BOARD_SETTINGS
309 
310  Bottle paramNameBoard(groupEthBoardSettings.find("Name").asString());
311  char xmlboardname[64] = {0};
312  snprintf(xmlboardname, sizeof(xmlboardname), "%s", paramNameBoard.toString().c_str());
313 
314 
315  if(0 != strlen(xmlboardname))
316  {
317  boarddata.settings.name = xmlboardname;
318  }
319  else
320  {
321  boarddata.settings.name = "NOT-NAMED";
322  }
323 
324 
325  // -> ETH_BOARD/ETH_BOARD_SETTINGS/RUNNINGMODE
326 
327  Bottle groupEthBoardSettings_RunningMode = Bottle(groupEthBoardSettings.findGroup("RUNNINGMODE"));
328  if(groupEthBoardSettings_RunningMode.isNull())
329  {
330  yWarning() << "eth::parser::read(): cannot find ETH_BOARD_PROPERTIES/RUNNINGMODE group in config files for BOARD w/ IP" << boarddata.properties.ipv4string << " and will use default values";
331  yWarning() << "Default values for ETH_BOARD_PROPERTIES/RUNNINGMODE group: (period, maxTimeOfRXactivity, maxTimeOfDOactivity, maxTimeOfTXactivity, TXrateOfRegularROPs) = " <<
332  boarddata.settings.txconfig.cycletime << boarddata.settings.txconfig.maxtimeRX << boarddata.settings.txconfig.maxtimeDO << boarddata.settings.txconfig.maxtimeTX << boarddata.settings.txconfig.txratedivider;
333  }
334  else
335  {
336 
337  if(true == groupEthBoardSettings_RunningMode.check("period"))
338  {
339  int tmp = groupEthBoardSettings_RunningMode.find("period").asInt32();
340 
341  if(1000 != tmp)
342  {
343  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::period can be only 1000 (so far) and it was:" << tmp;
344  tmp = 1000;
345  }
346  boarddata.settings.txconfig.cycletime = tmp;
347  }
348 
349  if(true == groupEthBoardSettings_RunningMode.check("maxTimeOfRXactivity"))
350  {
351  int tmp = groupEthBoardSettings_RunningMode.find("maxTimeOfRXactivity").asInt32();
352 
353  if((tmp < 5) || (tmp > 990))
354  {
355  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::maxTimeOfRXactivity must be in [5, 990] (so far) and it was:" << tmp << "Using default value";
356  tmp = 400;
357  }
358 
359  boarddata.settings.txconfig.maxtimeRX = tmp;
360  }
361 
362  if(true == groupEthBoardSettings_RunningMode.check("maxTimeOfDOactivity"))
363  {
364  int tmp = groupEthBoardSettings_RunningMode.find("maxTimeOfDOactivity").asInt32();
365 
366  if((tmp < 5) || (tmp > 990))
367  {
368  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::maxtimeOfDOactivity must be in [5, 990] (so far) and it was:" << tmp << "Using default value";
369  tmp = 300;
370  }
371 
372  boarddata.settings.txconfig.maxtimeDO = tmp;
373  }
374 
375  if(true == groupEthBoardSettings_RunningMode.check("maxTimeOfTXactivity"))
376  {
377  int tmp = groupEthBoardSettings_RunningMode.find("maxTimeOfTXactivity").asInt32();
378 
379  if((tmp < 5) || (tmp > 990))
380  {
381  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::maxTimeOfTXactivity must be in [5, 990] (so far) and it was:" << tmp << "Using default value";
382  tmp = 300;
383  }
384 
385  boarddata.settings.txconfig.maxtimeTX = tmp;
386  }
387 
388 
389  if(true == groupEthBoardSettings_RunningMode.check("TXrateOfRegularROPs"))
390  {
391  int tmp = groupEthBoardSettings_RunningMode.find("TXrateOfRegularROPs").asInt32();
392 
393  if(tmp <=0)
394  {
395  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::TXrateOfRegularROPs must be in [1, 20] and it was:" << tmp << "Using value = 1";
396  tmp = 1;
397  }
398  if(tmp >200)
399  {
400  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "ETH_BOARD_SETTINGS::RUNNINGMODE::TXrateOfRegularROPs must be in [1, 20] and it was:" << tmp << "Using value = 20";
401  tmp = 20;
402  }
403  boarddata.settings.txconfig.txratedivider = tmp;
404  }
405 
406  // consistency check
407  if((boarddata.settings.txconfig.maxtimeRX+boarddata.settings.txconfig.maxtimeDO+boarddata.settings.txconfig.maxtimeTX) != boarddata.settings.txconfig.cycletime)
408  {
409  yWarning() << "eth::parser::read() for BOARD" << boarddata.properties.ipv4string << "In ETH_BOARD_SETTINGS::RUNNINGMODE sum(maxTimeOfRXactivity, maxTimeOfDOactivity, maxTimeOfTXactivity) != period !!! Using default values";
410 
411  yError() << boarddata.settings.txconfig.maxtimeRX+boarddata.settings.txconfig.maxtimeDO+boarddata.settings.txconfig.maxtimeTX;
412  boarddata.settings.txconfig.cycletime = 1000;
413  boarddata.settings.txconfig.maxtimeRX = 400;
414  boarddata.settings.txconfig.maxtimeDO = 300;
415  boarddata.settings.txconfig.maxtimeTX = 300;
416  }
417 
418  }
419 
420 
421 
422  // <- ETH_BOARD/ETH_BOARD_SETTINGS/RUNNINGMODE
423 
424 
425  // <- ETH_BOARD/ETH_BOARD_SETTINGS
426 
427 
428  // -> ETH_BOARD/ETH_BOARD_ACTIONS
429  // -> ETH_BOARD/ETH_BOARD_ACTIONS/MONITOR_ITS_PRESENCE
430 
431 
432  // do we have a proper section ETH_BOARD_ACTIONS/MONITOR_ITS_PRESENCE? if so we change its config
433 
434  Bottle groupEthBoardActions = Bottle(groupEthBoard.findGroup("ETH_BOARD_ACTIONS"));
435  if(!groupEthBoardActions.isNull())
436  {
437  Bottle groupEthBoardActions_Monitor = Bottle(groupEthBoardActions.findGroup("MONITOR_ITS_PRESENCE"));
438  if(!groupEthBoardActions_Monitor.isNull())
439  {
440  Bottle groupEthBoardActions_Monitor_enabled = groupEthBoardActions_Monitor.findGroup("enabled");
441  std::string Ena = groupEthBoardActions_Monitor_enabled.get(1).asString();
442  const char *strEna = Ena.c_str();
443 
444  if(0 == strcmp(strEna, "true"))
445  {
446  boarddata.actions.monitorpresence_enabled = true;
447  }
448  else
449  {
450  boarddata.actions.monitorpresence_enabled = false;
451  }
452 
453  if(true == groupEthBoardActions_Monitor.check("timeout"))
454  {
455  double presenceTimeout = groupEthBoardActions_Monitor.find("timeout").asFloat64();
456 
457  if(presenceTimeout <= 0)
458  {
459  presenceTimeout = 0;
460  boarddata.actions.monitorpresence_enabled = false;
461  }
462 
463  if(presenceTimeout > 0.100)
464  {
465  presenceTimeout = 0.100;
466  }
467 
468  boarddata.actions.monitorpresence_timeout = presenceTimeout;
469 
470  }
471 
472 
473  if(true == groupEthBoardActions_Monitor.check("periodOfMissingReport"))
474  {
475  double reportMissingPeriod = groupEthBoardActions_Monitor.find("periodOfMissingReport").asFloat64();
476 
477  if(reportMissingPeriod <= 0)
478  {
479  reportMissingPeriod = 0.0;
480  }
481 
482  if(reportMissingPeriod > 600)
483  {
484  reportMissingPeriod = 600;
485  }
486 
487  boarddata.actions.monitorpresence_periodofmissingreport = reportMissingPeriod;
488  }
489  }
490  }
491 
492  // <- ETH_BOARD/ETH_BOARD_ACTIONS/MONITOR_ITS_PRESENCE
493  // <- ETH_BOARD/ETH_BOARD_ACTIONS
494 
495  return true;
496 }
497 
498 
499 // - end-of-file (leave a blank line after)----------------------------------------------------------------------------
500 
501 
bool read(yarp::os::Searchable &cfgtotal, pc104Data &pc104data)
Definition: ethParser.cpp:92
bool print(const pc104Data &pc104data)
Definition: ethParser.cpp:57
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
std::uint16_t maxSizeRXpacket
Definition: ethParser.h:40
eObrd_ethtype_t type
Definition: ethParser.h:39
eOipv4addressing_t ipv4addressing
Definition: ethParser.h:38
std::uint16_t maxSizeROP
Definition: ethParser.h:41
std::string ipv4addressingstring
Definition: ethParser.h:42
eOmn_appl_config_t txconfig
Definition: ethParser.h:58
eOipv4addressing_t localaddressing
Definition: ethParser.h:100
std::string addressingstring
Definition: ethParser.h:103
std::uint16_t rxrate
Definition: ethParser.h:102
std::uint16_t txrate
Definition: ethParser.h:101