Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

dx101.cpp

Go to the documentation of this file.
00001 
00002 /*
00003  ***************************************************************************
00004  *  Copyright 2007,2008 Impinj, Inc.
00005  *
00006  *  Licensed under the Apache License, Version 2.0 (the "License");
00007  *  you may not use this file except in compliance with the License.
00008  *  You may obtain a copy of the License at
00009  *
00010  *      http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  *  Unless required by applicable law or agreed to in writing, software
00013  *  distributed under the License is distributed on an "AS IS" BASIS,
00014  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  *  See the License for the specific language governing permissions and
00016  *  limitations under the License.
00017  *
00018  ***************************************************************************
00019  */
00020 
00058 #include <stdio.h>
00059 
00060 #include "ltkcpp.h"
00061 
00062 
00063 using namespace LLRP;
00064 
00065 
00066 /* forward declaration */
00067 void
00068 dump (
00069   unsigned char *               pBuffer,
00070   unsigned int                  nBuffer);
00071 
00072 
00088 int
00089 main (int ac, char *av[])
00090 {
00091     CTypeRegistry *             pTypeRegistry;
00092     FILE *                      infp;
00093 
00094     /*
00095      * Check arg count
00096      */
00097     if(ac != 2)
00098     {
00099         printf("ERROR: Bad usage\nusage: %s INPUTFILE\n", av[0]);
00100         exit(1);
00101     }
00102 
00103     /*
00104      * Open input file
00105      */
00106 #ifdef WIN32
00107     infp = fopen(av[1], "rb");
00108 #else
00109     infp = fopen(av[1], "r");
00110 #endif
00111     if(NULL == infp)
00112     {
00113         perror(av[1]);
00114         exit(2);
00115     }
00116 
00117     printf("Starting\n");
00118 
00119     /*
00120      * Construct the type registry. This is needed for decode.
00121      */
00122     pTypeRegistry = getTheTypeRegistry();
00123 
00124     /*
00125      * Loop iterates for each input frame
00126      */
00127     for(;;)
00128     {
00129         unsigned char           aInBuffer[16u*1024u];
00130         unsigned int            nInBuffer;
00131         bool                    bEOF;
00132 
00133         /*
00134          * Zero fill the buffer to make things easier
00135          * for printing the buffer on the debugger.
00136          */
00137         memset(aInBuffer, 0, sizeof aInBuffer);
00138 
00139         /*
00140          * Set status variables before entering the frame read loop.
00141          */
00142         nInBuffer = 0;
00143         bEOF = FALSE;
00144 
00145         /*
00146          * Loop iterates for each individual file read.
00147          * The size of each read is guided by LLRP_FrameExtract.
00148          */
00149         for(;;)
00150         {
00151             /*
00152              * Ask LLRP_FrameExtract() how we are doing
00153              * on building a frame. It'll tell us the
00154              * status and possibly the number of bytes
00155              * still needed.
00156              */
00157             CFrameExtract       MyFrameExtract(aInBuffer, nInBuffer);
00158 
00159             /*
00160              * If there is a framing error we have to declare
00161              * defeat. There is no way to realign the input
00162              * stream to a frame boundary. This could mean
00163              * the input file is bad or that the extract
00164              * function is broken.
00165              */
00166             if(CFrameExtract::FRAME_ERROR == MyFrameExtract.m_eStatus)
00167             {
00168                 printf("ERROR: Frame error, bail!\n");
00169                 bEOF = TRUE;
00170                 break;
00171             }
00172 
00173             /*
00174              * If we need more bytes read them in. This may
00175              * not request the entire frame. It might be
00176              * only asking form enough of the frame so that
00177              * LLRP_FrameExtract() can determine the actual
00178              * size of the frame.
00179              */
00180             if(CFrameExtract::NEED_MORE == MyFrameExtract.m_eStatus)
00181             {
00182                 int             rc;
00183 
00184                 rc = (int)fread(&aInBuffer[nInBuffer], 1u,
00185                             MyFrameExtract.m_nBytesNeeded, infp);
00186                 if(rc <= 0)
00187                 {
00188                     if(ferror(infp))
00189                     {
00190                         printf("ERROR: bad file read status\n");
00191                     }
00192                     bEOF = TRUE;
00193                     break;
00194                 }
00195                 nInBuffer += rc;
00196                 continue;
00197             }
00198 
00199             /*
00200              * The only remaining extract status we recognize
00201              * is READY. If it's anything else, give up.
00202              * This probably means that the frame extract
00203              * function is broken.
00204              */
00205             if(CFrameExtract::READY != MyFrameExtract.m_eStatus)
00206             {
00207                 printf("ERROR: Unrecognized extract status, bail!\n");
00208                 bEOF = TRUE;
00209                 break;
00210             }
00211 
00212             /*
00213              * The input buffer is ready -- it contains a complete frame.
00214              * Tattle on key FrameExtract values and exit this
00215              * frame-read loop.
00216              */
00217             printf("Frame nBuf=%u Length=%u ID=%u Type=%u Vers=%u\n",
00218                 nInBuffer,
00219                 MyFrameExtract.m_MessageLength,
00220                 MyFrameExtract.m_MessageID,
00221                 MyFrameExtract.m_MessageType,
00222                 MyFrameExtract.m_ProtocolVersion);
00223 
00224             break;
00225         }
00226 
00227         /*
00228          * Did the inner loop detect and end-of-file or other
00229          * reason to stop?
00230          */
00231         if(bEOF)
00232         {
00233             if(0 < nInBuffer)
00234             {
00235                 printf("ERROR: EOF w/ %u bytes in buffer\n", nInBuffer);
00236             }
00237             break;
00238         }
00239 
00240         /*
00241          * Construct a frame decoder. It references the
00242          * type registry and the input buffer.
00243          */
00244         CFrameDecoder           MyFrameDecoder(pTypeRegistry,
00245                                         aInBuffer, nInBuffer);
00246 
00247         /*
00248          * Now ask the frame decoder to actually decode
00249          * the message. It returns NULL for an error.
00250          */
00251         CMessage *              pMessage;
00252 
00253         pMessage = MyFrameDecoder.decodeMessage();
00254 
00255         /*
00256          * Did the decode fail?
00257          */
00258         if(NULL == pMessage)
00259         {
00260             const CErrorDetails *pError;
00261 
00262             pError = &MyFrameDecoder.m_ErrorDetails;
00263 
00264             printf("ERROR: Decoder error, result=%d\n",
00265                 pError->m_eResultCode);
00266             if(NULL != pError->m_pRefType)
00267             {
00268                 printf("ERROR ... refType=%s\n",
00269                     pError->m_pRefType->m_pName);
00270             }
00271             if(NULL != pError->m_pRefField)
00272             {
00273                 printf("ERROR ... refField=%s\n",
00274                     pError->m_pRefField->m_pName);
00275             }
00276 
00277             continue;
00278         }
00279 
00280         /*
00281          * pMessage points to the root of an object
00282          * tree representing the LLRP message.
00283          */
00284 
00285         /*
00286          * Print as XML text the LLRP message to stdout.
00287          */
00288         {
00289             char                aBuf[100*1024];
00290             CXMLTextEncoder     MyXMLEncoder(aBuf, sizeof aBuf);
00291 
00292             MyXMLEncoder.encodeElement(pMessage);
00293             if(!MyXMLEncoder.m_bOverflow)
00294             {
00295                 printf("%s", aBuf);
00296             }
00297             else
00298             {
00299                 printf("<!-- Buffer overflow -->\n");
00300             }
00301         }
00302 
00303         /*
00304          * Encode the LLRP message into a separate frame buffer.
00305          * Compare the resulting frame to the input frame.
00306          * Tattle on any differences.
00307          */
00308         {
00309             unsigned char   aOutBuffer[16u*1024u];
00310             unsigned int    nOutBuffer;
00311 
00312             /*
00313              * Zero fill the buffer to make things easier
00314              * on the debugger.
00315              */
00316             memset(aOutBuffer, 0, sizeof aOutBuffer);
00317 
00318             /*
00319              * Construct a frame encoder. It references
00320              * the output buffer and knows the maximum size.
00321              */
00322             CFrameEncoder   MyFrameEncoder(aOutBuffer, sizeof aOutBuffer);
00323 
00324             /*
00325              * Do the encode.
00326              * TODO: check the result, tattle on errors.
00327              */
00328             MyFrameEncoder.encodeElement(pMessage);
00329 
00330             /*
00331              * Get the byte length of the resulting frame.
00332              */
00333             nOutBuffer = MyFrameEncoder.getLength();
00334 
00335             /*
00336              * Check the status, tattle on errors
00337              */
00338             if(RC_OK != MyFrameEncoder.m_ErrorDetails.m_eResultCode)
00339             {
00340                 const CErrorDetails *pError;
00341 
00342                 pError = &MyFrameEncoder.m_ErrorDetails;
00343 
00344                 printf("ERROR: Encoder error, status=%d\n",
00345                     pError->m_eResultCode);
00346                 if(NULL != pError->m_pRefType)
00347                 {
00348                     printf("ERROR ... refType=%s\n",
00349                         pError->m_pRefType->m_pName);
00350                 }
00351                 if(NULL != pError->m_pRefField)
00352                 {
00353                     printf("ERROR ... refField=%s\n",
00354                         pError->m_pRefField->m_pName);
00355                 }
00356             }
00357 
00358             /*
00359              * The resulting frame should be an exact
00360              * match for the input frame.
00361              */
00362             if(nOutBuffer != nInBuffer ||
00363                0 != memcmp(aInBuffer, aOutBuffer, nInBuffer))
00364             {
00365                 /*
00366                  * Print hex dumps of each frame to aid debugging.
00367                  */
00368                 printf("ERROR: Miscompare\n");
00369                 printf("ERROR: ... Input  length=%u\n", nInBuffer);
00370                 dump(aInBuffer, nInBuffer);
00371                 printf("ERROR: ... Output length=%u\n", nOutBuffer);
00372                 dump(aOutBuffer, nOutBuffer);
00373             }
00374         }
00375 
00376         /*
00377          * Destruct the message. This must deallocate
00378          * everything that was allocated during decode.
00379          */
00380         delete pMessage;
00381     }
00382 
00383     printf ("Finished\n");
00384 
00385     /*
00386      * Done with the type registry.
00387      */
00388     delete pTypeRegistry;
00389 
00390     /*
00391      * Done with the input file.
00392      */
00393     fclose(infp);
00394 
00395     /*
00396      * When we get here everything that was allocated
00397      * should now be deallocated.
00398      */
00399     return 0;
00400 }
00401 
00420 void
00421 dump (
00422   unsigned char *               pBuffer,
00423   unsigned int                  nBuffer)
00424 {
00425     unsigned int                chk = 0;
00426     unsigned int                i;
00427 
00428     for(i = 0; i < nBuffer; i++)
00429     {
00430         if(i%4 == 0)
00431         {
00432             printf(" ");
00433         }
00434         printf(" %02X", pBuffer[i]);
00435         chk += pBuffer[i];
00436 
00437         if(i%16 == 15)
00438         {
00439             printf("  sum=%03X\n", chk);
00440             chk = 0;
00441         }
00442     }
00443     printf("\n");
00444 }

Generated on Wed Nov 26 12:27:44 2008 for LTKCPP-- LLRP Toolkit C Plus Plus Library by  doxygen 1.3.9.1