LTKCPP-- LLRP Toolkit C Plus Plus Library
|
00001 00002 /* 00003 ***************************************************************************** 00004 * * 00005 * IMPINJ CONFIDENTIAL AND PROPRIETARY * 00006 * * 00007 * This source code is the sole property of Impinj, Inc. Reproduction or * 00008 * utilization of this source code in whole or in part is forbidden without * 00009 * the prior written consent of Impinj, Inc. * 00010 * * 00011 * (c) Copyright Impinj, Inc. 2007,2011. All rights reserved. * 00012 * * 00013 *****************************************************************************/ 00014 00037 #include <stdio.h> 00038 #include "ltkcpp.h" 00039 #include "Impinj/impinj_ltkcpp.h" 00040 #include "Impinj/impinjinternal_ltkcpp.h" 00041 #include "dirent.h" 00042 #include "sys/stat.h" 00043 #include "libxml/parser.h" 00044 00045 using namespace LLRP; 00046 00047 #define MAX_PATH_LEN (256) 00048 00049 CTypeRegistry * pTypeRegistry; 00050 00051 00052 /* This is the message format that is agreed upon when messages fail 00053 ** to decode. It's somewhat arbitrary, but allows us to do easy 00054 ** comparisons */ 00055 /* the corresponding binary packet */ 00056 unsigned char errMsgBinary[18] = {0x04, 0x64, 0x00, 0x00, 00057 0x00, 0x12, 0x00, 0x00, 00058 0x00, 0x00, 0x01, 0x1F, 00059 0x00, 0x08, 0x00, 0x00, 00060 0x00, 0x00}; 00061 00062 #ifdef WIN32 00063 char pathSeparator = '\\'; 00064 #else 00065 char pathSeparator = '/'; 00066 #endif 00067 00077 void convertFile(char *ifile, char *ofile) { 00078 FILE * infp; 00079 FILE * outfp; 00080 CMessage * pMessage; 00081 CXMLTextDecoder * pDecoder; 00082 puts(ifile); 00083 puts(ofile); 00084 unsigned char *binbuf; 00085 char *xmlbuf; 00086 int xmlLen; 00087 int binLen; 00088 00089 /* 00090 * Open input file 00091 */ 00092 #ifdef WIN32 00093 if(fopen_s(&infp, ifile, "r")) 00094 #else 00095 infp = fopen(ifile, "r"); 00096 if(infp == NULL) 00097 #endif 00098 { 00099 perror(ifile); 00100 xmlCleanupParser(); 00101 exit(-1); 00102 } 00103 00104 fseek(infp,0,SEEK_END); //go to end 00105 xmlLen=ftell(infp); //get position at end (length) 00106 fseek(infp,0,SEEK_SET); //go to beg. 00107 xmlbuf=(char *) malloc(xmlLen); //malloc buffer 00108 if (xmlbuf) 00109 fread(xmlbuf,xmlLen,1,infp); //read into buffer 00110 fclose(infp); 00111 00112 if(xmlbuf == NULL) { 00113 perror("Could not malloc buffer for LTK-XML message"); 00114 xmlCleanupParser(); 00115 exit(-2); 00116 } 00117 00118 /* open the output file for writing */ 00119 #ifdef WIN32 00120 if(fopen_s(&outfp, ofile, "wb")) { 00121 #else 00122 outfp = fopen(ofile, "w"); 00123 if(outfp == NULL) { 00124 #endif 00125 fprintf(stderr, "Could not open output file %s for writing", ofile); 00126 xmlCleanupParser(); 00127 exit(-3); 00128 } 00129 00130 /* 00131 * Construct a frame decoder. It references the 00132 * type registry and the input buffer. 00133 */ 00134 pDecoder = new CXMLTextDecoder(pTypeRegistry, xmlbuf, xmlLen); 00135 00136 /* 00137 * Now ask the frame decoder to actually decode 00138 * the message. It returns NULL for an error. 00139 */ 00140 pMessage = pDecoder->decodeMessage(); 00141 00142 /* 00143 * Did the decode fail? 00144 */ 00145 if(NULL == pMessage) 00146 { 00147 const CErrorDetails *pError; 00148 00149 /* encode error message as binary */ 00150 fwrite(errMsgBinary, 1, sizeof(errMsgBinary), outfp); 00151 00152 pError = &pDecoder->m_ErrorDetails; 00153 00154 #ifdef XML2LLRP_DEBUG 00155 fprintf(stderr, "ERROR: Decoder error, result=%d\n", 00156 pError->m_eResultCode); 00157 00158 if(NULL != pMessageIDStr) 00159 { 00160 fprintf(stderr, "ERROR ... MessageID=%s\n", 00161 pMessageIDStr); 00162 } 00163 if(NULL != pError->m_pRefType) 00164 { 00165 fprintf(stderr, "ERROR ... refType=%s\n", 00166 pError->m_pRefType->m_pName); 00167 } 00168 if(NULL != pError->m_pRefField) 00169 { 00170 fprintf(stderr, "ERROR ... refField=%s\n", 00171 pError->m_pRefField->m_pName); 00172 } 00173 if(NULL != pError->m_pWhatStr) 00174 { 00175 fprintf(stderr, "ERROR ... whatStr=%s\n", 00176 pError->m_pWhatStr); 00177 } 00178 if(0 != pError->m_OtherDetail) 00179 { 00180 fprintf(stderr, "ERROR ... XML line number %d\n", 00181 pError->m_OtherDetail); 00182 } 00183 #endif /* XML2LLRP_DEBUG */ 00184 00185 delete pDecoder; 00186 /* we are done with this buffer */ 00187 free(xmlbuf); 00188 return; 00189 } 00190 else 00191 { 00192 CFrameEncoder * pEncoder; 00193 00194 /* clean up the xml decoder */ 00195 delete pDecoder; 00196 /* we are done with this buffer */ 00197 free(xmlbuf); 00198 00199 /* this is big enough */ 00200 binbuf = (unsigned char *) malloc(xmlLen); 00201 if(NULL == binbuf) { 00202 perror("Could not malloc buffer for LLRP Binary packet"); 00203 xmlCleanupParser(); 00204 exit(-5); 00205 } 00206 00207 memset(binbuf, 0, xmlLen); 00208 pEncoder = new CFrameEncoder(binbuf, xmlLen); 00209 00210 /* 00211 * Do the encode. 00212 * TODO: check the result, tattle on errors. 00213 */ 00214 pEncoder->encodeElement(pMessage); 00215 /* 00216 * Get the byte length of the resulting frame. 00217 */ 00218 binLen = pEncoder->getLength(); 00219 /* 00220 * Check the status, tattle on errors 00221 */ 00222 if(RC_OK != pEncoder->m_ErrorDetails.m_eResultCode) 00223 { 00224 const CErrorDetails *pError; 00225 pError = &pEncoder->m_ErrorDetails; 00226 00227 /* encode error message as binary */ 00228 fwrite(errMsgBinary,1, sizeof(errMsgBinary), outfp); 00229 00230 #ifdef XML2LLRP_DEBUG 00231 fprintf(stderr, "Failed to Encode XML message\n"); 00232 fprintf(stderr, "ERROR: Encoder error, status=%d\n", 00233 pError->m_eResultCode); 00234 if(NULL != pError->m_pRefType) 00235 { 00236 fprintf(stderr, "ERROR ... refType=%s\n", 00237 pError->m_pRefType->m_pName); 00238 } 00239 if(NULL != pError->m_pRefField) 00240 { 00241 fprintf(stderr, "ERROR ... refField=%s\n", 00242 pError->m_pRefField->m_pName); 00243 } 00244 #endif /* XML2LLRP_DEBUG */ 00245 } 00246 else 00247 { 00248 fwrite(binbuf, 1, binLen, outfp); 00249 } 00250 00251 00252 /* free the frame encoder */ 00253 free(binbuf); 00254 delete pEncoder; 00255 } 00256 00257 fclose(outfp); 00258 00259 /* free the message we built */ 00260 delete pMessage; 00261 } 00262 00263 00264 void convertDirEntry(char *idir, char *odir, struct dirent *ep) { 00265 char vector[MAX_PATH_LEN]; 00266 char iBuf[MAX_PATH_LEN]; 00267 char oBuf[MAX_PATH_LEN]; 00268 int len; 00269 00270 if(!ep) 00271 { 00272 perror("Invalid file endpoint from dirent"); 00273 } 00274 00275 /* string better end in .bin */ 00276 len = (int) strlen(ep->d_name); 00277 if(len < 4) 00278 { 00279 /* if not just ignore this file */ 00280 return; 00281 } 00282 00283 /* call it a success if we don't need to convert */ 00284 if(strncmp(&ep->d_name[len-4], ".xml", 4) != 0) { 00285 /* ignore this file */ 00286 return; 00287 } 00288 00289 memset(vector, 0x00, sizeof(vector)); 00290 #ifdef WIN32 00291 strncpy_s(vector, ep->d_name, len-4); 00292 sprintf_s(iBuf, "%s%s.xml", idir, vector); 00293 sprintf_s(oBuf, "%s%s.bin", odir, vector); 00294 #else 00295 strncpy(vector, ep->d_name, len-4); 00296 sprintf(iBuf, "%s%s.xml", idir, vector); 00297 sprintf(oBuf, "%s%s.bin", odir, vector); 00298 #endif 00299 convertFile(iBuf, oBuf); 00300 } 00301 00302 int 00303 main (int ac, char *av[]) 00304 { 00305 DIR * dpin; 00306 DIR * dpout; 00307 char idir[MAX_PATH_LEN]; 00308 char odir[MAX_PATH_LEN]; 00309 int len; 00310 struct dirent* ep; 00311 00312 /* 00313 * Check arg count 00314 */ 00315 if(ac != 3) 00316 { 00317 fprintf(stderr, "ERROR: Bad usage\nusage: %s INPUTDIR OUTPUTDIR\n", av[0]); 00318 exit(1); 00319 } 00320 00321 dpin = opendir (av[1]); 00322 if (dpin == NULL) 00323 { 00324 fprintf(stderr, "ERROR: Could not stat input directory %s\n", av[1]); 00325 exit(-1); 00326 } 00327 00328 /* make sure the directory has a path separator at the end */ 00329 #ifdef WIN32 00330 strcpy_s(idir, av[1]); 00331 #else 00332 strcpy(idir, av[1]); 00333 #endif 00334 00335 len = (int) strlen(idir); 00336 if(idir[len-1] != pathSeparator) { 00337 idir[len] = pathSeparator; 00338 idir[len + 1] = 0; 00339 } 00340 00341 00342 dpout = opendir (av[1]); 00343 if (dpout == NULL) 00344 { 00345 fprintf(stderr, "ERROR: Could not stat output directory %s\n", av[2]); 00346 exit(-1); 00347 } 00348 00349 /* make sure the directory has a path separator at the end */ 00350 #ifdef WIN32 00351 strcpy_s(odir, av[2]); 00352 #else 00353 strcpy(odir, av[2]); 00354 #endif 00355 len = (int) strlen(odir); 00356 if(odir[len-1] != pathSeparator) { 00357 odir[len] = pathSeparator; 00358 odir[len + 1] = 0; 00359 } 00360 00361 /* 00362 * Construct the type registry. This is needed for decode. 00363 */ 00364 pTypeRegistry = getTheTypeRegistry(); 00365 00366 enrollImpinjTypesIntoRegistry(pTypeRegistry); 00367 enrollImpinjInternalTypesIntoRegistry(pTypeRegistry); 00368 00369 00370 while((ep=readdir(dpin))) { 00371 convertDirEntry(idir, odir, ep); 00372 } 00373 00374 (void) closedir(dpin); 00375 (void) closedir(dpout); 00376 00377 /* 00378 * Done with the type registry. 00379 */ 00380 delete pTypeRegistry; 00381 xmlCleanupParser(); 00382 }