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,2008. All rights reserved.                *
00012  *                                                                           *
00013  *****************************************************************************/
00014 
00049 #include <stdio.h>
00050 
00051 #include "ltkcpp.h"
00052 #include "Impinj/impinj_ltkcpp.h"
00053 #include "Impinj/impinjinternal_ltkcpp.h"
00054 
00055 
00056 using namespace LLRP;
00057 
00058 
00059 /* Buffer sizes */
00060 #define FRAME_BUF_SIZE          (4u*1024u*1024u)
00061 #define XML_TEXT_BUF_SIZE       (10u * FRAME_BUF_SIZE)
00062 
00063 
00064 /* forward declaration */
00065 void
00066 dump (
00067   unsigned char *               pBuffer,
00068   unsigned int                  nBuffer);
00069 
00070 
00071 /*
00072  * XML header and footer enclosing the sequence of messages.
00073  */
00074 static char
00075 g_aPacketSequenceHeader[] =
00076 {
00077   "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
00078   "\n"
00079   "<ps:packetSequence\n"
00080   "  xmlns='http://www.llrp.org/ltk/schema/core/encoding/xml/1.0'\n"
00081   "  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
00082   "  xmlns:ps='http://www.llrp.org/ltk/schema/testing/encoding/xml/1.0'\n"
00083   "  xsi:schemaLocation='http://www.llrp.org/ltk/schema/core/encoding/xml/1.0\n"
00084   "                      http://www.llrp.org/ltk/schema/core/encoding/xml/1.0/llrp.xsd\n"
00085   "                      http://developer.impinj.com/ltk/schema/encoding/xml/1.10\n"
00086   "                      http://developer.impinj.com/ltk/schema/encoding/xml/1.10/impinj.xsd\n"
00087   "                      http://internal.impinj.com/RFID/Engineering/LLRP/ltk/schema/encoding/xml/1.10\n"
00088   "                      http://internal.impinj.com/RFID/Engineering/LLRP/ltk/schema/encoding/xml/1.10/impinjInternal.xsd'>\n"
00089 };
00090 
00091 static char
00092 g_aPacketSequenceFooter[] =
00093 {
00094   "\n</ps:packetSequence>\n"
00095 };
00096 
00097 /* This is the message format that is agreed upon when messages fail
00098 ** to decode. It's somewhat arbitrary, but allows us to do easy
00099 ** comparisons */
00100 static char * g_errMsgStr = "<ERROR_MESSAGE MessageID=\"0\" Version=\"0\">\n" \
00101                             "  <LLRPStatus>\n" \
00102                             "    <StatusCode>M_Success</StatusCode>\n" \
00103                             "    <ErrorDescription></ErrorDescription>\n" \
00104                             "  </LLRPStatus>\n" \
00105                             "</ERROR_MESSAGE>\n";
00106 
00107 /*
00108  * These used to be allocated as local (auto) variables.
00109  * But they are really, really big and Linux has a 10mb
00110  * stack limit. So they had to be moved here.
00111  */
00112 unsigned char                   aInBuffer[FRAME_BUF_SIZE];
00113 char                            aXMLTextBuf[XML_TEXT_BUF_SIZE];
00114 
00130 int
00131 main (int ac, char *av[])
00132 {
00133     CTypeRegistry *             pTypeRegistry;
00134     FILE *                      infp;
00135 
00136     /*
00137      * Check arg count
00138      */
00139     if(ac != 2)
00140     {
00141         fprintf(stderr, "ERROR: Bad usage\nusage: %s INPUTFILE\n", av[0]);
00142         exit(1);
00143     }
00144 
00145     /*
00146      * Open input file
00147      */
00148 #ifdef WIN32
00149     infp = fopen(av[1], "rb");
00150 #else
00151     infp = fopen(av[1], "r");
00152 #endif
00153     if(NULL == infp)
00154     {
00155         perror(av[1]);
00156         exit(2);
00157     }
00158 
00159     printf("%s\n", g_aPacketSequenceHeader);
00160 
00161     /*
00162      * Construct the type registry. This is needed for decode.
00163      */
00164     pTypeRegistry = getTheTypeRegistry();
00165 
00166     enrollImpinjTypesIntoRegistry(pTypeRegistry);
00167     enrollImpinjInternalTypesIntoRegistry(pTypeRegistry);
00168 
00169     /*
00170      * Loop iterates for each input frame
00171      */
00172     for(;;)
00173     {
00174 //        unsigned char           aInBuffer[FRAME_BUF_SIZE];
00175         unsigned int            nInBuffer = sizeof aInBuffer;
00176         bool                    bEOF;
00177 
00178         /*
00179          * Zero fill the buffer to make things easier
00180          * for printing the buffer on the debugger.
00181          */
00182         memset(aInBuffer, 0, nInBuffer);
00183 
00184         /*
00185          * Set status variables before entering the frame read loop.
00186          */
00187         nInBuffer = 0;
00188         bEOF = FALSE;
00189 
00190         /*
00191          * Loop iterates for each individual file read.
00192          * The size of each read is guided by LLRP_FrameExtract.
00193          */
00194         for(;;)
00195         {
00196             /*
00197              * Ask LLRP_FrameExtract() how we are doing
00198              * on building a frame. It'll tell us the
00199              * status and possibly the number of bytes
00200              * still needed.
00201              */
00202             CFrameExtract       MyFrameExtract(aInBuffer, nInBuffer);
00203 
00204             /*
00205              * If there is a framing error we have to declare
00206              * defeat. There is no way to realign the input
00207              * stream to a frame boundary. This could mean
00208              * the input file is bad or that the extract
00209              * function is broken.
00210              */
00211             if(CFrameExtract::FRAME_ERROR == MyFrameExtract.m_eStatus)
00212             {
00213                 fprintf(stderr, "ERROR: Frame error, bail!\n");
00214                 bEOF = TRUE;
00215                 break;
00216             }
00217 
00218             /*
00219              * If we need more bytes read them in. This may
00220              * not request the entire frame. It might be
00221              * only asking form enough of the frame so that
00222              * LLRP_FrameExtract() can determine the actual
00223              * size of the frame.
00224              */
00225             if(CFrameExtract::NEED_MORE == MyFrameExtract.m_eStatus)
00226             {
00227                 int             rc;
00228 
00229                 if (sizeof aInBuffer <
00230                         nInBuffer + MyFrameExtract.m_nBytesNeeded)
00231                 {
00232                     fprintf(stderr,"Input frame too big\n");
00233                     exit(3);
00234                 }
00235 
00236                 rc = (int)fread(&aInBuffer[nInBuffer], 1u,
00237                             MyFrameExtract.m_nBytesNeeded, infp);
00238                 if(rc <= 0)
00239                 {
00240                     if(ferror(infp))
00241                     {
00242                         fprintf(stderr,"ERROR: bad file read status\n");
00243                     }
00244                     bEOF = TRUE;
00245                     break;
00246                 }
00247                 nInBuffer += rc;
00248                 continue;
00249             }
00250 
00251             /*
00252              * The only remaining extract status we recognize
00253              * is READY. If it's anything else, give up.
00254              * This probably means that the frame extract
00255              * function is broken.
00256              */
00257             if(CFrameExtract::READY != MyFrameExtract.m_eStatus)
00258             {
00259                 fprintf(stderr, "ERROR: Unrecognized extract status, bail!\n");
00260                 bEOF = TRUE;
00261                 break;
00262             }
00263 
00264             break;
00265         }
00266 
00267         /*
00268          * Did the inner loop detect and end-of-file or other
00269          * reason to stop?
00270          */
00271         if(bEOF)
00272         {
00273             if(0 < nInBuffer)
00274             {
00275                 fprintf(stderr, "ERROR: EOF w/ %u bytes in buffer\n", nInBuffer);
00276             }
00277             break;
00278         }
00279 
00280         /* Put a blank line between messages */
00281         printf ("\n");
00282 
00283         /*
00284          * Construct a frame decoder. It references the
00285          * type registry and the input buffer.
00286          */
00287         CFrameDecoder           MyFrameDecoder(pTypeRegistry,
00288                                         aInBuffer, nInBuffer);
00289 
00290         /*
00291          * Now ask the frame decoder to actually decode
00292          * the message. It returns NULL for an error.
00293          */
00294         CMessage *              pMessage;
00295 
00296         pMessage = MyFrameDecoder.decodeMessage();
00297 
00298         /*
00299          * Did the decode fail?
00300          */
00301         if(NULL == pMessage)
00302         {
00303             const CErrorDetails *pError;
00304 
00305             pError = &MyFrameDecoder.m_ErrorDetails;
00306 
00307             fprintf(stderr, "ERROR: Decoder error, result=%d\n",
00308                 pError->m_eResultCode);
00309             if(NULL != pError->m_pRefType)
00310             {
00311                 fprintf(stderr, "ERROR ... refType=%s\n",
00312                     pError->m_pRefType->m_pName);
00313             }
00314             if(NULL != pError->m_pRefField)
00315             {
00316                 fprintf(stderr, "ERROR ... refField=%s\n",
00317                     pError->m_pRefField->m_pName);
00318             }
00319 
00320         printf("%s\n", g_errMsgStr);
00321 
00322             continue;
00323         }
00324 
00325         /*
00326          * pMessage points to the root of an object
00327          * tree representing the LLRP message.
00328          */
00329 
00330         /*
00331          * Print as XML text the LLRP message to stdout.
00332          */
00333         {
00334             CXMLTextEncoder     MyXMLEncoder(aXMLTextBuf, sizeof aXMLTextBuf);
00335 
00336             MyXMLEncoder.encodeElement(pMessage);
00337             if(!MyXMLEncoder.m_bOverflow)
00338             {
00339                 printf("%s", aXMLTextBuf);
00340             }
00341             else
00342             {
00343                 fprintf(stderr, "<!-- Buffer overflow -->\n");
00344             printf("%s\n", g_errMsgStr);
00345             }
00346         }
00347     
00348         delete pMessage;
00349     }
00350 
00351     printf("%s\n", g_aPacketSequenceFooter);
00352 
00353     /*
00354      * Done with the type registry.
00355      */
00356     delete pTypeRegistry;
00357 
00358     /*
00359      * Done with the input file.
00360      */
00361     fclose(infp);
00362 
00363     /*
00364      * When we get here everything that was allocated
00365      * should now be deallocated.
00366      */
00367     return 0;
00368 }
00369 
00388 void
00389 dump (
00390   unsigned char *               pBuffer,
00391   unsigned int                  nBuffer)
00392 {
00393     unsigned int                chk = 0;
00394     unsigned int                i;
00395 
00396     for(i = 0; i < nBuffer; i++)
00397     {
00398         if(i%4 == 0)
00399         {
00400             printf(" ");
00401         }
00402         printf(" %02X", pBuffer[i]);
00403         chk += pBuffer[i];
00404 
00405         if(i%16 == 15)
00406         {
00407             printf("  sum=%03X\n", chk);
00408             chk = 0;
00409         }
00410     }
00411     printf("\n");
00412 }

Generated on Wed Jun 6 11:55:49 2012 for LTKCPP-- LLRP Toolkit C Plus Plus Library by  doxygen 1.5.9