LTKCPP-- LLRP Toolkit C Plus Plus Library
custom_select_2.cpp
1 
2 /*
3  *****************************************************************************
4  * *
5  * IMPINJ CONFIDENTIAL AND PROPRIETARY *
6  * *
7  * This source code is the sole property of Impinj, Inc. Reproduction or *
8  * utilization of this source code in whole or in part is forbidden without *
9  * the prior written consent of Impinj, Inc. *
10  * *
11  * (c) Copyright Impinj, Inc. 2007,2009. All rights reserved. *
12  * *
13  *****************************************************************************/
14 
44 #include <stdio.h>
45 #include "ltkcpp.h"
46 #include "impinj_ltkcpp.h"
47 #include "time.h"
48 
49 using namespace LLRP;
50 
51 /*
52 ** Sorry, we use this linux safe method
53 ** to print buffers. WIndows has the same
54 ** method, but by a different name
55 */
56 #if (WIN32)
57 #define snprintf _snprintf
58 #endif
59 
60 class CMyApplication
61 {
62  unsigned int m_messageID;
63 
64  public:
66  int m_Verbose;
67 
69  CConnection * m_pConnectionToReader;
70 
71  inline
72  CMyApplication (void)
73  : m_Verbose(0), m_pConnectionToReader(NULL)
74  {
75  m_messageID = 0;
76  }
77 
78  int
79  run (
80  char * pReaderHostName);
81 
82  int
83  checkConnectionStatus (void);
84 
85  int
86  enableImpinjExtensions (void);
87 
88  int
89  resetConfigurationToFactoryDefaults (void);
90 
91  int
92  addROSpec (void);
93 
94  int
95  enableROSpec (void);
96 
97  int
98  startROSpec (void);
99 
100  int
101  stopROSpec (void);
102 
103  int
104  awaitAndPrintReport (int timeoutSec);
105 
106  void
107  printTagReportData (
108  CRO_ACCESS_REPORT * pRO_ACCESS_REPORT);
109 
110  void
111  printOneTagReportData (
112  CTagReportData * pTagReportData);
113 
114  void
115  formatOneEPC (
116  CParameter * pEpcParameter,
117  char * buf,
118  int buflen);
119 
120  void
121  handleReaderEventNotification (
122  CReaderEventNotificationData *pNtfData);
123 
124  void
125  handleAntennaEvent (
126  CAntennaEvent * pAntennaEvent);
127 
128  void
129  handleReaderExceptionEvent (
130  CReaderExceptionEvent * pReaderExceptionEvent);
131 
132  int
133  checkLLRPStatus (
134  CLLRPStatus * pLLRPStatus,
135  char * pWhatStr);
136 
137  CMessage *
138  transact (
139  CMessage * pSendMsg);
140 
141  CMessage *
142  recvMessage (
143  int nMaxMS);
144 
145  int
146  sendMessage (
147  CMessage * pSendMsg);
148 
149  void
150  printXMLMessage (
151  CMessage * pMessage);
152 };
153 
154 
155 /* BEGIN forward declarations */
156 int
157 main (
158  int ac,
159  char * av[]);
160 
161 void
162 usage (
163  char * pProgName);
164 /* END forward declarations */
165 
166 
182 int
183 main (
184  int ac,
185  char * av[])
186 {
187  CMyApplication myApp;
188  char * pReaderHostName;
189  int rc;
190 
191  /*
192  * Process comand arguments, determine reader name
193  * and verbosity level.
194  */
195  if(ac == 2)
196  {
197  pReaderHostName = av[1];
198  }
199  else if(ac == 3)
200  {
201  char * p = av[1];
202 
203  while(*p)
204  {
205  switch(*p++)
206  {
207  case '-': /* linux conventional option warn char */
208  case '/': /* Windows/DOS conventional option warn char */
209  break;
210 
211  case 'v':
212  case 'V':
213  myApp.m_Verbose++;
214  break;
215 
216  default:
217  usage(av[0]);
218  /* no return */
219  break;
220  }
221  }
222 
223  pReaderHostName = av[2];
224  }
225  else
226  {
227  usage(av[0]);
228  /* no return */
229  }
230 
231  /*
232  * Run application, capture return value for exit status
233  */
234  rc = myApp.run(pReaderHostName);
235 
236  printf("INFO: Done\n");
237 
238  /*
239  * Exit with the right status.
240  */
241  if(0 == rc)
242  {
243  exit(0);
244  }
245  else
246  {
247  exit(2);
248  }
249  /*NOTREACHED*/
250 }
251 
252 
264 void
265 usage (
266  char * pProgName)
267 {
268 #ifdef linux
269  printf("Usage: %s [-v[v]] READERHOSTNAME\n", pProgName);
270  printf("\n");
271  printf("Each -v increases verbosity level\n");
272 #endif /* linux */
273 #ifdef WIN32
274  printf("Usage: %s [/v[v]] READERHOSTNAME\n", pProgName);
275  printf("\n");
276  printf("Each /v increases verbosity level\n");
277 #endif /* WIN32 */
278  exit(1);
279 }
280 
281 
315 int
316 CMyApplication::run (
317  char * pReaderHostName)
318 {
319  CTypeRegistry * pTypeRegistry;
320  CConnection * pConn;
321  int rc;
322 
323  /*
324  * Allocate the type registry. This is needed
325  * by the connection to decode.
326  */
327  pTypeRegistry = getTheTypeRegistry();
328  if(NULL == pTypeRegistry)
329  {
330  printf("ERROR: getTheTypeRegistry failed\n");
331  return -1;
332  }
333 
334  /*
335  * Enroll impinj extension types into the
336  * type registry, in preparation for using
337  * Impinj extension params.
338  */
340 
341  /*
342  * Construct a connection (LLRP::CConnection).
343  * Using a 32kb max frame size for send/recv.
344  * The connection object is ready for business
345  * but not actually connected to the reader yet.
346  */
347  pConn = new CConnection(pTypeRegistry, 32u*1024u);
348  if(NULL == pConn)
349  {
350  printf("ERROR: new CConnection failed\n");
351  return -2;
352  }
353 
354  /*
355  * Open the connection to the reader
356  */
357  if(m_Verbose)
358  {
359  printf("INFO: Connecting to %s....\n", pReaderHostName);
360  }
361 
362  rc = pConn->openConnectionToReader(pReaderHostName);
363  if(0 != rc)
364  {
365  printf("ERROR: connect: %s (%d)\n", pConn->getConnectError(), rc);
366  delete pConn;
367  return -3;
368  }
369 
370  /*
371  * Record the pointer to the connection object so other
372  * routines can use it.
373  */
374  m_pConnectionToReader = pConn;
375 
376  if(m_Verbose)
377  {
378  printf("INFO: Connected, checking status....\n");
379  }
380 
381  /*
382  * Commence the sequence and check for errors as we go.
383  * See comments for each routine for details.
384  * Each routine prints messages.
385  */
386  rc = 1;
387  if(0 == checkConnectionStatus())
388  {
389  rc = 2;
390  if(0 == enableImpinjExtensions())
391  {
392  rc = 3;
393  if(0 == resetConfigurationToFactoryDefaults())
394  {
395  rc = 4;
396  if(0 == addROSpec())
397  {
398  rc = 5;
399  if(0 == enableROSpec())
400  {
401  //rc = 6;
402  //if(0 == startROSpec())
403  //{
404  rc = 7;
405  if(0 == awaitAndPrintReport(10))
406  {
407  rc = 8;
408  if(0 == stopROSpec())
409  {
410  rc = 0;
411  }
412  }
413  //}
414  }
415  }
416  }
417 
418  /*
419  * After we're done, try to leave the reader
420  * in a clean state for next use. This is best
421  * effort and no checking of the result is done.
422  */
423  if(m_Verbose)
424  {
425  printf("INFO: Clean up reader configuration...\n");
426  }
427  resetConfigurationToFactoryDefaults();
428  }
429  }
430 
431  if(m_Verbose)
432  {
433  printf("INFO: Finished\n");
434  }
435 
436  /*
437  * Close the connection and release its resources
438  */
439  pConn->closeConnectionToReader();
440  delete pConn;
441 
442  /*
443  * Done with the registry.
444  */
445  delete pTypeRegistry;
446 
447  /*
448  * When we get here all allocated memory should have been deallocated.
449  */
450 
451  return rc;
452 }
453 
454 
485 int
486 CMyApplication::checkConnectionStatus (void)
487 {
488  CMessage * pMessage;
491  CConnectionAttemptEvent * pEvent;
492 
493  /*
494  * Expect the notification within 10 seconds.
495  * It is suppose to be the very first message sent.
496  */
497  pMessage = recvMessage(10000);
498 
499  /*
500  * recvMessage() returns NULL if something went wrong.
501  */
502  if(NULL == pMessage)
503  {
504  /* recvMessage already tattled */
505  goto fail;
506  }
507 
508  /*
509  * Check to make sure the message is of the right type.
510  * The type label (pointer) in the message should be
511  * the type descriptor for READER_EVENT_NOTIFICATION.
512  */
513  if(&CREADER_EVENT_NOTIFICATION::s_typeDescriptor != pMessage->m_pType)
514  {
515  goto fail;
516  }
517 
518  /*
519  * Now that we are sure it is a READER_EVENT_NOTIFICATION,
520  * traverse to the ReaderEventNotificationData parameter.
521  */
522  pNtf = (CREADER_EVENT_NOTIFICATION *) pMessage;
523  pNtfData = pNtf->getReaderEventNotificationData();
524  if(NULL == pNtfData)
525  {
526  goto fail;
527  }
528 
529  /*
530  * The ConnectionAttemptEvent parameter must be present.
531  */
532  pEvent = pNtfData->getConnectionAttemptEvent();
533  if(NULL == pEvent)
534  {
535  goto fail;
536  }
537 
538  /*
539  * The status in the ConnectionAttemptEvent parameter
540  * must indicate connection success.
541  */
543  {
544  goto fail;
545  }
546 
547  /*
548  * Done with the message
549  */
550  delete pMessage;
551 
552  if(m_Verbose)
553  {
554  printf("INFO: Connection status OK\n");
555  }
556 
557  /*
558  * Victory.
559  */
560  return 0;
561 
562  fail:
563  /*
564  * Something went wrong. Tattle. Clean up. Return error.
565  */
566  printf("ERROR: checkConnectionStatus failed\n");
567  delete pMessage;
568  return -1;
569 }
570 
588 int
589 CMyApplication::enableImpinjExtensions (void)
590 {
592  CMessage * pRspMsg;
594 
595  /*
596  * Compose the command message
597  */
598  pCmd = new CIMPINJ_ENABLE_EXTENSIONS();
599  pCmd->setMessageID(m_messageID++);
600  /*
601  * Send the message, expect the response of certain type
602  */
603  pRspMsg = transact(pCmd);
604 
605  /*
606  * Done with the command message
607  */
608  delete pCmd;
609 
610  /*
611  * transact() returns NULL if something went wrong.
612  */
613  if(NULL == pRspMsg)
614  {
615  /* transact already tattled */
616  return -1;
617  }
618 
619  /*
620  * Cast to a CIMPINJ_ENABLE_EXTENSIONS_RESPONSE message.
621  */
622  pRsp = (CIMPINJ_ENABLE_EXTENSIONS_RESPONSE *) pRspMsg;
623 
624  /*
625  * Check the LLRPStatus parameter.
626  */
627  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(),
628  "enableImpinjExtensions"))
629  {
630  /* checkLLRPStatus already tattled */
631  delete pRspMsg;
632  return -1;
633  }
634 
635  /*
636  * Done with the response message.
637  */
638  delete pRspMsg;
639 
640  /*
641  * Tattle progress, maybe
642  */
643  if(m_Verbose)
644  {
645  printf("INFO: Impinj Extensions are enabled\n");
646  }
647 
648  /*
649  * Victory.
650  */
651  return 0;
652 }
653 
674 int
675 CMyApplication::resetConfigurationToFactoryDefaults (void)
676 {
677  CSET_READER_CONFIG * pCmd;
678  CMessage * pRspMsg;
680 
681  /*
682  * Compose the command message
683  */
684  pCmd = new CSET_READER_CONFIG();
685  pCmd->setMessageID(m_messageID++);
686  pCmd->setResetToFactoryDefault(1);
687 
688  /*
689  * Send the message, expect the response of certain type
690  */
691  pRspMsg = transact(pCmd);
692 
693  /*
694  * Done with the command message
695  */
696  delete pCmd;
697 
698  /*
699  * transact() returns NULL if something went wrong.
700  */
701  if(NULL == pRspMsg)
702  {
703  /* transact already tattled */
704  return -1;
705  }
706 
707  /*
708  * Cast to a SET_READER_CONFIG_RESPONSE message.
709  */
710  pRsp = (CSET_READER_CONFIG_RESPONSE *) pRspMsg;
711 
712  /*
713  * Check the LLRPStatus parameter.
714  */
715  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(),
716  "resetConfigurationToFactoryDefaults"))
717  {
718  /* checkLLRPStatus already tattled */
719  delete pRspMsg;
720  return -1;
721  }
722 
723  /*
724  * Done with the response message.
725  */
726  delete pRspMsg;
727 
728  /*
729  * Tattle progress, maybe
730  */
731  if(m_Verbose)
732  {
733  printf("INFO: Configuration reset to factory defaults\n");
734  }
735 
736  /*
737  * Victory.
738  */
739  return 0;
740 }
741 
742 
790 int
791 CMyApplication::addROSpec (void)
792 {
793  CROSpecStartTrigger * pROSpecStartTrigger =
794  new CROSpecStartTrigger();
795  pROSpecStartTrigger->setROSpecStartTriggerType(
797 
798  CROSpecStopTrigger * pROSpecStopTrigger = new CROSpecStopTrigger();
800  pROSpecStopTrigger->setDurationTriggerValue(0); /* n/a */
801 
802  CROBoundarySpec * pROBoundarySpec = new CROBoundarySpec();
803  pROBoundarySpec->setROSpecStartTrigger(pROSpecStartTrigger);
804  pROBoundarySpec->setROSpecStopTrigger(pROSpecStopTrigger);
805 
806  CAISpecStopTrigger * pAISpecStopTrigger = new CAISpecStopTrigger();
807  pAISpecStopTrigger->setAISpecStopTriggerType(
809  pAISpecStopTrigger->setDurationTrigger(0);
810 
811  CTagObservationTrigger * pAISpecTagObsvTrigger = new CTagObservationTrigger();
813  pAISpecTagObsvTrigger->setNumberOfTags(100);
814  pAISpecTagObsvTrigger->setNumberOfAttempts(0);
815  pAISpecTagObsvTrigger->setT(0);
816  pAISpecTagObsvTrigger->setTimeout(500);
817 
818  pAISpecStopTrigger->setTagObservationTrigger(pAISpecTagObsvTrigger);
819 
820 
822 
823 
824  CInventoryParameterSpec * pInventoryParameterSpec =
826  pInventoryParameterSpec->setInventoryParameterSpecID(1234);
827  pInventoryParameterSpec->setProtocolID(AirProtocols_EPCGlobalClass1Gen2);
828 
829  CAntennaConfiguration * pAntennaConfig = new CAntennaConfiguration();
830  pAntennaConfig->setAntennaID(1);
831 
832  CRFTransmitter * pRFTransmitter = new CRFTransmitter();
833  pRFTransmitter->setHopTableID(1);
834  pRFTransmitter->setChannelIndex(0);
835  pRFTransmitter->setTransmitPower(81);
836  pAntennaConfig->setRFTransmitter(pRFTransmitter);
837 
838  CC1G2InventoryCommand * pC1G2InventoryCmd = new CC1G2InventoryCommand();
839  pC1G2InventoryCmd->setTagInventoryStateAware(1);
840 
841 // Filter 1
842  CC1G2Filter * pC1G2Filter1 = new CC1G2Filter();
844 
845  CC1G2TagInventoryMask * pC1G2TagInvMask1 = new CC1G2TagInventoryMask();
846  pC1G2TagInvMask1->setMB(2);
847  pC1G2TagInvMask1->setPointer(0);
848 
849  llrp_u1v_t tagMask1 = llrp_u1v_t(15);
850  tagMask1.m_nBit = 15;
851  tagMask1.m_pValue[0] = 0xE2;
852  tagMask1.m_pValue[1] = 0x00;
853  pC1G2TagInvMask1->setTagMask(tagMask1);
854 
855  pC1G2Filter1->setC1G2TagInventoryMask(pC1G2TagInvMask1);
856 
857  CC1G2TagInventoryStateAwareFilterAction * pC1G2TagInvStateAwareFilterAction1 = new CC1G2TagInventoryStateAwareFilterAction();
858  pC1G2TagInvStateAwareFilterAction1->setTarget(C1G2StateAwareTarget_Inventoried_State_For_Session_S3);
859  pC1G2TagInvStateAwareFilterAction1->setAction(C1G2StateAwareAction_AssertSLOrA_DeassertSLOrB);
860 
861  pC1G2Filter1->setC1G2TagInventoryStateAwareFilterAction(pC1G2TagInvStateAwareFilterAction1);
862 
863  pC1G2InventoryCmd->addC1G2Filter(pC1G2Filter1);
864 
865  // Filter 2
866  CC1G2Filter * pC1G2Filter2 = new CC1G2Filter();
868 
869  CC1G2TagInventoryMask * pC1G2TagInvMask2 = new CC1G2TagInventoryMask();
870  pC1G2TagInvMask2->setMB(1);
871  pC1G2TagInvMask2->setPointer(0);
872 
873  llrp_u1v_t tagMask2 = llrp_u1v_t(16);
874  tagMask2.m_nBit = 16;
875  tagMask2.m_pValue[0] = 0xE2;
876  tagMask2.m_pValue[1] = 0x00;
877  pC1G2TagInvMask2->setTagMask(tagMask2);
878 
879  pC1G2Filter2->setC1G2TagInventoryMask(pC1G2TagInvMask2);
880 
881  CC1G2TagInventoryStateAwareFilterAction * pC1G2TagInvStateAwareFilterAction2 = new CC1G2TagInventoryStateAwareFilterAction();
882  pC1G2TagInvStateAwareFilterAction2->setTarget(C1G2StateAwareTarget_Inventoried_State_For_Session_S2);
883  pC1G2TagInvStateAwareFilterAction2->setAction(C1G2StateAwareAction_AssertSLOrA_DeassertSLOrB);
884 
885  pC1G2Filter2->setC1G2TagInventoryStateAwareFilterAction(pC1G2TagInvStateAwareFilterAction2);
886 
887  pC1G2InventoryCmd->addC1G2Filter(pC1G2Filter2);
888 
889 // Filter 3
890  CC1G2Filter * pC1G2Filter3 = new CC1G2Filter();
892 
893  CC1G2TagInventoryMask * pC1G2TagInvMask3 = new CC1G2TagInventoryMask();
894  pC1G2TagInvMask3->setMB(3);
895  pC1G2TagInvMask3->setPointer(0);
896 
897  llrp_u1v_t tagMask3 = llrp_u1v_t(32);
898  tagMask3.m_nBit = 32;
899  tagMask3.m_pValue[0] = 0xFF;
900  tagMask3.m_pValue[1] = 0xFF;
901  tagMask3.m_pValue[2] = 0xE2;
902  tagMask3.m_pValue[3] = 0x00;
903  pC1G2TagInvMask3->setTagMask(tagMask3);
904 
905  pC1G2Filter3->setC1G2TagInventoryMask(pC1G2TagInvMask3);
906 
907  CC1G2TagInventoryStateAwareFilterAction * pC1G2TagInvStateAwareFilterAction3 = new CC1G2TagInventoryStateAwareFilterAction();
908  pC1G2TagInvStateAwareFilterAction3->setTarget(C1G2StateAwareTarget_Inventoried_State_For_Session_S1);
909  pC1G2TagInvStateAwareFilterAction3->setAction(C1G2StateAwareAction_AssertSLOrA_DeassertSLOrB);
910 
911  pC1G2Filter3->setC1G2TagInventoryStateAwareFilterAction(pC1G2TagInvStateAwareFilterAction3);
912 
913  pC1G2InventoryCmd->addC1G2Filter(pC1G2Filter3);
914 
915 // Filter 4
916  CC1G2Filter * pC1G2Filter4 = new CC1G2Filter();
918 
919  CC1G2TagInventoryMask * pC1G2TagInvMask4 = new CC1G2TagInventoryMask();
920  pC1G2TagInvMask4->setMB(2);
921  pC1G2TagInvMask4->setPointer(0);
922 
923  llrp_u1v_t tagMask4 = llrp_u1v_t(8);
924  tagMask4.m_nBit = 8;
925  tagMask4.m_pValue[0] = 0xAA;
926  pC1G2TagInvMask4->setTagMask(tagMask4);
927 
928  pC1G2Filter4->setC1G2TagInventoryMask(pC1G2TagInvMask4);
929 
930  CC1G2TagInventoryStateAwareFilterAction * pC1G2TagInvStateAwareFilterAction4 = new CC1G2TagInventoryStateAwareFilterAction();
931  pC1G2TagInvStateAwareFilterAction4->setTarget(C1G2StateAwareTarget_Inventoried_State_For_Session_S0);
932  pC1G2TagInvStateAwareFilterAction4->setAction(C1G2StateAwareAction_AssertSLOrA_DeassertSLOrB);
933 
934  pC1G2Filter4->setC1G2TagInventoryStateAwareFilterAction(pC1G2TagInvStateAwareFilterAction4);
935 
936  pC1G2InventoryCmd->addC1G2Filter(pC1G2Filter4);
937 
938 // Filter 5
939  CC1G2Filter * pC1G2Filter5 = new CC1G2Filter();
941 
942  CC1G2TagInventoryMask * pC1G2TagInvMask5 = new CC1G2TagInventoryMask();
943  pC1G2TagInvMask5->setMB(1);
944  pC1G2TagInvMask5->setPointer(0);
945 
946  llrp_u1v_t tagMask5 = llrp_u1v_t(16);
947  tagMask5.m_nBit = 16;
948  tagMask5.m_pValue[0] = 0xFF;
949  tagMask5.m_pValue[1] = 0xFF;
950  pC1G2TagInvMask5->setTagMask(tagMask5);
951 
952  pC1G2Filter5->setC1G2TagInventoryMask(pC1G2TagInvMask5);
953 
954  CC1G2TagInventoryStateAwareFilterAction * pC1G2TagInvStateAwareFilterAction5 = new CC1G2TagInventoryStateAwareFilterAction();
955  pC1G2TagInvStateAwareFilterAction5->setTarget(C1G2StateAwareTarget_SL);
956  pC1G2TagInvStateAwareFilterAction5->setAction(C1G2StateAwareAction_AssertSLOrA_DeassertSLOrB);
957 
958  pC1G2Filter5->setC1G2TagInventoryStateAwareFilterAction(pC1G2TagInvStateAwareFilterAction5);
959 
960  pC1G2InventoryCmd->addC1G2Filter(pC1G2Filter5);
961 
962 //
963 
964 
965  CC1G2SingulationControl * pC1G2SingulationControl = new CC1G2SingulationControl();
966  pC1G2SingulationControl->setSession(1);
967  pC1G2SingulationControl->setTagPopulation(32);
968  pC1G2SingulationControl->setTagTransitTime(0);
969 
971  pC1G2TagInvStateAwareSingAction->setI(C1G2TagInventoryStateAwareI_State_B);
972  pC1G2TagInvStateAwareSingAction->setS(C1G2TagInventoryStateAwareS_SL);
973 
974  pC1G2SingulationControl->setC1G2TagInventoryStateAwareSingulationAction(pC1G2TagInvStateAwareSingAction);
975 
976  pC1G2InventoryCmd->setC1G2SingulationControl(pC1G2SingulationControl);
977 
978  pAntennaConfig->addAirProtocolInventoryCommandSettings(pC1G2InventoryCmd);
979 
980  pInventoryParameterSpec->addAntennaConfiguration(pAntennaConfig);
981 
983  llrp_u16v_t AntennaIDs = llrp_u16v_t(1);
984  AntennaIDs.m_pValue[0] = 1;
985 
986  CAISpec * pAISpec = new CAISpec();
987  pAISpec->setAntennaIDs(AntennaIDs);
988  pAISpec->setAISpecStopTrigger(pAISpecStopTrigger);
989  pAISpec->addInventoryParameterSpec(pInventoryParameterSpec);
990 
991 
993  CROReportSpec * pROReportSpec = new CROReportSpec();
995  pROReportSpec->setN(1000);
996 
997  CTagReportContentSelector * pTagRptContentSelector = new CTagReportContentSelector();
998  pTagRptContentSelector->setEnableROSpecID(1);
999  pTagRptContentSelector->setEnableSpecIndex(1);
1000  pTagRptContentSelector->setEnableInventoryParameterSpecID(1);
1001  pTagRptContentSelector->setEnableAntennaID(1);
1002  pTagRptContentSelector->setEnableChannelIndex(1);
1003  pTagRptContentSelector->setEnablePeakRSSI(1);
1004  pTagRptContentSelector->setEnableFirstSeenTimestamp(1);
1005  pTagRptContentSelector->setEnableLastSeenTimestamp(1);
1006  pTagRptContentSelector->setEnableTagSeenCount(1);
1007  pTagRptContentSelector->setEnableAccessSpecID(1);
1008 
1009  pROReportSpec->setTagReportContentSelector(pTagRptContentSelector);
1011 
1012 
1013  CROSpec * pROSpec = new CROSpec();
1014  pROSpec->setROSpecID(1);
1015  pROSpec->setPriority(0);
1017  pROSpec->setROBoundarySpec(pROBoundarySpec);
1018  pROSpec->addSpecParameter(pAISpec);
1019  pROSpec->setROReportSpec(pROReportSpec);
1020 
1021  CADD_ROSPEC * pCmd;
1022  CMessage * pRspMsg;
1023  CADD_ROSPEC_RESPONSE * pRsp;
1024 
1025  /*
1026  * Compose the command message.
1027  * N.B.: After the message is composed, all the parameters
1028  * constructed, immediately above, are considered "owned"
1029  * by the command message. When it is destructed so
1030  * too will the parameters be.
1031  */
1032  pCmd = new CADD_ROSPEC();
1033  pCmd->setMessageID(m_messageID++);
1034  pCmd->setROSpec(pROSpec);
1035 
1036  /*
1037  * Send the message, expect the response of certain type
1038  */
1039  pRspMsg = transact(pCmd);
1040 
1041  /*
1042  * Done with the command message.
1043  * N.B.: And the parameters
1044  */
1045  delete pCmd;
1046 
1047  /*
1048  * transact() returns NULL if something went wrong.
1049  */
1050  if(NULL == pRspMsg)
1051  {
1052  /* transact already tattled */
1053  return -1;
1054  }
1055 
1056  /*
1057  * Cast to a ADD_ROSPEC_RESPONSE message.
1058  */
1059  pRsp = (CADD_ROSPEC_RESPONSE *) pRspMsg;
1060 
1061  /*
1062  * Check the LLRPStatus parameter.
1063  */
1064  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "addROSpec"))
1065  {
1066  /* checkLLRPStatus already tattled */
1067  delete pRspMsg;
1068  return -1;
1069  }
1070 
1071  /*
1072  * Done with the response message.
1073  */
1074  delete pRspMsg;
1075 
1076  /*
1077  * Tattle progress, maybe
1078  */
1079  if(m_Verbose)
1080  {
1081  printf("INFO: ROSpec added\n");
1082  }
1083 
1084  /*
1085  * Victory.
1086  */
1087  return 0;
1088 }
1089 
1090 
1108 int
1109 CMyApplication::enableROSpec (void)
1110 {
1111  CENABLE_ROSPEC * pCmd;
1112  CMessage * pRspMsg;
1113  CENABLE_ROSPEC_RESPONSE * pRsp;
1114 
1115  /*
1116  * Compose the command message
1117  */
1118  pCmd = new CENABLE_ROSPEC();
1119  pCmd->setMessageID(m_messageID++);
1120  pCmd->setROSpecID(1);
1121 
1122  /*
1123  * Send the message, expect the response of certain type
1124  */
1125  pRspMsg = transact(pCmd);
1126 
1127  /*
1128  * Done with the command message
1129  */
1130  delete pCmd;
1131 
1132  /*
1133  * transact() returns NULL if something went wrong.
1134  */
1135  if(NULL == pRspMsg)
1136  {
1137  /* transact already tattled */
1138  return -1;
1139  }
1140 
1141  /*
1142  * Cast to a ENABLE_ROSPEC_RESPONSE message.
1143  */
1144  pRsp = (CENABLE_ROSPEC_RESPONSE *) pRspMsg;
1145 
1146  /*
1147  * Check the LLRPStatus parameter.
1148  */
1149  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "enableROSpec"))
1150  {
1151  /* checkLLRPStatus already tattled */
1152  delete pRspMsg;
1153  return -1;
1154  }
1155 
1156  /*
1157  * Done with the response message.
1158  */
1159  delete pRspMsg;
1160 
1161  /*
1162  * Tattle progress, maybe
1163  */
1164  if(m_Verbose)
1165  {
1166  printf("INFO: ROSpec enabled\n");
1167  }
1168 
1169  /*
1170  * Victory.
1171  */
1172  return 0;
1173 }
1174 
1175 
1193 int
1194 CMyApplication::startROSpec (void)
1195 {
1196  CSTART_ROSPEC * pCmd;
1197  CMessage * pRspMsg;
1198  CSTART_ROSPEC_RESPONSE * pRsp;
1199 
1200  /*
1201  * Compose the command message
1202  */
1203  pCmd = new CSTART_ROSPEC();
1204  pCmd->setMessageID(m_messageID++);
1205  pCmd->setROSpecID(1);
1206 
1207  /*
1208  * Send the message, expect the response of certain type
1209  */
1210  pRspMsg = transact(pCmd);
1211 
1212  /*
1213  * Done with the command message
1214  */
1215  delete pCmd;
1216 
1217  /*
1218  * transact() returns NULL if something went wrong.
1219  */
1220  if(NULL == pRspMsg)
1221  {
1222  /* transact already tattled */
1223  return -1;
1224  }
1225 
1226  /*
1227  * Cast to a START_ROSPEC_RESPONSE message.
1228  */
1229  pRsp = (CSTART_ROSPEC_RESPONSE *) pRspMsg;
1230 
1231  /*
1232  * Check the LLRPStatus parameter.
1233  */
1234  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "startROSpec"))
1235  {
1236  /* checkLLRPStatus already tattled */
1237  delete pRspMsg;
1238  return -1;
1239  }
1240 
1241  /*
1242  * Done with the response message.
1243  */
1244  delete pRspMsg;
1245 
1246  /*
1247  * Tattle progress
1248  */
1249  if(m_Verbose)
1250  {
1251  printf("INFO: ROSpec started\n");
1252  }
1253 
1254  /*
1255  * Victory.
1256  */
1257  return 0;
1258 }
1259 
1277 int
1278 CMyApplication::stopROSpec (void)
1279 {
1280  CSTOP_ROSPEC * pCmd;
1281  CMessage * pRspMsg;
1282  CSTOP_ROSPEC_RESPONSE * pRsp;
1283 
1284  /*
1285  * Compose the command message
1286  */
1287  pCmd = new CSTOP_ROSPEC();
1288  pCmd->setMessageID(m_messageID++);
1289  pCmd->setROSpecID(1);
1290 
1291  /*
1292  * Send the message, expect the response of certain type
1293  */
1294  pRspMsg = transact(pCmd);
1295 
1296  /*
1297  * Done with the command message
1298  */
1299  delete pCmd;
1300 
1301  /*
1302  * transact() returns NULL if something went wrong.
1303  */
1304  if(NULL == pRspMsg)
1305  {
1306  /* transact already tattled */
1307  return -1;
1308  }
1309 
1310  /*
1311  * Cast to a STOP_ROSPEC_RESPONSE message.
1312  */
1313  pRsp = (CSTOP_ROSPEC_RESPONSE *) pRspMsg;
1314 
1315  /*
1316  * Check the LLRPStatus parameter.
1317  */
1318  if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "stopROSpec"))
1319  {
1320  /* checkLLRPStatus already tattled */
1321  delete pRspMsg;
1322  return -1;
1323  }
1324 
1325  /*
1326  * Done with the response message.
1327  */
1328  delete pRspMsg;
1329 
1330  /*
1331  * Tattle progress
1332  */
1333  if(m_Verbose)
1334  {
1335  printf("INFO: ROSpec stopped\n");
1336  }
1337 
1338  /*
1339  * Victory.
1340  */
1341  return 0;
1342 }
1343 
1344 
1364 int
1365 CMyApplication::awaitAndPrintReport (int timeout)
1366 {
1367  int bDone = 0;
1368  int retVal = 0;
1369  time_t startTime = time(NULL);
1370  time_t tempTime;
1371  /*
1372  * Keep receiving messages until done or until
1373  * something bad happens.
1374  */
1375  while(!bDone)
1376  {
1377  CMessage * pMessage;
1378  const CTypeDescriptor * pType;
1379 
1380  /*
1381  * Wait up to 1 second for a report. Check
1382  * That way, we can check the timestamp even if
1383  * there are no reports coming in
1384  */
1385  pMessage = recvMessage(1000);
1386 
1387  /* validate the timestamp */
1388  tempTime = time(NULL);
1389  if(difftime(tempTime, startTime) > timeout)
1390  {
1391  bDone=1;
1392  }
1393 
1394  if(NULL == pMessage)
1395  {
1396  continue;
1397  }
1398 
1399  /*
1400  * What happens depends on what kind of message
1401  * received. Use the type label (m_pType) to
1402  * discriminate message types.
1403  */
1404  pType = pMessage->m_pType;
1405 
1406  /*
1407  * Is it a tag report? If so, print it out.
1408  */
1409  if(&CRO_ACCESS_REPORT::s_typeDescriptor == pType)
1410  {
1411  CRO_ACCESS_REPORT * pNtf;
1412 
1413  pNtf = (CRO_ACCESS_REPORT *) pMessage;
1414 
1415  printTagReportData(pNtf);
1416  }
1417 
1418  /*
1419  * Is it a reader event? This example only recognizes
1420  * AntennaEvents.
1421  */
1422  else if(&CREADER_EVENT_NOTIFICATION::s_typeDescriptor == pType)
1423  {
1425  CReaderEventNotificationData *pNtfData;
1426 
1427  pNtf = (CREADER_EVENT_NOTIFICATION *) pMessage;
1428 
1429  pNtfData = pNtf->getReaderEventNotificationData();
1430  if(NULL != pNtfData)
1431  {
1432  handleReaderEventNotification(pNtfData);
1433  }
1434  else
1435  {
1436  /*
1437  * This should never happen. Using continue
1438  * to keep indent depth down.
1439  */
1440  printf("WARNING: READER_EVENT_NOTIFICATION without data\n");
1441  }
1442  }
1443 
1444  /*
1445  * Hmmm. Something unexpected. Just tattle and keep going.
1446  */
1447  else
1448  {
1449  printf("WARNING: Ignored unexpected message during monitor: %s\n",
1450  pType->m_pName);
1451  }
1452 
1453  /*
1454  * Done with the received message
1455  */
1456  delete pMessage;
1457  }
1458 
1459  return retVal;
1460 }
1461 
1462 
1477 void
1478 CMyApplication::printTagReportData (
1479  CRO_ACCESS_REPORT * pRO_ACCESS_REPORT)
1480 {
1481  std::list<CTagReportData *>::iterator Cur;
1482 
1483  unsigned int nEntry = 0;
1484 
1485  /*
1486  * Loop through and count the number of entries
1487  */
1488  for(
1489  Cur = pRO_ACCESS_REPORT->beginTagReportData();
1490  Cur != pRO_ACCESS_REPORT->endTagReportData();
1491  Cur++)
1492  {
1493  nEntry++;
1494  }
1495 
1496  if(m_Verbose)
1497  {
1498  printf("INFO: %u tag report entries\n", nEntry);
1499  }
1500 
1501  /*
1502  * Loop through again and print each entry.
1503  */
1504  for(
1505  Cur = pRO_ACCESS_REPORT->beginTagReportData();
1506  Cur != pRO_ACCESS_REPORT->endTagReportData();
1507  Cur++)
1508  {
1509  printOneTagReportData(*Cur);
1510  }
1511 }
1512 
1513 
1522 void
1523 CMyApplication::formatOneEPC (
1524  CParameter *pEPCParameter,
1525  char *buf,
1526  int buflen)
1527 {
1528  char * p = buf;
1529  int bufsize = buflen;
1530  int written = 0;
1531 
1532  if(NULL != pEPCParameter)
1533  {
1534  const CTypeDescriptor * pType;
1535  llrp_u96_t my_u96;
1536  llrp_u1v_t my_u1v;
1537  llrp_u8_t * pValue = NULL;
1538  unsigned int n, i;
1539 
1540  pType = pEPCParameter->m_pType;
1541  if(&CEPC_96::s_typeDescriptor == pType)
1542  {
1543  CEPC_96 *pEPC_96;
1544 
1545  pEPC_96 = (CEPC_96 *) pEPCParameter;
1546  my_u96 = pEPC_96->getEPC();
1547  pValue = my_u96.m_aValue;
1548  n = 12u;
1549  }
1550  else if(&CEPCData::s_typeDescriptor == pType)
1551  {
1552  CEPCData * pEPCData;
1553 
1554  pEPCData = (CEPCData *) pEPCParameter;
1555  my_u1v = pEPCData->getEPC();
1556  pValue = my_u1v.m_pValue;
1557  n = (my_u1v.m_nBit + 7u) / 8u;
1558  }
1559 
1560  if(NULL != pValue)
1561  {
1562  for(i = 0; i < n; i++)
1563  {
1564  if(0 < i && i%2 == 0 && 1 < bufsize)
1565  {
1566  *p++ = '-';
1567  bufsize--;
1568  }
1569  if(bufsize > 2)
1570  {
1571  written = snprintf(p, bufsize, "%02X", pValue[i]);
1572  bufsize -= written;
1573  p+= written;
1574  }
1575  }
1576  }
1577  else
1578  {
1579  written = snprintf(p, bufsize, "%s", "---unknown-epc-data-type---");
1580  bufsize -= written;
1581  p += written;
1582  }
1583  }
1584  else
1585  {
1586  written = snprintf(p, bufsize, "%s", "--null epc---");
1587  bufsize -= written;
1588  p += written;
1589  }
1590 
1591  // null terminate this for good practice
1592  buf[buflen-1] = '\0';
1593 
1594 }
1595 
1604 void
1605 CMyApplication::printOneTagReportData (
1606  CTagReportData * pTagReportData)
1607 {
1608  char aBuf[64];
1609 
1610  /*
1611  * Print the EPC. It could be an 96-bit EPC_96 parameter
1612  * or an variable length EPCData parameter.
1613  */
1614 
1615  CParameter * pEPCParameter =
1616  pTagReportData->getEPCParameter();
1617 
1618  formatOneEPC(pEPCParameter, aBuf, 64);
1619 
1620  /*
1621  * End of line
1622  */
1623  printf("EPC: %s\n", aBuf);
1624 }
1625 
1626 
1640 void
1641 CMyApplication::handleReaderEventNotification (
1642  CReaderEventNotificationData *pNtfData)
1643 {
1644  CAntennaEvent * pAntennaEvent;
1645  CReaderExceptionEvent * pReaderExceptionEvent;
1646  int nReported = 0;
1647 
1648  pAntennaEvent = pNtfData->getAntennaEvent();
1649  if(NULL != pAntennaEvent)
1650  {
1651  handleAntennaEvent(pAntennaEvent);
1652  nReported++;
1653  }
1654 
1655  pReaderExceptionEvent = pNtfData->getReaderExceptionEvent();
1656  if(NULL != pReaderExceptionEvent)
1657  {
1658  handleReaderExceptionEvent(pReaderExceptionEvent);
1659  nReported++;
1660  }
1661 
1662  /*
1663  * Similarly handle other events here:
1664  * HoppingEvent
1665  * GPIEvent
1666  * ROSpecEvent
1667  * ReportBufferLevelWarningEvent
1668  * ReportBufferOverflowErrorEvent
1669  * RFSurveyEvent
1670  * AISpecEvent
1671  * ConnectionAttemptEvent
1672  * ConnectionCloseEvent
1673  * Custom
1674  */
1675 
1676  if(0 == nReported)
1677  {
1678  printf("NOTICE: Unexpected (unhandled) ReaderEvent\n");
1679  }
1680 }
1681 
1682 
1694 void
1695 CMyApplication::handleAntennaEvent (
1696  CAntennaEvent * pAntennaEvent)
1697 {
1698  EAntennaEventType eEventType;
1699  llrp_u16_t AntennaID;
1700  char * pStateStr;
1701 
1702  eEventType = pAntennaEvent->getEventType();
1703  AntennaID = pAntennaEvent->getAntennaID();
1704 
1705  switch(eEventType)
1706  {
1708  pStateStr = "disconnected";
1709  break;
1710 
1712  pStateStr = "connected";
1713  break;
1714 
1715  default:
1716  pStateStr = "?unknown-event?";
1717  break;
1718  }
1719 
1720  printf("NOTICE: Antenna %d is %s\n", AntennaID, pStateStr);
1721 }
1722 
1723 
1736 void
1737 CMyApplication::handleReaderExceptionEvent (
1738  CReaderExceptionEvent * pReaderExceptionEvent)
1739 {
1740  llrp_utf8v_t Message;
1741 
1742  Message = pReaderExceptionEvent->getMessage();
1743 
1744  if(0 < Message.m_nValue && NULL != Message.m_pValue)
1745  {
1746  printf("NOTICE: ReaderException '%.*s'\n",
1747  Message.m_nValue, Message.m_pValue);
1748  }
1749  else
1750  {
1751  printf("NOTICE: ReaderException but no message\n");
1752  }
1753 }
1754 
1755 
1774 int
1775 CMyApplication::checkLLRPStatus (
1776  CLLRPStatus * pLLRPStatus,
1777  char * pWhatStr)
1778 {
1779  /*
1780  * The LLRPStatus parameter is mandatory in all responses.
1781  * If it is missing there should have been a decode error.
1782  * This just makes sure (remember, this program is a
1783  * diagnostic and suppose to catch LTKC mistakes).
1784  */
1785  if(NULL == pLLRPStatus)
1786  {
1787  printf("ERROR: %s missing LLRP status\n", pWhatStr);
1788  return -1;
1789  }
1790 
1791  /*
1792  * Make sure the status is M_Success.
1793  * If it isn't, print the error string if one.
1794  * This does not try to pretty-print the status
1795  * code. To get that, run this program with -vv
1796  * and examine the XML output.
1797  */
1798  if(StatusCode_M_Success != pLLRPStatus->getStatusCode())
1799  {
1800  llrp_utf8v_t ErrorDesc;
1801 
1802  ErrorDesc = pLLRPStatus->getErrorDescription();
1803 
1804  if(0 == ErrorDesc.m_nValue)
1805  {
1806  printf("ERROR: %s failed, no error description given\n",
1807  pWhatStr);
1808  }
1809  else
1810  {
1811  printf("ERROR: %s failed, %.*s\n",
1812  pWhatStr, ErrorDesc.m_nValue, ErrorDesc.m_pValue);
1813  }
1814  return -2;
1815  }
1816 
1817  /*
1818  * Victory. Everything is fine.
1819  */
1820  return 0;
1821 }
1822 
1823 
1847 CMessage *
1848 CMyApplication::transact (
1849  CMessage * pSendMsg)
1850 {
1851  CConnection * pConn = m_pConnectionToReader;
1852  CMessage * pRspMsg;
1853 
1854  /*
1855  * Print the XML text for the outbound message if
1856  * verbosity is 2 or higher.
1857  */
1858  if(1 < m_Verbose)
1859  {
1860  printf("\n===================================\n");
1861  printf("INFO: Transact sending\n");
1862  printXMLMessage(pSendMsg);
1863  }
1864 
1865  /*
1866  * Send the message, expect the response of certain type.
1867  * If LLRP::CConnection::transact() returns NULL then there was
1868  * an error. In that case we try to print the error details.
1869  */
1870  pRspMsg = pConn->transact(pSendMsg, 5000);
1871 
1872  if(NULL == pRspMsg)
1873  {
1874  const CErrorDetails * pError = pConn->getTransactError();
1875 
1876  printf("ERROR: %s transact failed, %s\n",
1877  pSendMsg->m_pType->m_pName,
1878  pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
1879 
1880  if(NULL != pError->m_pRefType)
1881  {
1882  printf("ERROR: ... reference type %s\n",
1883  pError->m_pRefType->m_pName);
1884  }
1885 
1886  if(NULL != pError->m_pRefField)
1887  {
1888  printf("ERROR: ... reference field %s\n",
1889  pError->m_pRefField->m_pName);
1890  }
1891 
1892  return NULL;
1893  }
1894 
1895  /*
1896  * Print the XML text for the inbound message if
1897  * verbosity is 2 or higher.
1898  */
1899  if(1 < m_Verbose)
1900  {
1901  printf("\n- - - - - - - - - - - - - - - - - -\n");
1902  printf("INFO: Transact received response\n");
1903  printXMLMessage(pRspMsg);
1904  }
1905 
1906  /*
1907  * If it is an ERROR_MESSAGE (response from reader
1908  * when it can't understand the request), tattle
1909  * and declare defeat.
1910  */
1911  if(&CERROR_MESSAGE::s_typeDescriptor == pRspMsg->m_pType)
1912  {
1913  const CTypeDescriptor * pResponseType;
1914 
1915  pResponseType = pSendMsg->m_pType->m_pResponseType;
1916 
1917  printf("ERROR: Received ERROR_MESSAGE instead of %s\n",
1918  pResponseType->m_pName);
1919  delete pRspMsg;
1920  pRspMsg = NULL;
1921  }
1922 
1923  return pRspMsg;
1924 }
1925 
1926 
1951 CMessage *
1952 CMyApplication::recvMessage (
1953  int nMaxMS)
1954 {
1955  CConnection * pConn = m_pConnectionToReader;
1956  CMessage * pMessage;
1957 
1958  /*
1959  * Receive the message subject to a time limit
1960  */
1961  pMessage = pConn->recvMessage(nMaxMS);
1962 
1963  /*
1964  * If LLRP::CConnection::recvMessage() returns NULL then there was
1965  * an error. In that case we try to print the error details.
1966  */
1967  if(NULL == pMessage)
1968  {
1969  const CErrorDetails * pError = pConn->getRecvError();
1970 
1971  /* don't warn on timeout since this is a polling example */
1972  if(pError->m_eResultCode != RC_RecvTimeout)
1973  {
1974  printf("ERROR: recvMessage failed, %s\n",
1975  pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
1976  }
1977 
1978  if(NULL != pError->m_pRefType)
1979  {
1980  printf("ERROR: ... reference type %s\n",
1981  pError->m_pRefType->m_pName);
1982  }
1983 
1984  if(NULL != pError->m_pRefField)
1985  {
1986  printf("ERROR: ... reference field %s\n",
1987  pError->m_pRefField->m_pName);
1988  }
1989 
1990  return NULL;
1991  }
1992 
1993  /*
1994  * Print the XML text for the inbound message if
1995  * verbosity is 2 or higher.
1996  */
1997  if(1 < m_Verbose)
1998  {
1999  printf("\n===================================\n");
2000  printf("INFO: Message received\n");
2001  printXMLMessage(pMessage);
2002  }
2003 
2004  return pMessage;
2005 }
2006 
2007 
2025 int
2026 CMyApplication::sendMessage (
2027  CMessage * pSendMsg)
2028 {
2029  CConnection * pConn = m_pConnectionToReader;
2030 
2031  /*
2032  * Print the XML text for the outbound message if
2033  * verbosity is 2 or higher.
2034  */
2035  if(1 < m_Verbose)
2036  {
2037  printf("\n===================================\n");
2038  printf("INFO: Sending\n");
2039  printXMLMessage(pSendMsg);
2040  }
2041 
2042  /*
2043  * If LLRP::CConnection::sendMessage() returns other than RC_OK
2044  * then there was an error. In that case we try to print
2045  * the error details.
2046  */
2047  if(RC_OK != pConn->sendMessage(pSendMsg))
2048  {
2049  const CErrorDetails * pError = pConn->getSendError();
2050 
2051  printf("ERROR: %s sendMessage failed, %s\n",
2052  pSendMsg->m_pType->m_pName,
2053  pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
2054 
2055  if(NULL != pError->m_pRefType)
2056  {
2057  printf("ERROR: ... reference type %s\n",
2058  pError->m_pRefType->m_pName);
2059  }
2060 
2061  if(NULL != pError->m_pRefField)
2062  {
2063  printf("ERROR: ... reference field %s\n",
2064  pError->m_pRefField->m_pName);
2065  }
2066 
2067  return -1;
2068  }
2069 
2070  /*
2071  * Victory
2072  */
2073  return 0;
2074 }
2075 
2076 
2090 void
2091 CMyApplication::printXMLMessage (
2092  CMessage * pMessage)
2093 {
2094  char aBuf[100*1024];
2095 
2096  /*
2097  * Convert the message to an XML string.
2098  * This fills the buffer with either the XML string
2099  * or an error message. The return value could
2100  * be checked.
2101  */
2102 
2103  pMessage->toXMLString(aBuf, sizeof aBuf);
2104 
2105  /*
2106  * Print the XML Text to the standard output.
2107  */
2108  printf("%s", aBuf);
2109 }
void setChannelIndex(llrp_u16_t value)
Set accessor functions for the LLRP ChannelIndex field.
Definition: ltkcpp.h:13259
Class Definition CROBoundarySpec for LLRP parameter ROBoundarySpec.
Definition: ltkcpp.h:9540
Class Definition CTagObservationTrigger for LLRP parameter TagObservationTrigger. ...
Definition: ltkcpp.h:10602
void enrollImpinjTypesIntoRegistry(CTypeRegistry *pTypeRegistry)
Enrolls the types for Impinj into the LTKCPP registry.
void setDurationTrigger(llrp_u32_t value)
Set accessor functions for the LLRP DurationTrigger field.
Definition: ltkcpp.h:10523
void setAction(EC1G2StateAwareAction value)
Set accessor functions for the LLRP Action field.
Definition: ltkcpp.h:20616
char * m_pName
String name of field (e.g. "ROSpecID")
Definition: ltkcpp_base.h:840
void setAntennaIDs(llrp_u16v_t value)
Set accessor functions for the LLRP AntennaIDs field.
Definition: ltkcpp.h:10303
const CTypeDescriptor * m_pType
The type descriptor desribing this element.
Definition: ltkcpp_base.h:972
void setROSpecID(llrp_u32_t value)
Set accessor functions for the LLRP ROSpecID field.
Definition: ltkcpp.h:2922
Class Definition CAntennaConfiguration for LLRP parameter AntennaConfiguration.
Definition: ltkcpp.h:12905
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Definition: ltkcpp.h:2437
llrp_u8_t * m_pValue
Pointer to the first array element.
Definition: ltkcpp_base.h:443
Class for LLRP basic type u16v (List of unsigned 16-bit values)
Definition: ltkcpp_base.h:179
EResultCode setTagReportContentSelector(CTagReportContentSelector *pValue)
Set accessor functions for the LLRP TagReportContentSelector sub-parameter.
EResultCode addC1G2Filter(CC1G2Filter *pValue)
Add a C1G2Filter to the LLRP sub-parameter list.
std::list< CTagReportData * >::iterator beginTagReportData(void)
Returns the first element of the TagReportData sub-parameter list.
Definition: ltkcpp.h:6187
const CFieldDescriptor * m_pRefField
If non-NULL this is the field descriptors for the errored field.
Definition: ltkcpp_base.h:641
void setEnableFirstSeenTimestamp(llrp_u1_t value)
Set accessor functions for the LLRP EnableFirstSeenTimestamp field.
Definition: ltkcpp.h:14003
Class Definition CAISpec for LLRP parameter AISpec.
Definition: ltkcpp.h:10245
void setEnablePeakRSSI(llrp_u1_t value)
Set accessor functions for the LLRP EnablePeakRSSI field.
Definition: ltkcpp.h:13977
Class Definition CC1G2Filter for LLRP parameter C1G2Filter.
Definition: ltkcpp.h:20217
void setPriority(llrp_u8_t value)
Set accessor functions for the LLRP Priority field.
Definition: ltkcpp.h:9401
void usage(char *pProgName)
Print usage message and exit.
Definition: example1.cpp:247
const CTypeDescriptor * m_pRefType
If non-NULL this is the type descriptors for the errored type.
Definition: ltkcpp_base.h:639
Class Definition CInventoryParameterSpec for LLRP parameter InventoryParameterSpec.
Definition: ltkcpp.h:10807
EResultCode m_eResultCode
Result code from operation.
Definition: ltkcpp_base.h:635
Class for LLRP basic type u96 (96-bit value)
Definition: ltkcpp_base.h:566
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Definition: ltkcpp.h:5847
void setEnableAccessSpecID(llrp_u1_t value)
Set accessor functions for the LLRP EnableAccessSpecID field.
Definition: ltkcpp.h:14081
Class Definition CSTOP_ROSPEC for LLRP message STOP_ROSPEC.
Definition: ltkcpp.h:2864
llrp_u96_t getEPC(void)
Get accessor functions for the LLRP EPC field.
Definition: ltkcpp.h:14952
Class Definition CSTART_ROSPEC for LLRP message START_ROSPEC.
Definition: ltkcpp.h:2674
void setCurrentState(EROSpecState value)
Set accessor functions for the LLRP CurrentState field.
Definition: ltkcpp.h:9427
EStatusCode getStatusCode(void)
Get accessor functions for the LLRP StatusCode field.
Definition: ltkcpp.h:18940
const char * m_pWhatStr
Descriptive printable error string.
Definition: ltkcpp_base.h:637
EResultCode toXMLString(char *pBuffer, int nBuffer)
A wrapper around LLRP::toXMLString()
CReaderEventNotificationData * getReaderEventNotificationData(void)
Get accessor functions for the LLRP ReaderEventNotificationData sub-parameter.
Definition: ltkcpp.h:6517
Class Definition CROSpecStartTrigger for LLRP parameter ROSpecStartTrigger.
Definition: ltkcpp.h:9648
void setTransmitPower(llrp_u16_t value)
Set accessor functions for the LLRP TransmitPower field.
Definition: ltkcpp.h:13285
Class Definition CEPC_96 for LLRP parameter EPC_96.
Definition: ltkcpp.h:14901
void setEnableChannelIndex(llrp_u1_t value)
Set accessor functions for the LLRP EnableChannelIndex field.
Definition: ltkcpp.h:13951
Class Definition CENABLE_ROSPEC_RESPONSE for LLRP message ENABLE_ROSPEC_RESPONSE. ...
Definition: ltkcpp.h:3152
Class Definition CROReportSpec for LLRP parameter ROReportSpec.
Definition: ltkcpp.h:13599
Class Definition CRO_ACCESS_REPORT for LLRP message RO_ACCESS_REPORT.
Definition: ltkcpp.h:6142
llrp_u16_t m_nValue
The number of arrray elements.
Definition: ltkcpp_base.h:484
int closeConnectionToReader(void)
Close connection to reader, allow reuse of instance.
EConnectionAttemptStatusType getStatus(void)
Get accessor functions for the LLRP Status field.
Definition: ltkcpp.h:18764
void setTimeout(llrp_u32_t value)
Set accessor functions for the LLRP Timeout field.
Definition: ltkcpp.h:10764
void setEnableROSpecID(llrp_u1_t value)
Set accessor functions for the LLRP EnableROSpecID field.
Definition: ltkcpp.h:13847
A collection of pointers to CTypeDescriptors.
Definition: ltkcpp_base.h:885
Class Definition CREADER_EVENT_NOTIFICATION for LLRP message READER_EVENT_NOTIFICATION.
Definition: ltkcpp.h:6472
llrp_u16_t getAntennaID(void)
Get accessor functions for the LLRP AntennaID field.
Definition: ltkcpp.h:18666
const CErrorDetails * getTransactError(void)
Get the details that explains transact() error.
void setAntennaID(llrp_u16_t value)
Set accessor functions for the LLRP AntennaID field.
Definition: ltkcpp.h:12963
void setTagMask(llrp_u1v_t value)
Set accessor functions for the LLRP TagMask field.
Definition: ltkcpp.h:20472
void setTarget(EC1G2StateAwareTarget value)
Set accessor functions for the LLRP Target field.
Definition: ltkcpp.h:20590
Class Definition CConnectionAttemptEvent for LLRP parameter ConnectionAttemptEvent.
Definition: ltkcpp.h:18713
Class Definition CSTART_ROSPEC_RESPONSE for LLRP message START_ROSPEC_RESPONSE.
Definition: ltkcpp.h:2772
Class Definition CReaderEventNotificationData for LLRP parameter ReaderEventNotificationData.
Definition: ltkcpp.h:17017
void setROSpecID(llrp_u32_t value)
Set accessor functions for the LLRP ROSpecID field.
Definition: ltkcpp.h:2732
Class Definition CADD_ROSPEC for LLRP message ADD_ROSPEC.
Definition: ltkcpp.h:2303
void setResetToFactoryDefault(llrp_u1_t value)
Set accessor functions for the LLRP ResetToFactoryDefault field.
Definition: ltkcpp.h:5487
CMessage * recvMessage(int nMaxMS)
Receive a message from a connection.
Class Definition CTagReportContentSelector for LLRP parameter TagReportContentSelector.
Definition: ltkcpp.h:13789
Class Definition CADD_ROSPEC_RESPONSE for LLRP message ADD_ROSPEC_RESPONSE.
Definition: ltkcpp.h:2392
File that includes all Impinj Custom extension classes and types.
void setNumberOfAttempts(llrp_u16_t value)
Set accessor functions for the LLRP NumberOfAttempts field.
Definition: ltkcpp.h:10712
void setROReportTrigger(EROReportTriggerType value)
Set accessor functions for the LLRP ROReportTrigger field.
Definition: ltkcpp.h:13657
void setDurationTriggerValue(llrp_u32_t value)
Set accessor functions for the LLRP DurationTriggerValue field.
Definition: ltkcpp.h:10185
llrp_utf8v_t getErrorDescription(void)
Get accessor functions for the LLRP ErrorDescription field.
Definition: ltkcpp.h:18966
EResultCode setROSpec(CROSpec *pValue)
Set accessor functions for the LLRP ROSpec sub-parameter.
CMessage * transact(CMessage *pSendMessage, int nMaxMS)
Transact a LLRP request and response to a connection.
EResultCode addAntennaConfiguration(CAntennaConfiguration *pValue)
Add a AntennaConfiguration to the LLRP sub-parameter list.
Class Definition CAntennaEvent for LLRP parameter AntennaEvent.
Definition: ltkcpp.h:18589
const CErrorDetails * getRecvError(void)
Get the details that explains recvMessage() or recvResponse() error.
Class for LLRP basic type utf8v (vector of utf-8 encoded characters)
Definition: ltkcpp_base.h:480
llrp_u16_t m_nBit
The number of arrray elements.
Definition: ltkcpp_base.h:441
EResultCode setC1G2SingulationControl(CC1G2SingulationControl *pValue)
Set accessor functions for the LLRP C1G2SingulationControl sub-parameter.
Class for LLRP basic type u1v (vector of unsigned 1-bit values)
Definition: ltkcpp_base.h:437
Class Definition CENABLE_ROSPEC for LLRP message ENABLE_ROSPEC.
Definition: ltkcpp.h:3054
int openConnectionToReader(const char *pReaderHostName)
Open a connection to the reader over an unencrypted socket.
void setProtocolID(EAirProtocols value)
Set accessor functions for the LLRP ProtocolID field.
Definition: ltkcpp.h:10891
void setHopTableID(llrp_u16_t value)
Set accessor functions for the LLRP HopTableID field.
Definition: ltkcpp.h:13233
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Definition: ltkcpp.h:3007
EResultCode addSpecParameter(CParameter *pValue)
Add a SpecParameter to the LLRP sub-parameter list.
Class Definition CLLRPStatus for LLRP parameter LLRPStatus.
Definition: ltkcpp.h:18889
void setEnableSpecIndex(llrp_u1_t value)
Set accessor functions for the LLRP EnableSpecIndex field.
Definition: ltkcpp.h:13873
const CTypeDescriptor * m_pResponseType
For messages (bIsMessage==TRUE), this is the type descriptor for the corresponding response...
Definition: ltkcpp_base.h:776
EResultCode addAirProtocolInventoryCommandSettings(CParameter *pValue)
Add a AirProtocolInventoryCommandSettings to the LLRP sub-parameter list.
Class Definition CC1G2SingulationControl for LLRP parameter C1G2SingulationControl.
Definition: ltkcpp.h:20948
EResultCode setTagObservationTrigger(CTagObservationTrigger *pValue)
Set accessor functions for the LLRP TagObservationTrigger sub-parameter.
Class Definition CSTOP_ROSPEC_RESPONSE for LLRP message STOP_ROSPEC_RESPONSE.
Definition: ltkcpp.h:2962
void setROSpecID(llrp_u32_t value)
Set accessor functions for the LLRP ROSpecID field.
Definition: ltkcpp.h:3112
CReaderExceptionEvent * getReaderExceptionEvent(void)
Get accessor functions for the LLRP ReaderExceptionEvent sub-parameter.
Definition: ltkcpp.h:17164
void setN(llrp_u16_t value)
Set accessor functions for the LLRP N field.
Definition: ltkcpp.h:13683
EResultCode sendMessage(CMessage *pMessage)
Send a LLRP message to a connection.
CParameter * getEPCParameter(void)
Get accessor functions for the LLRP EPCParameter sub-parameter.
Definition: ltkcpp.h:14441
Class to return error details in LTKCPP operations.
Definition: ltkcpp_base.h:631
Class Definition CC1G2TagInventoryMask for LLRP parameter C1G2TagInventoryMask.
Definition: ltkcpp.h:20362
Class Definition CROSpec for LLRP parameter ROSpec.
Definition: ltkcpp.h:9317
void setMB(llrp_u2_t value)
Set accessor functions for the LLRP MB field.
Definition: ltkcpp.h:20420
EResultCode setROBoundarySpec(CROBoundarySpec *pValue)
Set accessor functions for the LLRP ROBoundarySpec sub-parameter.
char * m_pName
String name of parameter/message type (e.g. "ROSpec")
Definition: ltkcpp_base.h:762
Class Definition CC1G2InventoryCommand for LLRP parameter C1G2InventoryCommand.
Definition: ltkcpp.h:19981
File that includes all LLRP classes and types.
Class Definition CEPCData for LLRP parameter EPCData.
Definition: ltkcpp.h:14803
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Definition: ltkcpp.h:3197
Class Definition CSET_READER_CONFIG for LLRP message SET_READER_CONFIG.
Definition: ltkcpp.h:5429
void setEnableAntennaID(llrp_u1_t value)
Set accessor functions for the LLRP EnableAntennaID field.
Definition: ltkcpp.h:13925
void setTagInventoryStateAware(llrp_u1_t value)
Set accessor functions for the LLRP TagInventoryStateAware field.
Definition: ltkcpp.h:20039
void setT(llrp_u16_t value)
Set accessor functions for the LLRP T field.
Definition: ltkcpp.h:10738
void setSession(llrp_u2_t value)
Set accessor functions for the LLRP Session field.
Definition: ltkcpp.h:21006
void setROSpecStopTriggerType(EROSpecStopTriggerType value)
Set accessor functions for the LLRP ROSpecStopTriggerType field.
Definition: ltkcpp.h:10159
llrp_u1v_t getEPC(void)
Get accessor functions for the LLRP EPC field.
Definition: ltkcpp.h:14854
llrp_u16_t * m_pValue
Pointer to the first array element.
Definition: ltkcpp_base.h:185
EResultCode setRFTransmitter(CRFTransmitter *pValue)
Set accessor functions for the LLRP RFTransmitter sub-parameter.
EResultCode setROSpecStopTrigger(CROSpecStopTrigger *pValue)
Set accessor functions for the LLRP ROSpecStopTrigger sub-parameter.
llrp_u8_t m_aValue[12]
Simple array of basic type llrp_u8_t.
Definition: ltkcpp_base.h:570
void setInventoryParameterSpecID(llrp_u16_t value)
Set accessor functions for the LLRP InventoryParameterSpecID field.
Definition: ltkcpp.h:10865
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Definition: ltkcpp.h:2817
Base Class for All LLRP LTK Parameters.
Definition: ltkcpp_base.h:1125
Base Class for All LLRP LTK Messages.
Definition: ltkcpp_base.h:1088
EResultCode setC1G2TagInventoryMask(CC1G2TagInventoryMask *pValue)
Set accessor functions for the LLRP C1G2TagInventoryMask sub-parameter.
EResultCode setROSpecStartTrigger(CROSpecStartTrigger *pValue)
Set accessor functions for the LLRP ROSpecStartTrigger sub-parameter.
Class Definition CIMPINJ_ENABLE_EXTENSIONS_RESPONSE for LLRP message IMPINJ_ENABLE_EXTENSIONS_RESPONS...
std::list< CTagReportData * >::iterator endTagReportData(void)
Returns the last element of the TagReportData sub-parameter list.
Definition: ltkcpp.h:6194
llrp_utf8v_t getMessage(void)
Get accessor functions for the LLRP Message field.
Definition: ltkcpp.h:17979
const char * getConnectError(void)
Get the string that explains openReaderConnection() error.
void setTagTransitTime(llrp_u32_t value)
Set accessor functions for the LLRP TagTransitTime field.
Definition: ltkcpp.h:21058
Class Definition CSET_READER_CONFIG_RESPONSE for LLRP message SET_READER_CONFIG_RESPONSE.
Definition: ltkcpp.h:5802
Class Definition CIMPINJ_ENABLE_EXTENSIONS for LLRP message IMPINJ_ENABLE_EXTENSIONS.
Class Definition CReaderExceptionEvent for LLRP parameter ReaderExceptionEvent.
Definition: ltkcpp.h:17928
CAntennaEvent * getAntennaEvent(void)
Get accessor functions for the LLRP AntennaEvent sub-parameter.
Definition: ltkcpp.h:17215
void setEnableLastSeenTimestamp(llrp_u1_t value)
Set accessor functions for the LLRP EnableLastSeenTimestamp field.
Definition: ltkcpp.h:14029
void setEnableTagSeenCount(llrp_u1_t value)
Set accessor functions for the LLRP EnableTagSeenCount field.
Definition: ltkcpp.h:14055
void setROSpecID(llrp_u32_t value)
Set accessor functions for the LLRP ROSpecID field.
Definition: ltkcpp.h:9375
Class Definition CTagReportData for LLRP parameter TagReportData.
Definition: ltkcpp.h:14396
void setMessageID(llrp_u32_t MessageID)
Sets the LLRP Message ID for the Message.
Definition: ltkcpp_base.h:1097
void setAISpecStopTriggerType(EAISpecStopTriggerType value)
Set accessor functions for the LLRP AISpecStopTriggerType field.
Definition: ltkcpp.h:10497
void setS(EC1G2TagInventoryStateAwareS value)
Set accessor functions for the LLRP S field.
Definition: ltkcpp.h:21201
Class Definition CAISpecStopTrigger for LLRP parameter AISpecStopTrigger.
Definition: ltkcpp.h:10439
CLLRPStatus * getLLRPStatus(void)
Get accessor functions for the LLRP LLRPStatus sub-parameter.
Class Definition CC1G2TagInventoryStateAwareSingulationAction for LLRP parameter C1G2TagInventoryStat...
Definition: ltkcpp.h:21117
void setI(EC1G2TagInventoryStateAwareI value)
Set accessor functions for the LLRP I field.
Definition: ltkcpp.h:21175
void setPointer(llrp_u16_t value)
Set accessor functions for the LLRP Pointer field.
Definition: ltkcpp.h:20446
EResultCode addInventoryParameterSpec(CInventoryParameterSpec *pValue)
Add a InventoryParameterSpec to the LLRP sub-parameter list.
void setTagPopulation(llrp_u16_t value)
Set accessor functions for the LLRP TagPopulation field.
Definition: ltkcpp.h:21032
LLRP connection class.
int main(int ac, char *av[])
Command main routine.
Definition: example1.cpp:165
Class Definition CRFTransmitter for LLRP parameter RFTransmitter.
Definition: ltkcpp.h:13175
EAntennaEventType
Global enumeration EAntennaEventType for LLRP enumerated field AntennaEventType.
Definition: ltkcpp.h:1041
EResultCode setROReportSpec(CROReportSpec *pValue)
Set accessor functions for the LLRP ROReportSpec sub-parameter.
void setEnableInventoryParameterSpecID(llrp_u1_t value)
Set accessor functions for the LLRP EnableInventoryParameterSpecID field.
Definition: ltkcpp.h:13899
CConnectionAttemptEvent * getConnectionAttemptEvent(void)
Get accessor functions for the LLRP ConnectionAttemptEvent sub-parameter.
Definition: ltkcpp.h:17232
llrp_utf8_t * m_pValue
Pointer to the first array element.
Definition: ltkcpp_base.h:486
void setTriggerType(ETagObservationTriggerType value)
Set accessor functions for the LLRP TriggerType field.
Definition: ltkcpp.h:10660
void setNumberOfTags(llrp_u16_t value)
Set accessor functions for the LLRP NumberOfTags field.
Definition: ltkcpp.h:10686
void setT(EC1G2TruncateAction value)
Set accessor functions for the LLRP T field.
Definition: ltkcpp.h:20275
Class Definition CC1G2TagInventoryStateAwareFilterAction for LLRP parameter C1G2TagInventoryStateAwar...
Definition: ltkcpp.h:20532
EAntennaEventType getEventType(void)
Get accessor functions for the LLRP EventType field.
Definition: ltkcpp.h:18640
EResultCode setAISpecStopTrigger(CAISpecStopTrigger *pValue)
Set accessor functions for the LLRP AISpecStopTrigger sub-parameter.
Describes a message or parameter type.
Definition: ltkcpp_base.h:755
void setROSpecStartTriggerType(EROSpecStartTriggerType value)
Set accessor functions for the LLRP ROSpecStartTriggerType field.
Definition: ltkcpp.h:9706
Class Definition CROSpecStopTrigger for LLRP parameter ROSpecStopTrigger.
Definition: ltkcpp.h:10101
const CErrorDetails * getSendError(void)
Get the details that explains sendMessage() error.
EResultCode setC1G2TagInventoryStateAwareFilterAction(CC1G2TagInventoryStateAwareFilterAction *pValue)
Set accessor functions for the LLRP C1G2TagInventoryStateAwareFilterAction sub-parameter.
EResultCode setC1G2TagInventoryStateAwareSingulationAction(CC1G2TagInventoryStateAwareSingulationAction *pValue)
Set accessor functions for the LLRP C1G2TagInventoryStateAwareSingulationAction sub-parameter.