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 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 }