Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
diagProd.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // Program: laelaps_diag
6 //
7 // File: diagProd.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2016-02-01 15:14:45 -0700 (Mon, 01 Feb 2016) $
12  * $Rev: 4289 $
13  *
14  * \brief Perform Laelaps product diagnostics.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \par Copyright
19  * \h_copy 2015-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  *
26  * Unless otherwise stated explicitly, all materials contained are copyrighted
27  * and may not be used without RoadNarrows LLC's written consent,
28  * except as provided in these terms and conditions or in the copyright
29  * notice (documents and software) or other proprietary notice provided with
30  * the relevant materials.
31  *
32  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
33  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
34  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
35  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
36  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44  *
45  * @EulaEnd@
46  */
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <unistd.h>
50 #include <termios.h>
51 #include <string.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <stdarg.h>
55 
56 #include <iostream>
57 #include <fstream>
58 #include <string>
59 #include <vector>
60 #include <map>
61 
62 #include "rnr/rnrconfig.h"
63 #include "rnr/log.h"
64 #include "rnr/opts.h"
65 #include "rnr/pkg.h"
66 
67 // common
68 #include "Laelaps/laelaps.h"
69 #include "Laelaps/laeUtils.h"
70 
71 // target diagnostics
72 #include "Laelaps/laeDesc.h"
73 #include "Laelaps/laeTune.h"
74 #include "Laelaps/laeXmlCfg.h"
75 #include "Laelaps/laeXmlTune.h"
76 
77 #include "laelaps_diag.h"
78 
79 using namespace std;
80 using namespace laelaps;
81 
82 static const char *SubSysName = "Product";
83 
84 static string ProdSN("??????");
85 static LaeDesc ProdDesc;
86 static LaeTunes ProdTunes;
87 static map<string, string> ProdEnv;
88 
89 
90 static DiagStats readProdSN()
91 {
92  FILE *fp;
93  char buf[7];
94  size_t snlen = sizeof(buf) - 1;
95 
96  DiagStats stats;
97 
98  printSubHdr("Reading Serial Number");
99 
100  ++stats.testCnt;
101  if( (fp = fopen("/usr/local/share/misc/.sn", "r")) == NULL )
102  {
103  printTestResult(FailTag, "%s: Find serial number.", SubSysName);
104  }
105  else if( fread(buf, sizeof(char), snlen, fp) < snlen )
106  {
107  printTestResult(FailTag, "%s: Read serial number.", SubSysName);
108  }
109  else
110  {
111  buf[snlen] = 0;
112  ProdSN = buf;
113  printTestResult(PassTag, "%s: Read serial number %s.", SubSysName, buf);
114  ++stats.passCnt;
115  }
116 
117  if( fp != NULL )
118  {
119  fclose(fp);
120  }
121 
122  return stats;
123 }
124 
125 static DiagStats readProdDesc()
126 {
127  LaeXmlCfg xml;
128  int rc;
129 
130  DiagStats stats;
131 
132  ++stats.testCnt;
133 
134  if( (rc = xml.load(ProdDesc, LaeSysCfgPath, LaeEtcCfg)) != LAE_OK )
135  {
136  printTestResult(FailTag, "%s: Load and parse file %s.",
137  SubSysName, LaeEtcCfg);
138  }
139  else
140  {
141  printTestResult(PassTag, "%s: Load and parse file %s.",
142  SubSysName, LaeEtcCfg);
143  ++stats.passCnt;
144  }
145 
146  ++stats.testCnt;
147 
148  if( (rc = ProdDesc.markAsDescribed()) != LAE_OK )
149  {
150  printTestResult(FailTag, "%s: Description complete.", SubSysName);
151  }
152  else
153  {
154  printTestResult(PassTag, "%s: Description complete.", SubSysName);
155  ++stats.passCnt;
156  }
157 
158  return stats;
159 }
160 
161 static DiagStats readProdTunes()
162 {
163  LaeXmlTune xml;
164  int rc;
165  DiagStats stats;
166 
167  ++stats.testCnt;
168 
169  if( (rc = xml.load(ProdTunes, LaeSysCfgPath, LaeEtcTune)) != LAE_OK )
170  {
171  printTestResult(FailTag, "%s: Load and parse file %s.",
172  SubSysName, LaeEtcCfg);
173  }
174  else
175  {
176  printTestResult(PassTag, "%s: Load and parse file %s.",
177  SubSysName, LaeEtcCfg);
178  ++stats.passCnt;
179  }
180 
181  return stats;
182 }
183 
184 static DiagStats readProdEnv()
185 {
186  const char *EnvName[] =
187  {
188  "ROS_DISTRO", "ROS_ETC_DIR", "ROS_MASTER_URI", "ROS_PACKAGE_PATH",
189  "ROS_ROOT"
190  };
191 
192  char *sVal;
193  DiagStats stats;
194  const char *sTag;
195  size_t i;
196 
197  for(i = 0; i < arraysize(EnvName); ++i)
198  {
199  ++stats.testCnt;
200  sTag = FailTag;
201  if( (sVal = getenv(EnvName[i])) != NULL )
202  {
203  ProdEnv[EnvName[i]] = sVal;
204  ++stats.passCnt;
205  sTag = PassTag;
206  }
207  printTestResult(sTag, "%s: getenv(%s).", SubSysName, EnvName[i]);
208  }
209 
210  return stats;
211 }
212 
213 static void printResults()
214 {
215  map<string, string>::iterator iter;
216 
217  printf("\n");
218  printf("Laelaps Product Summary:\n");
219 
220  printf(" Serial Number: %s\n", ProdSN.c_str());
221 
222  printf("\n");
223  ProdDesc.print(2);
224 
225  printf("\n");
226  ProdTunes.print(2);
227 
228  printf("\n");
229  for(iter = ProdEnv.begin(); iter != ProdEnv.end(); ++iter)
230  {
231  printf("%18s: %s\n", iter->first.c_str(), iter->second.c_str());
232  }
233 
234  printf("\n\n");
235 }
236 
237 DiagStats runProductDiagnostics()
238 {
239  DiagStats statsTest;
240  DiagStats statsTotal;
241 
242  printHdr("Product Diagnostics");
243 
244  //
245  // Read Serial Number Tests
246  //
247  if( !statsTotal.fatal )
248  {
249  statsTest = readProdSN();
250 
251  printSubTotals(statsTest);
252 
253  statsTotal += statsTest;
254  }
255 
256  //
257  // Read and Parse Product Description Tests
258  //
259  if( !statsTotal.fatal )
260  {
261  statsTest = readProdDesc();
262 
263  printSubTotals(statsTest);
264 
265  statsTotal += statsTest;
266  }
267 
268  //
269  // Read and Parse Product Tuning Paramers Tests
270  //
271  if( !statsTotal.fatal )
272  {
273  statsTest = readProdTunes();
274 
275  printSubTotals(statsTest);
276 
277  statsTotal += statsTest;
278  }
279 
280  //
281  // Read Product Environment Tests
282  //
283  if( !statsTotal.fatal )
284  {
285  statsTest = readProdEnv();
286 
287  printSubTotals(statsTest);
288 
289  statsTotal += statsTest;
290  }
291 
292  //
293  // Summary
294  //
295  printTotals(statsTotal);
296 
297  printResults();
298 
299  return statsTotal;
300 }
Diagnotics header file.
Laelaps tuning data class.
Definition: laeTune.h:566
LaeXmlTune <b><i>Laelaps</i></b> XML tuning class.
Definition: laeXmlTune.h:71
Laelaps robotic mobile platform full description class.
Definition: laeDesc.h:451
void print(int indent=0)
Print out tuning parameters to stdout.
Definition: laeTune.cxx:447
<b><i>Laelaps</i></b> XML tuning class interface.
virtual int load(LaeTunes &tunes, const std::string &strSearchPath=LaeSysCfgPath, const std::string &strXmlFileName=LaeEtcTune, bool bAllInstances=false)
Load XML file into DOM and set the <b><i>Laelaps</i></b> tuning parameters.
Definition: laeXmlTune.cxx:71
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
Laelaps robotic base mobile platform description class interface.
Simple diagnostics statistics class.
Definition: laelaps_diag.h:106
Laelaps common utilities.
int markAsDescribed()
Mark <b><i>Laelaps</i></b> hardware as fully described.
Definition: laeDesc.cxx:672
Laelaps tuning.
<b><i>Laelaps</i></b> XML configuration class interface.
virtual int load(LaeDesc &desc, const std::string &strSearchPath, const std::string &strXmlFileName, bool bAllInstances=false)
Load XML file into DOM and set the <b><i>Laelaps</i></b> description.
Definition: laeXmlCfg.cxx:65
void print(int indent=0)
Print out description to stdout.
Definition: laeDesc.cxx:821
Top-level package include file.
LaeXmlCfg <b><i>Laelaps</i></b> XML configuration class.
Definition: laeXmlCfg.h:71