LTKCPP-- LLRP Toolkit C Plus Plus Library
llrp2xml.cpp
Go to the documentation of this file.
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 
00044 using namespace LLRP;
00045 
00046 #define MAX_PATH_LEN            (256)
00047 
00048 CTypeRegistry *             pTypeRegistry;
00049 
00050 
00051 /* This is the message format that is agreed upon when messages fail
00052 ** to decode. It's somewhat arbitrary, but allows us to do easy
00053 ** comparisons */
00054 static char * g_errMsgStr = "<ERROR_MESSAGE MessageID=\"0\" Version=\"0\"\n" \
00055                             " xmlns:llrp=\'http://www.llrp.org/ltk/schema/core/encoding/xml/1.0\'\n" \
00056                             " xmlns=\'http://www.llrp.org/ltk/schema/core/encoding/xml/1.0\'>\n" \
00057                             "  <LLRPStatus>\n" \
00058                             "    <StatusCode>M_Success</StatusCode>\n" \
00059                             "    <ErrorDescription></ErrorDescription>\n" \
00060                             "  </LLRPStatus>\n" \
00061                             "</ERROR_MESSAGE>\n";
00062 
00063 #ifdef WIN32
00064     char                            pathSeparator = '\\';
00065 #else
00066     char                            pathSeparator = '/';
00067 #endif
00068 
00078 void convertFile(char *ifile, char *ofile) {
00079     FILE *                      infp;
00080     FILE *                      outfp;
00081     CMessage *              pMessage;
00082     puts(ifile);
00083     puts(ofile);
00084     unsigned char *binbuf;
00085     char *xmlbuf;
00086     int xmlLen;
00087     int len;
00088 
00089     /*
00090      * Open input file
00091      */
00092 #ifdef WIN32
00093     if(fopen_s(&infp, ifile, "rb"))
00094 #else
00095     infp = fopen(ifile, "r");
00096     if(infp == NULL)
00097 #endif
00098     {
00099         perror(ifile);
00100         exit(-1);
00101     }
00102 
00103     fseek(infp,0,SEEK_END); //go to end
00104     len=ftell(infp); //get position at end (length)
00105     fseek(infp,0,SEEK_SET); //go to beg.
00106     binbuf=(unsigned char *)malloc(len); //malloc buffer
00107     if (binbuf)
00108         fread(binbuf,len,1,infp); //read into buffer
00109     fclose(infp);   
00110 
00111     if(binbuf == NULL) {
00112         perror("Could not malloc buffer for binary packet");
00113         exit(-2);
00114     }
00115 
00116     /* open the output file for writing */
00117 #ifdef WIN32
00118     if(fopen_s(&outfp, ofile, "w")) {
00119 #else
00120         outfp = fopen(ofile, "w");
00121         if(outfp == NULL) {
00122 #endif
00123         fprintf(stderr, "Could not open output file %s for writing", ofile);
00124         exit(-3);
00125     }
00126 
00127     xmlLen = 100 * len;
00128     /*
00129      * Construct a frame decoder. It references the
00130      * type registry and the input buffer.
00131      */
00132     CFrameDecoder           MyFrameDecoder(pTypeRegistry,
00133                                     binbuf, len);
00134 
00135     /*
00136      * Now ask the frame decoder to actually decode
00137      * the message. It returns NULL for an error.
00138      */
00139 
00140     pMessage = MyFrameDecoder.decodeMessage();
00141 
00142     free(binbuf);
00143 
00144     /*
00145      * Did the decode fail?
00146      */
00147     if(NULL == pMessage)
00148     {
00149         const CErrorDetails *pError;
00150 
00151         pError = &MyFrameDecoder.m_ErrorDetails;
00152 
00153         fprintf(stderr, "ERROR: Decoder error, result=%d\n",
00154             pError->m_eResultCode);
00155         if(NULL != pError->m_pRefType)
00156         {
00157             fprintf(stderr, "ERROR ... refType=%s\n",
00158                 pError->m_pRefType->m_pName);
00159         }
00160         if(NULL != pError->m_pRefField)
00161         {
00162             fprintf(stderr, "ERROR ... refField=%s\n",
00163                 pError->m_pRefField->m_pName);
00164         }
00165 
00166         fprintf(outfp, "%s\n", g_errMsgStr);
00167     } else if ((xmlbuf = (char*) malloc(xmlLen)) == NULL) {
00168         fprintf(stderr, "Could not allocate output buffer for XML file size %u\n", xmlLen);
00169         fprintf(outfp, "%s\n", g_errMsgStr);
00170     } else {        
00171         CXMLTextEncoder     MyXMLEncoder(xmlbuf, xmlLen);
00172         MyXMLEncoder.encodeElement(pMessage);
00173         if(!MyXMLEncoder.m_bOverflow)
00174         {
00175             fprintf(outfp, "%s", xmlbuf);
00176         }
00177         else
00178         {
00179             fprintf(stderr, "<!-- Buffer overflow -->\n");
00180             fprintf(outfp, "%s\n", g_errMsgStr);
00181         }
00182         free(xmlbuf);
00183     }
00184     
00185     fclose(outfp);
00186     delete pMessage;
00187 }
00188 
00189 void convertDirEntry(char *idir, char *odir, struct dirent *ep) {
00190     char vector[MAX_PATH_LEN];
00191     char iBuf[MAX_PATH_LEN];
00192     char oBuf[MAX_PATH_LEN];
00193     int len;
00194 
00195     if(!ep) 
00196     {
00197         perror("Invalid file endpoint from dirent");
00198     }
00199     
00200     /* string better end in .bin */
00201     len = (int) strlen(ep->d_name);
00202     if(len < 4) 
00203     {
00204         /* if not just ignore this file */
00205         return;
00206     }
00207 
00208     /* call it a success if we don't need to convert */
00209     if(strncmp(&ep->d_name[len-4], ".bin", 4) != 0) {
00210         /* ignore this file */
00211         return;
00212     }
00213 
00214     memset(vector, 0x00, sizeof(vector));
00215 #ifdef WIN32
00216     strncpy_s(vector, ep->d_name, len-4);
00217     sprintf_s(iBuf, "%s%s.bin", idir, vector); 
00218     sprintf_s(oBuf, "%s%s.xml", odir, vector);
00219 #else
00220     strncpy(vector, ep->d_name, len-4);
00221     sprintf(iBuf, "%s%s.bin", idir, vector); 
00222     sprintf(oBuf, "%s%s.xml", odir, vector);
00223 #endif
00224     convertFile(iBuf, oBuf);
00225 }
00226 
00227 int
00228 main (int ac, char *av[])
00229 {
00230     DIR *                       dpin;  
00231     DIR *                       dpout;
00232     char                        idir[MAX_PATH_LEN];
00233     char                        odir[MAX_PATH_LEN];
00234     int                         len;
00235     struct dirent*              ep;
00236 
00237     /*
00238      * Check arg count
00239      */
00240     if(ac != 3)
00241     {
00242         fprintf(stderr, "ERROR: Bad usage\nusage: %s INPUTDIR OUTPUTDIR\n", av[0]);
00243         exit(1);
00244     }
00245 
00246     dpin = opendir (av[1]);  
00247     if (dpin == NULL)  
00248     {    
00249         fprintf(stderr, "ERROR: Could not stat input directory %s\n", av[1]);
00250         exit(-1);
00251     }
00252 
00253     /* make sure the directory has a path separator at the end */
00254 #ifdef WIN32
00255     strcpy_s(idir, av[1]);
00256 #else
00257     strcpy(idir, av[1]);
00258 #endif
00259 
00260     len = (int) strlen(idir);
00261     if(idir[len-1] != pathSeparator) {
00262         idir[len] = pathSeparator;
00263         idir[len + 1] = 0;
00264     }
00265 
00266 
00267     dpout = opendir (av[1]);  
00268     if (dpout == NULL)  
00269     {    
00270         fprintf(stderr, "ERROR: Could not stat output directory %s\n", av[2]);
00271         exit(-1);
00272     }
00273 
00274     /* make sure the directory has a path separator at the end */
00275 #ifdef WIN32
00276     strcpy_s(odir, av[2]);
00277 #else
00278     strcpy(odir, av[2]);
00279 #endif
00280     len = (int) strlen(odir);
00281     if(odir[len-1] != pathSeparator) {
00282         odir[len] = pathSeparator;
00283         odir[len + 1] = 0;
00284     }
00285 
00286     /*
00287      * Construct the type registry. This is needed for decode.
00288      */
00289     pTypeRegistry = getTheTypeRegistry();
00290 
00291     enrollImpinjTypesIntoRegistry(pTypeRegistry);
00292     enrollImpinjInternalTypesIntoRegistry(pTypeRegistry);
00293 
00294 
00295     while((ep=readdir(dpin))) {
00296         convertDirEntry(idir, odir, ep);
00297     }
00298 
00299     (void) closedir(dpin);
00300     (void) closedir(dpout);
00301 
00302     /*
00303      * Done with the type registry.
00304      */
00305     delete pTypeRegistry;
00306 }