LTKCPP-- LLRP Toolkit C Plus Plus Library
llrp2xml.cpp
Go to the documentation of this file.
1 
2 /*
3  *****************************************************************************
4  * *
5  * IMPINJ CONFIDENTIAL AND PROPRIETARY *
6  * *
7  * This source code is the sole property of Impinj, Inc. Reproduction or *
8  * utilization of this source code in whole or in part is forbidden without *
9  * the prior written consent of Impinj, Inc. *
10  * *
11  * (c) Copyright Impinj, Inc. 2007,2011. All rights reserved. *
12  * *
13  *****************************************************************************/
14 
37 #include <stdio.h>
38 #include "ltkcpp.h"
39 #include "impinj_ltkcpp.h"
40 #include "impinjinternal_ltkcpp.h"
41 #include "dirent.h"
42 #include "sys/stat.h"
43 
44 using namespace LLRP;
45 
46 #define MAX_PATH_LEN (256)
47 
48 CTypeRegistry * pTypeRegistry;
49 
50 
51 /* This is the message format that is agreed upon when messages fail
52 ** to decode. It's somewhat arbitrary, but allows us to do easy
53 ** comparisons */
54 static char * g_errMsgStr = "<ERROR_MESSAGE MessageID=\"0\" Version=\"0\"\n" \
55  " xmlns:llrp=\'http://www.llrp.org/ltk/schema/core/encoding/xml/1.0\'\n" \
56  " xmlns=\'http://www.llrp.org/ltk/schema/core/encoding/xml/1.0\'>\n" \
57  " <LLRPStatus>\n" \
58  " <StatusCode>M_Success</StatusCode>\n" \
59  " <ErrorDescription></ErrorDescription>\n" \
60  " </LLRPStatus>\n" \
61  "</ERROR_MESSAGE>\n";
62 
63 #ifdef WIN32
64  char pathSeparator = '\\';
65 #else
66  char pathSeparator = '/';
67 #endif
68 
78 void convertFile(char *ifile, char *ofile) {
79  FILE * infp;
80  FILE * outfp;
81  CMessage * pMessage;
82  puts(ifile);
83  puts(ofile);
84  unsigned char *binbuf;
85  char *xmlbuf;
86  int xmlLen;
87  int len;
88 
89  /*
90  * Open input file
91  */
92 #ifdef WIN32
93  if(fopen_s(&infp, ifile, "rb"))
94 #else
95  infp = fopen(ifile, "r");
96  if(infp == NULL)
97 #endif
98  {
99  perror(ifile);
100  exit(-1);
101  }
102 
103  fseek(infp,0,SEEK_END); //go to end
104  len=ftell(infp); //get position at end (length)
105  fseek(infp,0,SEEK_SET); //go to beg.
106  binbuf=(unsigned char *)malloc(len); //malloc buffer
107  if (binbuf)
108  fread(binbuf,len,1,infp); //read into buffer
109  fclose(infp);
110 
111  if(binbuf == NULL) {
112  perror("Could not malloc buffer for binary packet");
113  exit(-2);
114  }
115 
116  /* open the output file for writing */
117 #ifdef WIN32
118  if(fopen_s(&outfp, ofile, "w")) {
119 #else
120  outfp = fopen(ofile, "w");
121  if(outfp == NULL) {
122 #endif
123  fprintf(stderr, "Could not open output file %s for writing", ofile);
124  exit(-3);
125  }
126 
127  xmlLen = 100 * len;
128  /*
129  * Construct a frame decoder. It references the
130  * type registry and the input buffer.
131  */
132  CFrameDecoder MyFrameDecoder(pTypeRegistry,
133  binbuf, len);
134 
135  /*
136  * Now ask the frame decoder to actually decode
137  * the message. It returns NULL for an error.
138  */
139 
140  pMessage = MyFrameDecoder.decodeMessage();
141 
142  free(binbuf);
143 
144  /*
145  * Did the decode fail?
146  */
147  if(NULL == pMessage)
148  {
149  const CErrorDetails *pError;
150 
151  pError = &MyFrameDecoder.m_ErrorDetails;
152 
153  fprintf(stderr, "ERROR: Decoder error, result=%d\n",
154  pError->m_eResultCode);
155  if(NULL != pError->m_pRefType)
156  {
157  fprintf(stderr, "ERROR ... refType=%s\n",
158  pError->m_pRefType->m_pName);
159  }
160  if(NULL != pError->m_pRefField)
161  {
162  fprintf(stderr, "ERROR ... refField=%s\n",
163  pError->m_pRefField->m_pName);
164  }
165 
166  fprintf(outfp, "%s\n", g_errMsgStr);
167  } else if ((xmlbuf = (char*) malloc(xmlLen)) == NULL) {
168  fprintf(stderr, "Could not allocate output buffer for XML file size %u\n", xmlLen);
169  fprintf(outfp, "%s\n", g_errMsgStr);
170  } else {
171  CXMLTextEncoder MyXMLEncoder(xmlbuf, xmlLen);
172  MyXMLEncoder.encodeElement(pMessage);
173  if(!MyXMLEncoder.m_bOverflow)
174  {
175  fprintf(outfp, "%s", xmlbuf);
176  }
177  else
178  {
179  fprintf(stderr, "<!-- Buffer overflow -->\n");
180  fprintf(outfp, "%s\n", g_errMsgStr);
181  }
182  free(xmlbuf);
183  }
184 
185  fclose(outfp);
186  delete pMessage;
187 }
188 
189 void convertDirEntry(char *idir, char *odir, struct dirent *ep) {
190  char vector[MAX_PATH_LEN];
191  char iBuf[MAX_PATH_LEN];
192  char oBuf[MAX_PATH_LEN];
193  int len;
194 
195  if(!ep)
196  {
197  perror("Invalid file endpoint from dirent");
198  }
199 
200  /* string better end in .bin */
201  len = (int) strlen(ep->d_name);
202  if(len < 4)
203  {
204  /* if not just ignore this file */
205  return;
206  }
207 
208  /* call it a success if we don't need to convert */
209  if(strncmp(&ep->d_name[len-4], ".bin", 4) != 0) {
210  /* ignore this file */
211  return;
212  }
213 
214  memset(vector, 0x00, sizeof(vector));
215 #ifdef WIN32
216  strncpy_s(vector, ep->d_name, len-4);
217  sprintf_s(iBuf, "%s%s.bin", idir, vector);
218  sprintf_s(oBuf, "%s%s.xml", odir, vector);
219 #else
220  strncpy(vector, ep->d_name, len-4);
221  sprintf(iBuf, "%s%s.bin", idir, vector);
222  sprintf(oBuf, "%s%s.xml", odir, vector);
223 #endif
224  convertFile(iBuf, oBuf);
225 }
226 
227 int
228 main (int ac, char *av[])
229 {
230  DIR * dpin;
231  DIR * dpout;
232  char idir[MAX_PATH_LEN];
233  char odir[MAX_PATH_LEN];
234  int len;
235  struct dirent* ep;
236 
237  /*
238  * Check arg count
239  */
240  if(ac != 3)
241  {
242  fprintf(stderr, "ERROR: Bad usage\nusage: %s INPUTDIR OUTPUTDIR\n", av[0]);
243  exit(1);
244  }
245 
246  dpin = opendir (av[1]);
247  if (dpin == NULL)
248  {
249  fprintf(stderr, "ERROR: Could not stat input directory %s\n", av[1]);
250  exit(-1);
251  }
252 
253  /* make sure the directory has a path separator at the end */
254 #ifdef WIN32
255  strcpy_s(idir, av[1]);
256 #else
257  strcpy(idir, av[1]);
258 #endif
259 
260  len = (int) strlen(idir);
261  if(idir[len-1] != pathSeparator) {
262  idir[len] = pathSeparator;
263  idir[len + 1] = 0;
264  }
265 
266 
267  dpout = opendir (av[1]);
268  if (dpout == NULL)
269  {
270  fprintf(stderr, "ERROR: Could not stat output directory %s\n", av[2]);
271  exit(-1);
272  }
273 
274  /* make sure the directory has a path separator at the end */
275 #ifdef WIN32
276  strcpy_s(odir, av[2]);
277 #else
278  strcpy(odir, av[2]);
279 #endif
280  len = (int) strlen(odir);
281  if(odir[len-1] != pathSeparator) {
282  odir[len] = pathSeparator;
283  odir[len + 1] = 0;
284  }
285 
286  /*
287  * Construct the type registry. This is needed for decode.
288  */
289  pTypeRegistry = getTheTypeRegistry();
290 
291  enrollImpinjTypesIntoRegistry(pTypeRegistry);
292  enrollImpinjInternalTypesIntoRegistry(pTypeRegistry);
293 
294 
295  while((ep=readdir(dpin))) {
296  convertDirEntry(idir, odir, ep);
297  }
298 
299  (void) closedir(dpin);
300  (void) closedir(dpout);
301 
302  /*
303  * Done with the type registry.
304  */
305  delete pTypeRegistry;
306 }
char * m_pName
String name of field (e.g. "ROSpecID")
Definition: ltkcpp_base.h:840
const CFieldDescriptor * m_pRefField
If non-NULL this is the field descriptors for the errored field.
Definition: ltkcpp_base.h:641
const CTypeDescriptor * m_pRefType
If non-NULL this is the type descriptors for the errored type.
Definition: ltkcpp_base.h:639
EResultCode m_eResultCode
Result code from operation.
Definition: ltkcpp_base.h:635
void enrollImpinjTypesIntoRegistry(CTypeRegistry *pTypeRegistry)
Enrolls the types for Impinj into the LTKCPP registry.
A collection of pointers to CTypeDescriptors.
Definition: ltkcpp_base.h:885
File that includes all Impinj Custom extension classes and types.
Class to return error details in LTKCPP operations.
Definition: ltkcpp_base.h:631
char * m_pName
String name of parameter/message type (e.g. "ROSpec")
Definition: ltkcpp_base.h:762
void convertFile(char *ifile, char *ofile)
Definition: llrp2xml.cpp:78
File that includes all LLRP classes and types.
Base Class for All LLRP LTK Messages.
Definition: ltkcpp_base.h:1088
Definition: ltkcpp.h:45