xml2llrp.cpp

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,2010. All rights reserved.                *
00012  *                                                                           *
00013  *****************************************************************************/
00014 
00048 #include <stdio.h>
00049 
00050 #include "ltkcpp.h"
00051 #include "Impinj/impinj_ltkcpp.h"
00052 #include "Impinj/impinjinternal_ltkcpp.h"
00053 #include "libxml/parser.h"
00054 #include "libxml/tree.h"
00055 
00056 
00057 using namespace LLRP;
00058 
00059 // turn this on to learn more about errors 
00060 #undef XML2LLRP_DEBUG
00061 
00062 #define FRAME_BUF_SIZE          (4u*1024u*1024u)
00063 
00064 /* This is the message format that is agreed upon when messages fail
00065 ** to decode. It's somewhat arbitrary, but allows us to do easy
00066 ** comparisons */
00067 const char * errMsgStr = "<ERROR_MESSAGE MessageID=\"0\" Version=\"0\">\n" \
00068                          "  <LLRPStatus>\n" \
00069                          "    <StatusCode>M_Success</StatusCode>\n" \
00070                          "    <ErrorDescription></ErrorDescription>\n" \
00071                          "  </LLRPStatus>\n" \
00072                          "</ERROR_MESSAGE>\n";
00073 
00074 /* the corresponding binary packet */
00075 unsigned char errMsgBinary[18] = {0x04, 0x64, 0x00, 0x00, 
00076                                   0x00, 0x12, 0x00, 0x00, 
00077                                   0x00, 0x00, 0x01, 0x1F, 
00078                                   0x00, 0x08, 0x00, 0x00, 
00079                                   0x00, 0x00};
00080 
00096 int
00097 main (int ac, char *av[])
00098 {
00099     CTypeRegistry *             pTypeRegistry;
00100     CXMLTextDecoder *           pDecoder;
00101     CMessage *                  pMessage;
00102     xmlDoc*                     pDoc;
00103     xmlNode*                    pNode;
00104     /*
00105      * Check arg count
00106      */
00107     if(ac != 2)
00108     {
00109         fprintf(stderr, "ERROR: Bad usage\nusage: %s INPUTFILE\n", av[0]);
00110         exit(1);
00111     }
00112 
00113     /*
00114      * Construct the type registry. This is needed for decode.
00115      */
00116     pTypeRegistry = getTheTypeRegistry();
00117 
00118     enrollImpinjTypesIntoRegistry(pTypeRegistry);
00119     enrollImpinjInternalTypesIntoRegistry(pTypeRegistry);
00120 
00121     /* use libXML to read the DOM */
00122     xmlInitParser();
00123 
00124     /* set the line numbers for error reporting */
00125     xmlLineNumbersDefault(1);
00126 
00127     pDoc = xmlReadFile(av[1], 
00128                        NULL, 
00129                        XML_PARSE_COMPACT | XML_PARSE_NONET);
00130 
00131     if(NULL == pDoc)
00132     {
00133         fprintf(stderr, "ERROR: Could not read XML File\n");
00134         delete pTypeRegistry;
00135         xmlCleanupParser();
00136         exit(2);
00137     }
00138 
00139     pNode = xmlDocGetRootElement(pDoc);
00140 
00141     /* find the first element node and make sure its PS */
00142     while((pNode) && (XML_ELEMENT_NODE != pNode->type))
00143     {
00144         pNode = pNode->next;
00145     }
00146 
00147     if(NULL == pNode)
00148     {
00149         fprintf(stderr, "ERROR: Could not get XML PacketSequence node.  " \
00150                         "Found no top-level Element nodes \n");
00151         delete pTypeRegistry;
00152         xmlCleanupParser();
00153         exit(3);
00154     }
00155 
00156     if(strcmp((const char*) pNode->name, "packetSequence") != 0)
00157     {
00158         fprintf(stderr, "ERROR: Could not get XML PacketSequence node.  " \
00159                         "Found %s instead\n", pNode->name);
00160         xmlFreeDoc(pDoc);
00161         xmlCleanupParser();
00162         delete pTypeRegistry;
00163         exit(4);
00164     }
00165     
00166     /* not sure this is necessary */
00167     freopen(NULL, "wb", stdout);
00168 
00169     /* packets are all children of the first node */
00170     pNode = pNode->children;
00171   
00172     while(pNode != NULL)
00173     {
00174         if(XML_ELEMENT_NODE == pNode->type)
00175         {
00176             xmlChar *           pMessageIDStr = NULL;
00177 
00178             /* It helps to know the message ID for debugging */
00179             pMessageIDStr = xmlGetProp(pNode, (const xmlChar*) "MessageID");
00180 
00181             /*
00182              * Construct a frame decoder. It references the
00183              * type registry and the input buffer.
00184              */
00185             pDecoder = new CXMLTextDecoder(pTypeRegistry, pNode);
00186 
00187             /*
00188              * Now ask the frame decoder to actually decode
00189              * the message. It returns NULL for an error.
00190              */
00191              pMessage = pDecoder->decodeMessage();
00192 
00193             /*
00194              * Did the decode fail?
00195              */
00196             if(NULL == pMessage)
00197             {
00198                 const CErrorDetails *pError;
00199  
00200                 /* encode error message as binary */
00201                 fwrite(errMsgBinary, 1, sizeof(errMsgBinary), stdout);
00202 
00203                 pError = &pDecoder->m_ErrorDetails;
00204  
00205 #ifdef XML2LLRP_DEBUG
00206                 fprintf(stderr, "ERROR: Decoder error, result=%d\n",
00207                         pError->m_eResultCode);
00208 
00209                 if(NULL != pMessageIDStr)
00210                 {
00211                     fprintf(stderr, "ERROR ... MessageID=%s\n", 
00212                            pMessageIDStr);
00213                 }
00214                 if(NULL != pError->m_pRefType)
00215                 { 
00216                     fprintf(stderr, "ERROR ... refType=%s\n",
00217                            pError->m_pRefType->m_pName);
00218                 }
00219                 if(NULL != pError->m_pRefField)
00220                 {
00221                     fprintf(stderr, "ERROR ... refField=%s\n",
00222                            pError->m_pRefField->m_pName);
00223                 }
00224                 if(NULL != pError->m_pWhatStr)
00225                 {
00226                     fprintf(stderr, "ERROR ... whatStr=%s\n",
00227                            pError->m_pWhatStr); 
00228                 }
00229                 if(0 != pError->m_OtherDetail)
00230                 {
00231                     fprintf(stderr, "ERROR ... XML line number %d\n", 
00232                             pError->m_OtherDetail);
00233                 }
00234 #endif /* XML2LLRP_DEBUG */
00235 
00236                 delete pDecoder;
00237                 xmlFree(pMessageIDStr);
00238             }
00239             else
00240             {
00241                 unsigned char           aOutBuffer[FRAME_BUF_SIZE];
00242                 unsigned int            nOutBuffer;
00243                 CFrameEncoder *         pEncoder;
00244 
00245 #ifdef XML2LLRP_DEBUG
00246                 if(NULL == pMessageIDStr)
00247                 {
00248                     pMessageIDStr = (xmlChar*) "unknown";
00249                 }
00250                 fprintf(stderr, "SUCCESS ... MessageID=%s passed encoding\n", 
00251                         pMessageIDStr);
00252 
00253 #endif  /* XML2LLRP_DEBUG */
00254 
00255                 xmlFree(pMessageIDStr);
00256                 delete pDecoder;
00257                 
00258                 /* encode the message as binary */
00259  
00260                 /*
00261                  * Zero fill the buffer to make things easier
00262                  * on the debugger.
00263                  */
00264                 memset(aOutBuffer, 0, sizeof aOutBuffer);
00265 
00266                 /*
00267                  * Construct a frame encoder. It references
00268                  * the output buffer and knows the maximum size.
00269                  */
00270                 pEncoder = new CFrameEncoder(aOutBuffer, 
00271                                              sizeof aOutBuffer);
00272 
00273                 /*
00274                  * Do the encode.
00275                  * TODO: check the result, tattle on errors.
00276                  */
00277                 pEncoder->encodeElement(pMessage);
00278 
00279                 /*
00280                  * Get the byte length of the resulting frame.
00281                  */
00282                 nOutBuffer = pEncoder->getLength();
00283 
00284                 /*
00285                  * Check the status, tattle on errors
00286                  */
00287                 if(RC_OK != pEncoder->m_ErrorDetails.m_eResultCode)
00288                 {
00289                     const CErrorDetails *pError;
00290 
00291                     pError = &pEncoder->m_ErrorDetails;
00292 
00293                     /* encode error message as binary */
00294                     fwrite(errMsgBinary,1, sizeof(errMsgBinary), stdout);
00295 
00296 #ifdef XML2LLRP_DEBUG
00297                     fprintf(stderr, "Failed to Encode XML message\n");
00298                     fprintf(stderr, "ERROR: Encoder error, status=%d\n",
00299                             pError->m_eResultCode);
00300                     if(NULL != pError->m_pRefType)
00301                     {
00302                         fprintf(stderr, "ERROR ... refType=%s\n",
00303                                 pError->m_pRefType->m_pName);
00304                     }
00305                     if(NULL != pError->m_pRefField)
00306                     {
00307                         fprintf(stderr, "ERROR ... refField=%s\n",
00308                                 pError->m_pRefField->m_pName);
00309                     }
00310 #endif /* XML2LLRP_DEBUG */
00311                 }
00312                 else
00313                 {
00314                     fwrite(aOutBuffer, 1, nOutBuffer, stdout);
00315                 }
00316 
00317 
00318                 /* free the frame encoder */
00319                 delete pEncoder;
00320             }
00321 
00322             /* free the message we built */
00323             delete pMessage;
00324         }
00325         pNode = pNode->next;
00326     }
00327 
00328     xmlFreeDoc(pDoc);
00329     xmlCleanupParser();
00330     delete pTypeRegistry;
00331 
00332     /*
00333      * When we get here everything that was allocated
00334      * should now be deallocated.
00335      */
00336     return 0;
00337 }
00338 
00339 
00340 

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