netmsgs  1.2.2
RoadNarrows Robotics Network Messaging Package
nmExample.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: NetMsgs
4 //
5 // Program: nmExample
6 //
7 // File: nmExample.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2010-05-03 13:49:15 -0600 (Mon, 03 May 2010) $
12  * $Rev: 365 $
13  *
14  * \brief Example NetMsgs message packing/unpacking application.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \copyright
19  * \h_copy 2010-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 // Permission is hereby granted, without written agreement and without
24 // license or royalty fees, to use, copy, modify, and distribute this
25 // software and its documentation for any purpose, provided that
26 // (1) The above copyright notice and the following two paragraphs
27 // appear in all copies of the source code and (2) redistributions
28 // including binaries reproduces these notices in the supporting
29 // documentation. Substantial modifications to this software may be
30 // copyrighted by their authors and need not follow the licensing terms
31 // described here, provided that the new terms are clearly indicated in
32 // all files where they apply.
33 //
34 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
35 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
36 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
37 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
38 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
39 // THE POSSIBILITY OF SUCH DAMAGE.
40 //
41 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
42 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
43 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
44 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
45 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
46 //
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <stdio.h>
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <libgen.h>
53 #include <string.h>
54 
55 #include "rnr/rnrconfig.h"
56 #include "rnr/new.h"
57 #include "rnr/opts.h"
58 #include "rnr/log.h"
59 #include "rnr/netmsgs.h"
60 
61 #include "nmExample.h"
62 #include "AstroMsgs.h"
63 
64 #include "version.h"
65 
66 
67 // ---------------------------------------------------------------------------
68 // Private Interface
69 // ---------------------------------------------------------------------------
70 
71 //
72 // Application Exit Codes
73 //
74 #define APP_EC_OK 0 ///< success exit code
75 #define APP_EC_USAGE 2 ///< usage error exit code
76 #define APP_EC_EXEC 4 ///< execution error exit code
77 
78 //
79 // The command and command-line options.
80 //
81 static char *Argv0; ///< this command basename
82 static bool_t OptsTrace = false; ///< do [not] trace packing/unpacking
83 // add others later
84 
85 /*!
86  * \brief Program information.
87  */
88 static OptsPgmInfo_T PgmInfo =
89 {
90  .synopsis =
91  "Simple example packing and unpacking NetMsgs messages.",
92 
93  .long_desc =
94  "The %P application uses the python NetMsgs package generated C code "
95  "from the AstroMsgs.xml NetMsgs XML specification and the libnetmsgs "
96  "library to pack and unpack the messages."
97 };
98 
99 /*!
100  * \brief Command-line options information.
101  */
102 static OptsInfo_T OptsInfo[] =
103 {
104  // --proxy=<addr[:port]>
105  {
106  .long_opt = "trace",
107  .short_opt = 't',
108  .has_arg = no_argument,
109  .has_default= true,
110  .opt_addr = &OptsTrace,
111  .fn_cvt = OptsCvtArgBool,
112  .fn_fmt = OptsFmtBool,
113  .arg_name = NULL,
114  .opt_desc = "Do [not] enable tracing of packing and unpacking "
115  "operations. If enabled, tracing is printed to stderr."
116  },
117 
118  {NULL, }
119 };
120 
121 //
122 // State
123 //
124 
125 
126 // ...........................................................................
127 // Initialization Functions
128 // ...........................................................................
129 
130 /*!
131  * \brief Initialize simple_khr2 command.
132  *
133  * Any command-line error immediately terminates application.
134  *
135  * \param argc Command-line argument count.
136  * \param argv Command-line argument list.
137  *
138  * \return
139  * Returns \ref APP_EC_OK on success, >0 exit code on failure.
140  */
141 static int MainInit(int argc, char *argv[])
142 {
143  // Name of this process.
144  Argv0 = basename(argv[0]);
145 
146  //
147  // Parse input options.
148  //
149  argv = OptsGet(Argv0, &PkgInfo, &PgmInfo, OptsInfo, true, &argc, argv);
150 
151  return APP_EC_OK;
152 }
153 
154 
155 // ...........................................................................
156 // Execution Functions
157 // ...........................................................................
158 
159 typedef int (*Packer_T)(void *, byte_t [], size_t, bool_t); ///< packer type
160 typedef int (*Unpacker_T)(byte_t [], size_t, void *, bool_t); ///< unpacker type
161 
162 #define MSG_NS "Astro" ///< message namespace
163 
164 /*!
165  * \brief Concatenate two tokens.
166  * \param a Token a.
167  * \param b Token b.
168  */
169 #define CAT(a, b) a ## b
170 
171 /*!
172  * \brief Concatenate three tokens.
173  * \param a Token a.
174  * \param b Token b.
175  * \param c Token c.
176  */
177 #define CAT3(a, b, c) a ## b ## c
178 
179 /*!
180  * \brief Print side-by-side comparision of prepacked tx and post-unpacked rx
181  * member.
182  *
183  * \note Implicit use of txmsg and rxmst external variables.
184  *
185  * \param mem Structure member of txmsg and rxmsg.
186  * \param fmt Member print format.
187  */
188 #define PRCMP(mem, fmt) \
189  do \
190  { \
191  int k; \
192  k = fprintf(stderr, "%s: ", #mem); \
193  if( k > 38 ) \
194  { \
195  fprintf(stderr, "\n"); \
196  k = 0; \
197  } \
198  fprintf(stderr, "%*stx " fmt "\n", 40-k, "", txmsg.mem); \
199  fprintf(stderr, "%*srx " fmt "\n\n", 40, "", rxmsg.mem); \
200  } while(0)
201 
202 /*!
203  * \brief Execute the pack, unpack identiy function.
204  *
205  * \param xmlname XML name token
206  * \param txmsg Pre-packed, populated message structure.
207  * \param rxmsg Post-unacked, populated message structure.
208  */
209 #define IDENTITY(xmlname, txmsg, rxmsg) \
210  Identity(#xmlname, (Packer_T)CAT3(Astro, Pack, xmlname), &txmsg, \
211  (Unpacker_T)CAT3(Astro, Unpack, xmlname), &rxmsg)
212 
213 
214 /*!
215  * \brief Execute the pack, unpack identiy function.
216  *
217  * \param sXmlName XML name string
218  * \param fnPacker Packing function.
219  * \param pTxMsg Pointer to pre-packed, populated message structure.
220  * \param fnUnpacker Unpacking function.
221  * \param pRxMsg Pointer to post-unacked, message structure.
222  *
223  * \return
224  * Number of bytes unpacked (== packed) on success.\n
225  * \h_lt 0 on error.
226  */
227 int Identity(const char *sXmlName, Packer_T fnPacker, void *pTxMsg,
228  Unpacker_T fnUnpacker, void *pRxMsg)
229 {
230  byte_t buf[2048];
231  int n;
232 
233  if( (n = fnPacker(pTxMsg, buf, sizeof(buf), OptsTrace)) < 0 )
234  {
235  LOGERROR("%s(ecode=%d): %sPack%s()", nmStrError(n), n, MSG_NS, sXmlName);
236  }
237 
238 
239  else if( (n = fnUnpacker(buf, (size_t)n, pRxMsg, OptsTrace)) < 0 )
240  {
241  LOGERROR("%s(ecode=%d): %sUnpack%s()", nmStrError(n), n, MSG_NS, sXmlName);
242  }
243 
244  return n;
245 }
246 
247 /*! Test Function Type */
248 typedef int (*tstfunc_t)();
249 
250 /*!
251  * \brief Test AstroRspMsg message packing and unpacking.
252  *
253  * \return
254  * Number of bytes unpacked (== packed) on success.\n
255  * \h_lt 0 on error.
256  */
258 {
259  AstroRspErr_T txmsg, rxmsg;
260  int n;
261 
262  txmsg.m_ECode = 55;
263  strcpy(txmsg.m_EMsg, "this is an error message");
264 
265  n = IDENTITY(RspErr, txmsg, rxmsg);
266 
267  if( n >= 0 )
268  {
269  fprintf(stderr, "\n--- AstroRspErr_T Results\n");
270  PRCMP(m_ECode, "%u");
271  PRCMP(m_EMsg, "'%s'");
272  }
273 
274  return n;
275 }
276 
277 /*!
278  * \brief Test CmdZodiac message packing and unpacking.
279  *
280  * \return
281  * Number of bytes unpacked (== packed) on success.\n
282  * \h_lt 0 on error.
283  */
285 {
286  int n = 0;
287  size_t i;
288 
289  AstroCmdZodiac_T txmsg, rxmsg;
290 
291  strcpy(txmsg.m_Family, "test const");
292 
293  strcpy(txmsg.m_Constellation.m_Name, "Orion");
294 
295  txmsg.m_Constellation.m_Designation.u.m_buf[ALPHA] = ALPHA;
296  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[ALPHA].m_Name, "Betelgeuse");
297  txmsg.m_Constellation.m_Star.u.m_buf[ALPHA].m_Type = 'M';
298  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[ALPHA].m_Color, "Red");
299  txmsg.m_Constellation.m_Star.u.m_buf[ALPHA].m_TempK = 3500;
300  txmsg.m_Constellation.m_Star.u.m_buf[ALPHA].m_MassSun = 19.0;
301 
302  txmsg.m_Constellation.m_Designation.u.m_buf[BETA] = BETA;
303  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[BETA].m_Name, "Rigel");
304  txmsg.m_Constellation.m_Star.u.m_buf[BETA].m_Type = 'B';
305  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[BETA].m_Color, "Blue");
306  txmsg.m_Constellation.m_Star.u.m_buf[BETA].m_TempK = 11000;
307  txmsg.m_Constellation.m_Star.u.m_buf[BETA].m_MassSun = 17.0;
308 
309  txmsg.m_Constellation.m_Designation.u.m_buf[GAMMA] = GAMMA;
310  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[GAMMA].m_Name, "Bellatrix");
311  txmsg.m_Constellation.m_Star.u.m_buf[GAMMA].m_Type = 'B';
312  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[GAMMA].m_Color, "Blue");
313  txmsg.m_Constellation.m_Star.u.m_buf[GAMMA].m_TempK = 21500;
314  txmsg.m_Constellation.m_Star.u.m_buf[GAMMA].m_MassSun = 8.5;
315 
316  txmsg.m_Constellation.m_Designation.u.m_buf[DELTA] = DELTA;
317  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[DELTA].m_Name, "Mintaka");
318  txmsg.m_Constellation.m_Star.u.m_buf[DELTA].m_Type = 'B';
319  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[DELTA].m_Color, "Blue");
320  txmsg.m_Constellation.m_Star.u.m_buf[DELTA].m_TempK = 30000;
321  txmsg.m_Constellation.m_Star.u.m_buf[DELTA].m_MassSun = 20.0;
322 
323  txmsg.m_Constellation.m_Designation.u.m_buf[EPSILON] = EPSILON;
324  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[EPSILON].m_Name, "Alnilam");
325  txmsg.m_Constellation.m_Star.u.m_buf[EPSILON].m_Type = 'B';
326  strcpy(txmsg.m_Constellation.m_Star.u.m_buf[EPSILON].m_Color, "Blue");
327  txmsg.m_Constellation.m_Star.u.m_buf[EPSILON].m_TempK = 25000;
328  txmsg.m_Constellation.m_Star.u.m_buf[EPSILON].m_MassSun = 40.0;
329 
330  txmsg.m_Constellation.m_Designation.m_count = EPSILON+1;
331  txmsg.m_Constellation.m_Star.m_count = EPSILON+1;
332 
333  n = IDENTITY(CmdZodiac, txmsg, rxmsg);
334 
335  if( n >= 0 )
336  {
337  fprintf(stderr, "\n--- AstroCmdZodiac_T Results\n");
338  PRCMP(m_Family, "%s");
339  PRCMP(m_Constellation.m_Name, "%s");
340  PRCMP(m_Constellation.m_Designation.m_count, "%zu");
341  PRCMP(m_Constellation.m_Star.m_count, "%zu");
342  for(i=0; i<txmsg.m_Constellation.m_Star.m_count; ++i)
343  {
344  PRCMP(m_Constellation.m_Designation.u.m_buf[i], "%hhu");
345  PRCMP(m_Constellation.m_Star.u.m_buf[i].m_Name, "%s");
346  PRCMP(m_Constellation.m_Star.u.m_buf[i].m_Type, "'%c'");
347  PRCMP(m_Constellation.m_Star.u.m_buf[i].m_Color, "%s");
348  PRCMP(m_Constellation.m_Star.u.m_buf[i].m_TempK, "%u");
349  PRCMP(m_Constellation.m_Star.u.m_buf[i].m_MassSun, "%f");
350  }
351  }
352 
353  return n;
354 }
355 
356 /*!
357  * \brief Test CmdUniverse message packing and unpacking.
358  *
359  * \return
360  * Number of bytes unpacked (== packed) on success.\n
361  * \h_lt 0 on error.
362  */
364 {
365  static char *p1 = "p-branes";
366  static char *p2 = "bad captain kirk";
367 
368  AstroCmdUniverse_T txmsg =
369  {
370  .m_Truth = true,
371  .m_Aura = 'z',
372  .m_Gluon = 3,
373  .m_Electron = -3,
374  .m_Planet = 16433,
375  .m_StellarObj = -31000,
376  .m_StarSystem = 999999,
377  .m_Galaxy = -11,
378  .m_GalaxyGroup = 0xffffffff,
379  .m_Filament = 85,
380  .m_VisUnivLY = (float)-53.42,
381  .m_FullUnivLY = 53e12,
382  .m_Math.m_One = 1,
383  .m_Math.m_Two = 2,
384  .m_Math.m_DotDotDot = 101,
385  .m_StarType = 'O',
386  .m_StarInfo.m_Type = 'M',
387  .m_StarInfo.m_TempK = 10000,
388  .m_StarInfo.m_MassSun = (float)2.6,
389  };
390  AstroCmdUniverse_T rxmsg;
391  int n;
392 
393  txmsg.m_HiddenDim = p1;
394  txmsg.m_ParallelUniv = p2;
395  strcpy(txmsg.m_TheUnamed, "God");
396  txmsg.m_Physics.m_count = 3;
397  txmsg.m_Physics.u.m_buf[0] = 31415;
398  txmsg.m_Physics.u.m_buf[1] = 214;
399  txmsg.m_Physics.u.m_buf[2] = 317;
400  txmsg.m_Physics.u.m_buf[3] = 555555;
401  strcpy(txmsg.m_StarInfo.m_Name, "Rigel");
402  strcpy(txmsg.m_StarInfo.m_Color, "Blue");
403 
404  n = IDENTITY(CmdUniverse, txmsg, rxmsg);
405 
406  if( n >= 0 )
407  {
408  fprintf(stderr, "\n--- AstroCmdUniverse_T Results\n");
409  PRCMP(m_Truth, "%hhu");
410  PRCMP(m_Aura, "'%c'");
411  PRCMP(m_Gluon, "%hhu");
412  PRCMP(m_Electron, "%hhd");
413  PRCMP(m_Planet, "%hu");
414  PRCMP(m_StellarObj, "%hd");
415  PRCMP(m_StarSystem, "%u");
416  PRCMP(m_Galaxy, "%d");
417  PRCMP(m_GalaxyGroup, "%llu");
418  PRCMP(m_Filament, "%lld");
419  PRCMP(m_VisUnivLY, "%f");
420  PRCMP(m_FullUnivLY, "%e");
421  fprintf(stderr, "%*s%p->\"%s\"\n", 43, "", p1, p1);
422  PRCMP(m_HiddenDim, "%p");
423  fprintf(stderr, "%*s%p->\"%s\"\n", 43, "", p2, p2);
424  PRCMP(m_ParallelUniv, "%p");
425  PRCMP(m_TheUnamed, "%s");
426  PRCMP(m_Math.m_One, "%hu");
427  PRCMP(m_Math.m_Two, "%u");
428  PRCMP(m_Math.m_DotDotDot, "%llu");
429  PRCMP(m_Physics.m_count, "%zu");
430  PRCMP(m_Physics.u.m_buf[0], "%u");
431  PRCMP(m_Physics.u.m_buf[1], "%u");
432  PRCMP(m_Physics.u.m_buf[2], "%u");
433  PRCMP(m_StarType, "'%c'");
434  PRCMP(m_StarInfo.m_Type, "'%c'");
435  PRCMP(m_StarInfo.m_TempK, "%u");
436  PRCMP(m_StarInfo.m_MassSun, "%f");
437  PRCMP(m_StarInfo.m_Name, "%s");
438  PRCMP(m_StarInfo.m_Color, "%s");
439  }
440 
441  return n;
442 }
443 
444 /*!
445  * Table of Test Functions.
446  */
448 {
449  tstRspErr,
450  tstCmdZodiac,
452  NULL
453 };
454 
455 /*!
456  * \brief Simple NetMsg example main.
457  *
458  * \param argc Command-line argument count.
459  * \param argv Command-line argument list.
460  *
461  * \par Exit Status:
462  * Program exits with 0 success, \h_gt 0 on failure.
463  */
464 int main(int argc, char *argv[])
465 {
466  tstfunc_t fnTst;
467  int i;
468  int n = NM_OK;
469 
470  // Initialize command.
471  MainInit(argc, argv);
472 
473  for(i=0; (fnTst=TstTbl[i])!=NULL; ++i)
474  {
475  if( (n = fnTst()) < 0 )
476  {
477  break;
478  }
479  }
480 
481  return n>=0? APP_EC_OK: APP_EC_EXEC;
482 }
#define BETA
2nd star
Definition: nmExample.h:63
static OptsInfo_T OptsInfo[]
Command-line options information.
Definition: nmExample.c:102
int(* Unpacker_T)(byte_t[], size_t, void *, bool_t)
unpacker type
Definition: nmExample.c:160
static char * Argv0
this command basename
Definition: nmExample.c:81
#define MSG_NS
message namespace
Definition: nmExample.c:162
#define APP_EC_OK
success exit code
Definition: nmExample.c:74
#define ALPHA
1st star
Definition: nmExample.h:62
int Identity(const char *sXmlName, Packer_T fnPacker, void *pTxMsg, Unpacker_T fnUnpacker, void *pRxMsg)
Execute the pack, unpack identiy function.
Definition: nmExample.c:227
#define APP_EC_EXEC
execution error exit code
Definition: nmExample.c:76
#define GAMMA
3rd star
Definition: nmExample.h:64
#define NM_OK
not an error, success
Definition: netmsgs.h:70
static int MainInit(int argc, char *argv[])
Initialize simple_khr2 command.
Definition: nmExample.c:141
int tstCmdZodiac()
Test CmdZodiac message packing and unpacking.
Definition: nmExample.c:284
int(* Packer_T)(void *, byte_t[], size_t, bool_t)
packer type
Definition: nmExample.c:159
int tstCmdUniverse()
Test CmdUniverse message packing and unpacking.
Definition: nmExample.c:363
static bool_t OptsTrace
do [not] trace packing/unpacking
Definition: nmExample.c:82
#define PRCMP(mem, fmt)
Print side-by-side comparision of prepacked tx and post-unpacked rx member.
Definition: nmExample.c:188
static const PkgInfo_T PkgInfo
Definition: version.h:45
Package version information.
#define DELTA
4th star
Definition: nmExample.h:65
int(* tstfunc_t)()
Definition: nmExample.c:248
tstfunc_t TstTbl[]
Definition: nmExample.c:447
#define IDENTITY(xmlname, txmsg, rxmsg)
Execute the pack, unpack identiy function.
Definition: nmExample.c:209
static OptsPgmInfo_T PgmInfo
Program information.
Definition: nmExample.c:88
#define EPSILON
5th star
Definition: nmExample.h:66
int main(int argc, char *argv[])
Simple NetMsg example main.
Definition: nmExample.c:464
Network Messaging declarations.
Example NetMsgs message packing/unpacking application declarations.
int tstRspErr()
Test AstroRspMsg message packing and unpacking.
Definition: nmExample.c:257