00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00050 #include <stdio.h>
00051 #ifdef linux
00052 #include <unistd.h>
00053 #endif
00054
00055 #include "ltkcpp.h"
00056
00057 using namespace LLRP;
00058
00059
00060 class CMyApplication
00061 {
00062 public:
00064 int m_Verbose;
00065
00068 int m_ModeIndex;
00070 int m_Quiet;
00072 int m_nTagReport;
00073
00075 CConnection * m_pConnectionToReader;
00076
00077 inline
00078 CMyApplication (void)
00079 : m_Verbose(0), m_ModeIndex(-1), m_Quiet(0),
00080 m_nTagReport(0), m_pConnectionToReader(NULL)
00081 {}
00082
00083 int
00084 run (
00085 char * pReaderHostName);
00086
00087 int
00088 checkConnectionStatus (void);
00089
00090 int
00091 scrubConfiguration (void);
00092
00093 int
00094 resetConfigurationToFactoryDefaults (void);
00095
00096 int
00097 deleteAllROSpecs (void);
00098
00099 int
00100 deleteAllAccessSpecs (void);
00101
00102 int
00103 prepareReader(void);
00104
00105 int
00106 getAllCapabilities (void);
00107
00108 int
00109 getAllConfiguration (void);
00110
00111 int
00112 configureNotificationStates (void);
00113
00114 int
00115 addROSpec (void);
00116
00117 int
00118 enableROSpec (void);
00119
00120 int
00121 startAndMonitorOperation (void);
00122
00123 void
00124 printTagReportData (
00125 CRO_ACCESS_REPORT * pRO_ACCESS_REPORT);
00126
00127 void
00128 printOneTagReportData (
00129 CTagReportData * pTagReportData);
00130
00131 int
00132 checkLLRPStatus (
00133 CLLRPStatus * pLLRPStatus,
00134 char * pWhatStr);
00135
00136 CMessage *
00137 transact (
00138 CMessage * pSendMsg);
00139
00140 CMessage *
00141 recvMessage (
00142 int nMaxMS);
00143
00144 int
00145 sendMessage (
00146 CMessage * pSendMsg);
00147
00148 void
00149 printXMLMessage (
00150 CMessage * pMessage);
00151 };
00152
00153
00154
00155 int
00156 main (
00157 int ac,
00158 char * av[]);
00159
00160 void
00161 usage (
00162 char * pProgName);
00163
00164
00165
00187 int
00188 main (
00189 int ac,
00190 char * av[])
00191 {
00192 CMyApplication myApp;
00193 char * pReaderHostName;
00194 int rc;
00195 #ifdef linux
00196 char * pMemHiwatAtStart = (char*)sbrk(0);
00197 #endif
00198
00199
00200
00201
00202
00203 if(ac == 2)
00204 {
00205 pReaderHostName = av[1];
00206 }
00207 else if(ac == 3)
00208 {
00209 char * p = av[1];
00210
00211 while(*p)
00212 {
00213 switch(*p++)
00214 {
00215 case '-':
00216 case '/':
00217 break;
00218
00219 case 'v':
00220 case 'V':
00221 myApp.m_Verbose++;
00222 break;
00223
00224 case 'q':
00225 case 'Q':
00226 myApp.m_Quiet++;
00227 break;
00228
00229 case '0': case '1': case '2': case '3': case '4': case '5':
00230 myApp.m_ModeIndex = p[-1] - '0';
00231 break;
00232
00233 default:
00234 usage(av[0]);
00235
00236 break;
00237 }
00238 }
00239
00240 pReaderHostName = av[2];
00241 }
00242 else
00243 {
00244 usage(av[0]);
00245
00246 }
00247
00248
00249
00250
00251 rc = myApp.run(pReaderHostName);
00252
00253 printf("INFO: Done\n");
00254
00255 #ifdef linux
00256 {
00257 char * pMemHiwatAtEnd = (char*)sbrk(0);
00258
00259 printf("INFO: Needed %d bytes of heap\n",
00260 pMemHiwatAtEnd - pMemHiwatAtStart);
00261 }
00262 #endif
00263
00264
00265
00266
00267 if(0 == rc)
00268 {
00269 exit(0);
00270 }
00271 else
00272 {
00273 exit(2);
00274 }
00275
00276 }
00277
00278
00290 void
00291 usage (
00292 char * pProgName)
00293 {
00294 #ifdef linux
00295 printf("Usage: %s [-v[v]] READERHOSTNAME\n", pProgName);
00296 printf("\n");
00297 printf("Each -v increases verbosity level\n");
00298 #endif
00299 #ifdef WIN32
00300 printf("Usage: %s [/v[v]] READERHOSTNAME\n", pProgName);
00301 printf("\n");
00302 printf("Each /v increases verbosity level\n");
00303 #endif
00304 exit(1);
00305 }
00306
00307
00337 int
00338 CMyApplication::run (
00339 char * pReaderHostName)
00340 {
00341 CTypeRegistry * pTypeRegistry;
00342 CConnection * pConn;
00343 int rc;
00344
00345
00346
00347
00348
00349 pTypeRegistry = getTheTypeRegistry();
00350 if(NULL == pTypeRegistry)
00351 {
00352 printf("ERROR: getTheTypeRegistry failed\n");
00353 return -1;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 pConn = new CConnection(pTypeRegistry, 32u*1024u);
00363 if(NULL == pConn)
00364 {
00365 printf("ERROR: new CConnection failed\n");
00366 return -2;
00367 }
00368
00369
00370
00371
00372 if(m_Verbose)
00373 {
00374 printf ("INFO: Connecting to %s....\n", pReaderHostName);
00375 }
00376
00377 rc = pConn->openConnectionToReader(pReaderHostName);
00378 if(0 != rc)
00379 {
00380 printf("ERROR: connect: %s (%d)\n", pConn->getConnectError(), rc);
00381 delete pConn;
00382 return -3;
00383 }
00384
00385
00386
00387
00388
00389 m_pConnectionToReader = pConn;
00390
00391 if(m_Verbose)
00392 {
00393 printf ("INFO: Connected, checking status....\n");
00394 }
00395
00396
00397
00398
00399
00400
00401 rc = 1;
00402 if(0 == checkConnectionStatus())
00403 {
00404 rc = 2;
00405 if(0 == scrubConfiguration())
00406 {
00407 rc = 3;
00408 if(0 == prepareReader())
00409 {
00410 rc = 4;
00411 if(0 == startAndMonitorOperation())
00412 {
00413 rc = 0;
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422 if(m_Verbose)
00423 {
00424 printf("INFO: Clean up reader configuration...\n");
00425 }
00426 scrubConfiguration();
00427 }
00428 }
00429
00430 if(m_Verbose)
00431 {
00432 printf ("INFO: Finished\n");
00433 }
00434
00435
00436
00437
00438 pConn->closeConnectionToReader();
00439 delete pConn;
00440
00441
00442
00443
00444 delete pTypeRegistry;
00445
00446
00447
00448
00449
00450
00451
00452 if(m_Verbose || m_Quiet)
00453 {
00454 printf("INFO: %d Tag reports\n", m_nTagReport);
00455 }
00456
00457
00458
00459
00460
00461 return rc;
00462 }
00463
00464
00495 int
00496 CMyApplication::checkConnectionStatus (void)
00497 {
00498 CMessage * pMessage;
00499 CREADER_EVENT_NOTIFICATION *pNtf;
00500 CReaderEventNotificationData *pNtfData;
00501 CConnectionAttemptEvent * pEvent;
00502
00503
00504
00505
00506
00507 pMessage = recvMessage(10000);
00508
00509
00510
00511
00512 if(NULL == pMessage)
00513 {
00514
00515 goto fail;
00516 }
00517
00518
00519
00520
00521
00522
00523 if(&CREADER_EVENT_NOTIFICATION::s_typeDescriptor != pMessage->m_pType)
00524 {
00525 goto fail;
00526 }
00527
00528
00529
00530
00531
00532 pNtf = (CREADER_EVENT_NOTIFICATION *) pMessage;
00533 pNtfData = pNtf->getReaderEventNotificationData();
00534 if(NULL == pNtfData)
00535 {
00536 goto fail;
00537 }
00538
00539
00540
00541
00542 pEvent = pNtfData->getConnectionAttemptEvent();
00543 if(NULL == pEvent)
00544 {
00545 goto fail;
00546 }
00547
00548
00549
00550
00551
00552 if(ConnectionAttemptStatusType_Success != pEvent->getStatus())
00553 {
00554 goto fail;
00555 }
00556
00557
00558
00559
00560 delete pMessage;
00561
00562 if(m_Verbose)
00563 {
00564 printf("INFO: Connection status OK\n");
00565 }
00566
00567
00568
00569
00570 return 0;
00571
00572 fail:
00573
00574
00575
00576 printf("ERROR: checkConnectionStatus failed\n");
00577 delete pMessage;
00578 return -1;
00579 }
00580
00581
00605 int
00606 CMyApplication::scrubConfiguration (void)
00607 {
00608 if(0 != resetConfigurationToFactoryDefaults())
00609 {
00610 return -1;
00611 }
00612
00613 if(0 != deleteAllROSpecs())
00614 {
00615 return -2;
00616 }
00617
00618 if(0 != deleteAllAccessSpecs())
00619 {
00620 return -3;
00621 }
00622
00623 return 0;
00624 }
00625
00626
00647 int
00648 CMyApplication::resetConfigurationToFactoryDefaults (void)
00649 {
00650 CSET_READER_CONFIG * pCmd;
00651 CMessage * pRspMsg;
00652 CSET_READER_CONFIG_RESPONSE *pRsp;
00653
00654
00655
00656
00657 pCmd = new CSET_READER_CONFIG();
00658 pCmd->setMessageID(101);
00659 pCmd->setResetToFactoryDefault(1);
00660
00661
00662
00663
00664 pRspMsg = transact(pCmd);
00665
00666
00667
00668
00669 delete pCmd;
00670
00671
00672
00673
00674 if(NULL == pRspMsg)
00675 {
00676
00677 return -1;
00678 }
00679
00680
00681
00682
00683 pRsp = (CSET_READER_CONFIG_RESPONSE *) pRspMsg;
00684
00685
00686
00687
00688 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(),
00689 "resetConfigurationToFactoryDefaults"))
00690 {
00691
00692 delete pRspMsg;
00693 return -1;
00694 }
00695
00696
00697
00698
00699 delete pRspMsg;
00700
00701
00702
00703
00704 if(m_Verbose)
00705 {
00706 printf("INFO: Configuration reset to factory defaults\n");
00707 }
00708
00709
00710
00711
00712 return 0;
00713 }
00714
00715
00735 int
00736 CMyApplication::deleteAllROSpecs (void)
00737 {
00738 CDELETE_ROSPEC * pCmd;
00739 CMessage * pRspMsg;
00740 CDELETE_ROSPEC_RESPONSE * pRsp;
00741
00742
00743
00744
00745 pCmd = new CDELETE_ROSPEC();
00746 pCmd->setMessageID(102);
00747 pCmd->setROSpecID(0);
00748
00749
00750
00751
00752 pRspMsg = transact(pCmd);
00753
00754
00755
00756
00757 delete pCmd;
00758
00759
00760
00761
00762 if(NULL == pRspMsg)
00763 {
00764
00765 return -1;
00766 }
00767
00768
00769
00770
00771 pRsp = (CDELETE_ROSPEC_RESPONSE *) pRspMsg;
00772
00773
00774
00775
00776 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "deleteAllROSpecs"))
00777 {
00778
00779 delete pRspMsg;
00780 return -1;
00781 }
00782
00783
00784
00785
00786 delete pRspMsg;
00787
00788
00789
00790
00791 if(m_Verbose)
00792 {
00793 printf("INFO: All ROSpecs are deleted\n");
00794 }
00795
00796
00797
00798
00799 return 0;
00800 }
00801
00802
00822 int
00823 CMyApplication::deleteAllAccessSpecs (void)
00824 {
00825 CDELETE_ACCESSSPEC * pCmd;
00826 CMessage * pRspMsg;
00827 CDELETE_ACCESSSPEC_RESPONSE *pRsp;
00828
00829
00830
00831
00832 pCmd = new CDELETE_ACCESSSPEC();
00833 pCmd->setMessageID(103);
00834 pCmd->setAccessSpecID(0);
00835
00836
00837
00838
00839 pRspMsg = transact(pCmd);
00840
00841
00842
00843
00844 delete pCmd;
00845
00846
00847
00848
00849 if(NULL == pRspMsg)
00850 {
00851
00852 return -1;
00853 }
00854
00855
00856
00857
00858 pRsp = (CDELETE_ACCESSSPEC_RESPONSE *) pRspMsg;
00859
00860
00861
00862
00863 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "deleteAllAccessSpecs"))
00864 {
00865
00866 delete pRspMsg;
00867 return -1;
00868 }
00869
00870
00871
00872
00873 delete pRspMsg;
00874
00875
00876
00877
00878 if(m_Verbose)
00879 {
00880 printf("INFO: All AccessSpecs are deleted\n");
00881 }
00882
00883
00884
00885
00886 return 0;
00887 }
00888
00889
00918 int
00919 CMyApplication::prepareReader(void)
00920 {
00921 if(0 != getAllCapabilities())
00922 {
00923 return -1;
00924 }
00925
00926 if(0 != getAllConfiguration())
00927 {
00928 return -2;
00929 }
00930
00931 if(0 != configureNotificationStates())
00932 {
00933 return -3;
00934 }
00935
00936 if(0 != getAllConfiguration())
00937 {
00938 return -4;
00939 }
00940
00941 if(0 != addROSpec())
00942 {
00943 return -5;
00944 }
00945
00946 if(0 != enableROSpec())
00947 {
00948 return -6;
00949 }
00950
00951 return 0;
00952 }
00953
00954
00977 int
00978 CMyApplication::getAllCapabilities (void)
00979 {
00980 CGET_READER_CAPABILITIES * pCmd;
00981 CMessage * pRspMsg;
00982 CGET_READER_CAPABILITIES_RESPONSE *pRsp;
00983
00984
00985
00986
00987 pCmd = new CGET_READER_CAPABILITIES();
00988 pCmd->setMessageID(120);
00989 pCmd->setRequestedData(GetReaderCapabilitiesRequestedData_All);
00990
00991
00992
00993
00994 pRspMsg = transact(pCmd);
00995
00996
00997
00998
00999 delete pCmd;
01000
01001
01002
01003
01004 if(NULL == pRspMsg)
01005 {
01006
01007 return -1;
01008 }
01009
01010
01011
01012
01013 pRsp = (CGET_READER_CAPABILITIES_RESPONSE *) pRspMsg;
01014
01015
01016
01017
01018 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "getAllCapabilities"))
01019 {
01020
01021 delete pRspMsg;
01022 return -1;
01023 }
01024
01025
01026
01027
01028 delete pRspMsg;
01029
01030
01031
01032
01033 if(m_Verbose)
01034 {
01035 printf("INFO: Got capabilities\n");
01036 }
01037
01038
01039
01040
01041 return 0;
01042 }
01043
01044
01067 int
01068 CMyApplication::getAllConfiguration (void)
01069 {
01070 CGET_READER_CONFIG * pCmd;
01071 CMessage * pRspMsg;
01072 CGET_READER_CONFIG_RESPONSE *pRsp;
01073
01074
01075
01076
01077 pCmd = new CGET_READER_CONFIG();
01078 pCmd->setMessageID(121);
01079 pCmd->setRequestedData(GetReaderConfigRequestedData_All);
01080
01081
01082
01083
01084 pRspMsg = transact(pCmd);
01085
01086
01087
01088
01089 delete pCmd;
01090
01091
01092
01093
01094 if(NULL == pRspMsg)
01095 {
01096
01097 return -1;
01098 }
01099
01100
01101
01102
01103 pRsp = (CGET_READER_CONFIG_RESPONSE *) pRspMsg;
01104
01105
01106
01107
01108 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "getAllConfiguration"))
01109 {
01110
01111 delete pRspMsg;
01112 return -1;
01113 }
01114
01115
01116
01117
01118 delete pRspMsg;
01119
01120
01121
01122
01123 if(m_Verbose)
01124 {
01125 printf("INFO: Got configuration\n");
01126 }
01127
01128
01129
01130
01131 return 0;
01132 }
01133
01134
01199 int
01200 CMyApplication::configureNotificationStates (void)
01201 {
01202 CEventNotificationState * pENHop = new CEventNotificationState();
01203 pENHop->setEventType(NotificationEventType_Upon_Hopping_To_Next_Channel);
01204 pENHop->setNotificationState(TRUE);
01205
01206 CEventNotificationState * pENGPI = new CEventNotificationState();
01207 pENGPI->setEventType(NotificationEventType_GPI_Event);
01208 pENGPI->setNotificationState(FALSE);
01209
01210 CEventNotificationState * pENROSpec = new CEventNotificationState();
01211 pENROSpec->setEventType(NotificationEventType_ROSpec_Event);
01212 pENROSpec->setNotificationState(TRUE);
01213
01214 CEventNotificationState * pENBufWarn = new CEventNotificationState();
01215 pENBufWarn->setEventType(NotificationEventType_Report_Buffer_Fill_Warning);
01216 pENBufWarn->setNotificationState(TRUE);
01217
01218 CEventNotificationState * pENExcept = new CEventNotificationState();
01219 pENExcept->setEventType(NotificationEventType_Reader_Exception_Event);
01220 pENExcept->setNotificationState(TRUE);
01221
01222 CEventNotificationState * pENSurvey = new CEventNotificationState();
01223 pENSurvey->setEventType(NotificationEventType_RFSurvey_Event);
01224 pENSurvey->setNotificationState(FALSE);
01225
01226 CEventNotificationState * pENAISpec = new CEventNotificationState();
01227 pENAISpec->setEventType(NotificationEventType_AISpec_Event);
01228 pENAISpec->setNotificationState(TRUE);
01229
01230 CEventNotificationState * pENAISpecDetails
01231 = new CEventNotificationState();
01232 pENAISpecDetails->setEventType(
01233 NotificationEventType_AISpec_Event_With_Details);
01234 pENAISpecDetails->setNotificationState(FALSE);
01235
01236 CEventNotificationState * pENAnt = new CEventNotificationState();
01237 pENAnt->setEventType(NotificationEventType_Antenna_Event);
01238 pENAnt->setNotificationState(TRUE);
01239
01240 CReaderEventNotificationSpec * pReaderEventNotificationSpec;
01241
01242 pReaderEventNotificationSpec = new CReaderEventNotificationSpec;
01243
01244 pReaderEventNotificationSpec->addEventNotificationState(pENHop);
01245 pReaderEventNotificationSpec->addEventNotificationState(pENGPI);
01246 pReaderEventNotificationSpec->addEventNotificationState(pENROSpec);
01247 pReaderEventNotificationSpec->addEventNotificationState(pENBufWarn);
01248 pReaderEventNotificationSpec->addEventNotificationState(pENExcept);
01249 pReaderEventNotificationSpec->addEventNotificationState(pENSurvey);
01250 pReaderEventNotificationSpec->addEventNotificationState(pENAISpec);
01251 pReaderEventNotificationSpec->addEventNotificationState(
01252 pENAISpecDetails);
01253 pReaderEventNotificationSpec->addEventNotificationState(pENAnt);
01254
01255 CSET_READER_CONFIG * pCmd;
01256 CMessage * pRspMsg;
01257 CSET_READER_CONFIG_RESPONSE *pRsp;
01258
01259
01260
01261
01262
01263
01264
01265
01266 pCmd = new CSET_READER_CONFIG();
01267 pCmd->setMessageID(150);
01268 pCmd->setReaderEventNotificationSpec(pReaderEventNotificationSpec);
01269
01270
01271
01272
01273 pRspMsg = transact(pCmd);
01274
01275
01276
01277
01278
01279 delete pCmd;
01280
01281
01282
01283
01284 if(NULL == pRspMsg)
01285 {
01286
01287 return -1;
01288 }
01289
01290
01291
01292
01293 pRsp = (CSET_READER_CONFIG_RESPONSE *) pRspMsg;
01294
01295
01296
01297
01298 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(),
01299 "configureNotificationStates"))
01300 {
01301 delete pRspMsg;
01302 return -1;
01303 }
01304
01305
01306
01307
01308 delete pRspMsg;
01309
01310
01311
01312
01313 if(m_Verbose)
01314 {
01315 printf("INFO: Notifications are configured\n");
01316 }
01317
01318
01319
01320
01321 return 0;
01322 }
01323
01324
01415 int
01416 CMyApplication::addROSpec (void)
01417 {
01418 CROSpecStartTrigger * pROSpecStartTrigger =
01419 new CROSpecStartTrigger();
01420 pROSpecStartTrigger->setROSpecStartTriggerType(
01421 ROSpecStartTriggerType_Null);
01422
01423 CROSpecStopTrigger * pROSpecStopTrigger = new CROSpecStopTrigger();
01424 pROSpecStopTrigger->setROSpecStopTriggerType(ROSpecStopTriggerType_Null);
01425 pROSpecStopTrigger->setDurationTriggerValue(0);
01426
01427 CROBoundarySpec * pROBoundarySpec = new CROBoundarySpec();
01428 pROBoundarySpec->setROSpecStartTrigger(pROSpecStartTrigger);
01429 pROBoundarySpec->setROSpecStopTrigger(pROSpecStopTrigger);
01430
01431 #if 1
01432 CAISpecStopTrigger * pAISpecStopTrigger = new CAISpecStopTrigger();
01433 pAISpecStopTrigger->setAISpecStopTriggerType(
01434 AISpecStopTriggerType_Duration);
01435 pAISpecStopTrigger->setDurationTrigger(30000);
01436 #else
01437 CTagObservationTrigger * pTagObservationTrigger =
01438 new CTagObservationTrigger();
01439 pTagObservationTrigger->setTriggerType (
01440 TagObservationTriggerType_Upon_Seeing_No_More_New_Tags_For_Tms_Or_Timeout);
01441 pTagObservationTrigger->setNumberOfTags(0);
01442 pTagObservationTrigger->setNumberOfAttempts(0);
01443 pTagObservationTrigger->setT(3500);
01444 pTagObservationTrigger->setTimeout(12500);
01445
01446 CAISpecStopTrigger * pAISpecStopTrigger = new CAISpecStopTrigger();
01447 pAISpecStopTrigger->setAISpecStopTriggerType(
01448 AISpecStopTriggerType_Tag_Observation);
01449 pAISpecStopTrigger->setDurationTrigger(0);
01450 pAISpecStopTrigger->setTagObservationTrigger(pTagObservationTrigger);
01451 #endif
01452
01453 CC1G2SingulationControl * pC1G2SingulationControl =
01454 new CC1G2SingulationControl();
01455 pC1G2SingulationControl->setSession(2);
01456 pC1G2SingulationControl->setTagPopulation(32);
01457
01458 CC1G2InventoryCommand * pC1G2InventoryCommand =
01459 new CC1G2InventoryCommand();
01460 pC1G2InventoryCommand->setC1G2SingulationControl(
01461 pC1G2SingulationControl);
01462
01463
01464
01465
01466 CAntennaConfiguration * pAntennaConfiguration =
01467 new CAntennaConfiguration();
01468 pAntennaConfiguration->addAirProtocolInventoryCommandSettings (
01469 pC1G2InventoryCommand);
01470
01471 CInventoryParameterSpec * pInventoryParameterSpec =
01472 new CInventoryParameterSpec();
01473 pInventoryParameterSpec->setInventoryParameterSpecID(1234);
01474 pInventoryParameterSpec->setProtocolID(AirProtocols_EPCGlobalClass1Gen2);
01475 pInventoryParameterSpec->addAntennaConfiguration (
01476 pAntennaConfiguration);
01477
01478 llrp_u16v_t AntennaIDs = llrp_u16v_t(1);
01479 AntennaIDs.m_pValue[0] = 0;
01480
01481 CAISpec * pAISpec = new CAISpec();
01482 pAISpec->setAntennaIDs(AntennaIDs);
01483 pAISpec->setAISpecStopTrigger(pAISpecStopTrigger);
01484 pAISpec->addInventoryParameterSpec(pInventoryParameterSpec);
01485
01486 CTagReportContentSelector * pTagReportContentSelector =
01487 new CTagReportContentSelector();
01488 pTagReportContentSelector->setEnableROSpecID(FALSE);
01489 pTagReportContentSelector->setEnableSpecIndex(FALSE);
01490 pTagReportContentSelector->setEnableInventoryParameterSpecID(FALSE);
01491 pTagReportContentSelector->setEnableAntennaID(TRUE);
01492 pTagReportContentSelector->setEnableChannelIndex(FALSE);
01493 pTagReportContentSelector->setEnablePeakRSSI(TRUE);
01494 pTagReportContentSelector->setEnableFirstSeenTimestamp(TRUE);
01495 pTagReportContentSelector->setEnableLastSeenTimestamp(TRUE);
01496 pTagReportContentSelector->setEnableTagSeenCount(TRUE);
01497 pTagReportContentSelector->setEnableAccessSpecID(FALSE);
01498
01499 CROReportSpec * pROReportSpec = new CROReportSpec();
01500 pROReportSpec->setROReportTrigger(
01501 ROReportTriggerType_Upon_N_Tags_Or_End_Of_ROSpec);
01502 pROReportSpec->setN(1);
01503 pROReportSpec->setTagReportContentSelector(pTagReportContentSelector);
01504
01505 CROSpec * pROSpec = new CROSpec();
01506 pROSpec->setROSpecID(123);
01507 pROSpec->setPriority(0);
01508 pROSpec->setCurrentState(ROSpecState_Disabled);
01509 pROSpec->setROBoundarySpec(pROBoundarySpec);
01510 pROSpec->addSpecParameter(pAISpec);
01511 pROSpec->setROReportSpec(pROReportSpec);
01512
01513 CADD_ROSPEC * pCmd;
01514 CMessage * pRspMsg;
01515 CADD_ROSPEC_RESPONSE * pRsp;
01516
01517
01518
01519
01520
01521
01522
01523
01524 pCmd = new CADD_ROSPEC();
01525 pCmd->setMessageID(201);
01526 pCmd->setROSpec(pROSpec);
01527
01528
01529
01530
01531
01532
01533 if(0 <= m_ModeIndex)
01534 {
01535 CC1G2RFControl * pC1G2RFControl =
01536 new CC1G2RFControl();
01537
01538 pC1G2RFControl->setModeIndex(m_ModeIndex);
01539 pC1G2InventoryCommand->setC1G2RFControl(pC1G2RFControl);
01540 }
01541
01542
01543
01544
01545 pRspMsg = transact(pCmd);
01546
01547
01548
01549
01550
01551 delete pCmd;
01552
01553
01554
01555
01556 if(NULL == pRspMsg)
01557 {
01558
01559 return -1;
01560 }
01561
01562
01563
01564
01565 pRsp = (CADD_ROSPEC_RESPONSE *) pRspMsg;
01566
01567
01568
01569
01570 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "addROSpec"))
01571 {
01572
01573 delete pRspMsg;
01574 return -1;
01575 }
01576
01577
01578
01579
01580 delete pRspMsg;
01581
01582
01583
01584
01585 if(m_Verbose)
01586 {
01587 printf("INFO: ROSpec added\n");
01588 }
01589
01590
01591
01592
01593 return 0;
01594 }
01595
01596
01614 int
01615 CMyApplication::enableROSpec (void)
01616 {
01617 CENABLE_ROSPEC * pCmd;
01618 CMessage * pRspMsg;
01619 CENABLE_ROSPEC_RESPONSE * pRsp;
01620
01621
01622
01623
01624 pCmd = new CENABLE_ROSPEC();
01625 pCmd->setMessageID(202);
01626 pCmd->setROSpecID(123);
01627
01628
01629
01630
01631 pRspMsg = transact(pCmd);
01632
01633
01634
01635
01636 delete pCmd;
01637
01638
01639
01640
01641 if(NULL == pRspMsg)
01642 {
01643
01644 return -1;
01645 }
01646
01647
01648
01649
01650 pRsp = (CENABLE_ROSPEC_RESPONSE *) pRspMsg;
01651
01652
01653
01654
01655 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "enableROSpec"))
01656 {
01657
01658 delete pRspMsg;
01659 return -1;
01660 }
01661
01662
01663
01664
01665 delete pRspMsg;
01666
01667
01668
01669
01670 if(m_Verbose)
01671 {
01672 printf("INFO: ROSpec enabled\n");
01673 }
01674
01675
01676
01677
01678 return 0;
01679 }
01680
01681
01724 int
01725 CMyApplication::startAndMonitorOperation (void)
01726 {
01727 CSTART_ROSPEC * pCmd;
01728 int bDone = 0;
01729 int RetVal = 0;
01730
01731
01732
01733
01734 printf("INFO: Inventory operation starting\n");
01735
01736
01737
01738
01739 pCmd = new CSTART_ROSPEC();
01740 pCmd->setMessageID(203);
01741 pCmd->setROSpecID(123);
01742
01743
01744
01745
01746 if(0 != sendMessage(pCmd))
01747 {
01748
01749 return -1;
01750 }
01751
01752
01753
01754
01755 delete pCmd;
01756
01757
01758
01759
01760
01761 while(!bDone)
01762 {
01763 CMessage * pMessage;
01764 const CTypeDescriptor * pType;
01765
01766
01767
01768
01769
01770
01771 pMessage = recvMessage(20000);
01772 if(NULL == pMessage)
01773 {
01774
01775
01776
01777
01778 RetVal = -2;
01779 bDone = 1;
01780 continue;
01781 }
01782
01783
01784
01785
01786
01787
01788 pType = pMessage->m_pType;
01789
01790
01791
01792
01793
01794
01795
01796 if(&CSTART_ROSPEC_RESPONSE::s_typeDescriptor == pType)
01797 {
01798 CSTART_ROSPEC_RESPONSE *pRsp;
01799
01800
01801
01802
01803 pRsp = (CSTART_ROSPEC_RESPONSE *) pMessage;
01804
01805
01806
01807
01808 if(0 != checkLLRPStatus(pRsp->getLLRPStatus(), "startROSpec"))
01809 {
01810
01811 RetVal = -3;
01812 bDone = 1;
01813 }
01814 else
01815 {
01816
01817 if(m_Verbose)
01818 {
01819 printf("INFO: Start command acknowledged\n");
01820 }
01821 }
01822 }
01823
01824
01825
01826
01827 else if(&CREADER_EVENT_NOTIFICATION::s_typeDescriptor == pType)
01828 {
01829 CREADER_EVENT_NOTIFICATION *pNtf;
01830 CReaderEventNotificationData *pNtfData;
01831
01832 pNtf = (CREADER_EVENT_NOTIFICATION *) pMessage;
01833 pNtfData = pNtf->getReaderEventNotificationData();
01834
01835
01836
01837
01838
01839 if(NULL != pNtfData->getROSpecEvent())
01840 {
01841 CROSpecEvent * pROEvent;
01842
01843 pROEvent = pNtfData->getROSpecEvent();
01844 switch(pROEvent->getEventType())
01845 {
01846 default:
01847 printf("ERROR: Unknown RO event type\n");
01848 RetVal = -4;
01849 bDone = 1;
01850 break;
01851
01852 case ROSpecEventType_Start_Of_ROSpec:
01853 if(m_Verbose)
01854 {
01855 printf("INFO: RO running\n");
01856 }
01857 break;
01858
01859 case ROSpecEventType_End_Of_ROSpec:
01860 if(m_Verbose)
01861 {
01862 printf("INFO: RO stopped\n");
01863 }
01864 RetVal = 0;
01865 bDone = 1;
01866 break;
01867 }
01868 }
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 }
01880
01881
01882
01883
01884 else if(&CRO_ACCESS_REPORT::s_typeDescriptor == pType)
01885 {
01886 CRO_ACCESS_REPORT * pNtf;
01887
01888 pNtf = (CRO_ACCESS_REPORT *) pMessage;
01889
01890 printTagReportData(pNtf);
01891 }
01892
01893
01894
01895
01896 else
01897 {
01898 printf("WARNING: Ignored unexpected message during monitor: %s\n",
01899 pType->m_pName);
01900 }
01901
01902
01903
01904
01905 delete pMessage;
01906 }
01907
01908
01909
01910
01911 if(RetVal != 0)
01912 {
01913 printf("ERROR: Inventory operation terminated (%d)\n", RetVal);
01914 }
01915 else if(m_Verbose)
01916 {
01917 printf("INFO: Inventory operation finished\n");
01918 }
01919
01920 return RetVal;
01921 }
01922
01923
01938 void
01939 CMyApplication::printTagReportData (
01940 CRO_ACCESS_REPORT * pRO_ACCESS_REPORT)
01941 {
01942 std::list<CTagReportData *>::iterator Cur;
01943 unsigned int nEntry = 0;
01944
01945
01946
01947
01948 m_nTagReport++;
01949
01950
01951
01952
01953 if(m_Quiet)
01954 {
01955 return;
01956 }
01957
01958
01959
01960
01961 for (
01962 Cur = pRO_ACCESS_REPORT->beginTagReportData();
01963 Cur != pRO_ACCESS_REPORT->endTagReportData();
01964 Cur++)
01965 {
01966 nEntry++;
01967 }
01968
01969 printf("INFO: %u tag report entries\n", nEntry);
01970
01971
01972
01973
01974 for (
01975 Cur = pRO_ACCESS_REPORT->beginTagReportData();
01976 Cur != pRO_ACCESS_REPORT->endTagReportData();
01977 Cur++)
01978 {
01979 printOneTagReportData (*Cur);
01980 }
01981 }
01982
01983
01997 void
01998 CMyApplication::printOneTagReportData (
01999 CTagReportData * pTagReportData)
02000 {
02001 const CTypeDescriptor * pType;
02002 char aBuf[64];
02003
02004
02005
02006
02007
02008
02009 CParameter * pEPCParameter =
02010 pTagReportData->getEPCParameter();
02011
02012 if(NULL != pEPCParameter)
02013 {
02014 char * p = aBuf;
02015 llrp_u96_t my_u96;
02016 llrp_u1v_t my_u1v;
02017 llrp_u8_t * pValue = NULL;
02018 unsigned int n, i;
02019
02020 pType = pEPCParameter->m_pType;
02021 if(&CEPC_96::s_typeDescriptor == pType)
02022 {
02023 CEPC_96 *pEPC_96;
02024
02025 pEPC_96 = (CEPC_96 *) pEPCParameter;
02026 my_u96 = pEPC_96->getEPC();
02027 pValue = my_u96.m_aValue;
02028 n = 12u;
02029 }
02030 else if(&CEPCData::s_typeDescriptor == pType)
02031 {
02032 CEPCData * pEPCData;
02033
02034 pEPCData = (CEPCData *) pEPCParameter;
02035 my_u1v = pEPCData->getEPC();
02036 pValue = my_u1v.m_pValue;
02037 n = (my_u1v.m_nBit + 7u) / 8u;
02038 }
02039
02040 if(NULL != pValue)
02041 {
02042 for(i = 0; i < n; i++)
02043 {
02044 if(0 < i && i%2 == 0)
02045 {
02046 *p++ = '-';
02047 }
02048 sprintf(p, "%02X", pValue[i]);
02049 while(*p) p++;
02050 }
02051 }
02052 else
02053 {
02054 strcpy(aBuf, "---unknown-epc-data-type---");
02055 }
02056 }
02057 else
02058 {
02059 strcpy(aBuf, "---missing-epc-data---");
02060 }
02061 printf("%-32s", aBuf);
02062
02063
02064
02065
02066 if(NULL != pTagReportData->getAntennaID())
02067 {
02068 sprintf(aBuf, "ant%d",
02069 pTagReportData->getAntennaID()->getAntennaID());
02070 }
02071 else
02072 {
02073 sprintf(aBuf, "ant?");
02074 }
02075 printf(" %-5s", aBuf);
02076
02077
02078
02079
02080 if(NULL != pTagReportData->getPeakRSSI())
02081 {
02082 sprintf(aBuf, "%3ddBm",
02083 pTagReportData->getPeakRSSI()->getPeakRSSI());
02084 }
02085 else
02086 {
02087 sprintf(aBuf, " ?dBm");
02088 }
02089 printf(" %-7s", aBuf);
02090
02091
02092
02093
02094 if(NULL != pTagReportData->getTagSeenCount())
02095 {
02096 sprintf(aBuf, "%4dseen",
02097 pTagReportData->getTagSeenCount()->getTagCount());
02098 }
02099 else
02100 {
02101 sprintf(aBuf, " ?seen");
02102 }
02103 printf(" %-8s", aBuf);
02104
02105
02106
02107
02108 printf("\n");
02109 }
02110
02111
02130 int
02131 CMyApplication::checkLLRPStatus (
02132 CLLRPStatus * pLLRPStatus,
02133 char * pWhatStr)
02134 {
02135
02136
02137
02138
02139
02140
02141 if(NULL == pLLRPStatus)
02142 {
02143 printf("ERROR: %s missing LLRP status\n", pWhatStr);
02144 return -1;
02145 }
02146
02147
02148
02149
02150
02151
02152
02153
02154 if(StatusCode_M_Success != pLLRPStatus->getStatusCode())
02155 {
02156 llrp_utf8v_t ErrorDesc;
02157
02158 ErrorDesc = pLLRPStatus->getErrorDescription();
02159
02160 if(0 == ErrorDesc.m_nValue)
02161 {
02162 printf("ERROR: %s failed, no error description given\n",
02163 pWhatStr);
02164 }
02165 else
02166 {
02167 printf("ERROR: %s failed, %.*s\n",
02168 pWhatStr, ErrorDesc.m_nValue, ErrorDesc.m_pValue);
02169 }
02170 return -2;
02171 }
02172
02173
02174
02175
02176 return 0;
02177 }
02178
02179
02203 CMessage *
02204 CMyApplication::transact (
02205 CMessage * pSendMsg)
02206 {
02207 CConnection * pConn = m_pConnectionToReader;
02208 CMessage * pRspMsg;
02209
02210
02211
02212
02213
02214 if(1 < m_Verbose)
02215 {
02216
02217 if(2 > m_Quiet)
02218 {
02219 printf("\n===================================\n");
02220 printf("INFO: Transact sending\n");
02221 }
02222 printXMLMessage(pSendMsg);
02223 }
02224
02225
02226
02227
02228
02229
02230 pRspMsg = pConn->transact(pSendMsg, 5000);
02231
02232 if(NULL == pRspMsg)
02233 {
02234 const CErrorDetails * pError = pConn->getTransactError();
02235
02236 printf("ERROR: %s transact failed, %s\n",
02237 pSendMsg->m_pType->m_pName,
02238 pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
02239
02240 if(NULL != pError->m_pRefType)
02241 {
02242 printf("ERROR: ... reference type %s\n",
02243 pError->m_pRefType->m_pName);
02244 }
02245
02246 if(NULL != pError->m_pRefField)
02247 {
02248 printf("ERROR: ... reference field %s\n",
02249 pError->m_pRefField->m_pName);
02250 }
02251
02252 return NULL;
02253 }
02254
02255
02256
02257
02258
02259 if(1 < m_Verbose)
02260 {
02261
02262 if(2 > m_Quiet)
02263 {
02264 printf("\n- - - - - - - - - - - - - - - - - -\n");
02265 printf("INFO: Transact received response\n");
02266 }
02267 printXMLMessage(pRspMsg);
02268 }
02269
02270
02271
02272
02273
02274
02275 if(&CERROR_MESSAGE::s_typeDescriptor == pRspMsg->m_pType)
02276 {
02277 const CTypeDescriptor * pResponseType;
02278
02279 pResponseType = pSendMsg->m_pType->m_pResponseType;
02280
02281 printf("ERROR: Received ERROR_MESSAGE instead of %s\n",
02282 pResponseType->m_pName);
02283 delete pRspMsg;
02284 pRspMsg = NULL;
02285 }
02286
02287 return pRspMsg;
02288 }
02289
02290
02315 CMessage *
02316 CMyApplication::recvMessage (
02317 int nMaxMS)
02318 {
02319 CConnection * pConn = m_pConnectionToReader;
02320 CMessage * pMessage;
02321
02322
02323
02324
02325 pMessage = pConn->recvMessage(nMaxMS);
02326
02327
02328
02329
02330
02331 if(NULL == pMessage)
02332 {
02333 const CErrorDetails * pError = pConn->getRecvError();
02334
02335 printf("ERROR: recvMessage failed, %s\n",
02336 pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
02337
02338 if(NULL != pError->m_pRefType)
02339 {
02340 printf("ERROR: ... reference type %s\n",
02341 pError->m_pRefType->m_pName);
02342 }
02343
02344 if(NULL != pError->m_pRefField)
02345 {
02346 printf("ERROR: ... reference field %s\n",
02347 pError->m_pRefField->m_pName);
02348 }
02349
02350 return NULL;
02351 }
02352
02353
02354
02355
02356
02357 if(1 < m_Verbose)
02358 {
02359
02360 if(2 > m_Quiet)
02361 {
02362 printf("\n===================================\n");
02363 printf("INFO: Message received\n");
02364 }
02365 printXMLMessage(pMessage);
02366 }
02367
02368 return pMessage;
02369 }
02370
02371
02389 int
02390 CMyApplication::sendMessage (
02391 CMessage * pSendMsg)
02392 {
02393 CConnection * pConn = m_pConnectionToReader;
02394
02395
02396
02397
02398
02399 if(1 < m_Verbose)
02400 {
02401
02402 if(2 > m_Quiet)
02403 {
02404 printf("\n===================================\n");
02405 printf("INFO: Sending\n");
02406 }
02407 printXMLMessage(pSendMsg);
02408 }
02409
02410
02411
02412
02413
02414
02415 if(RC_OK != pConn->sendMessage(pSendMsg))
02416 {
02417 const CErrorDetails * pError = pConn->getSendError();
02418
02419 printf("ERROR: %s sendMessage failed, %s\n",
02420 pSendMsg->m_pType->m_pName,
02421 pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
02422
02423 if(NULL != pError->m_pRefType)
02424 {
02425 printf("ERROR: ... reference type %s\n",
02426 pError->m_pRefType->m_pName);
02427 }
02428
02429 if(NULL != pError->m_pRefField)
02430 {
02431 printf("ERROR: ... reference field %s\n",
02432 pError->m_pRefField->m_pName);
02433 }
02434
02435 return -1;
02436 }
02437
02438
02439
02440
02441 return 0;
02442 }
02443
02444
02458 void
02459 CMyApplication::printXMLMessage (
02460 CMessage * pMessage)
02461 {
02462 char aBuf[100*1024];
02463
02464
02465
02466
02467
02468
02469
02470
02471 pMessage->toXMLString(aBuf, sizeof aBuf);
02472
02473
02474
02475
02476
02477
02478
02479
02480 if(2 > m_Quiet)
02481 {
02482 printf("%s", aBuf);
02483 }
02484 }