00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "tm_config.h"
00030 #include "tm_reader.h"
00031 #include "serial_reader_imp.h"
00032 #include <stdio.h>
00033 #ifdef TMR_ENABLE_BACKGROUND_READS
00034
00035 #include <stdlib.h>
00036 #include <pthread.h>
00037 #include <semaphore.h>
00038 #include <time.h>
00039 #include <stdio.h>
00040
00041 #ifndef WIN32
00042 #include <sys/time.h>
00043 #endif
00044
00045 #ifdef TMR_ENABLE_LLRP_READER
00046 #include "llrp_reader_imp.h"
00047 #endif
00048 #include "osdep.h"
00049 #include "tmr_utils.h"
00050
00051 static void *do_background_reads(void *arg);
00052 static void *parse_tag_reads(void *arg);
00053 static void process_async_response(TMR_Reader *reader);
00054 bool IsDutyCycleEnabled(TMR_Reader *reader);
00055 bool isBufferOverFlow = false;
00056 #endif
00057
00058 TMR_Status
00059 TMR_startReading(struct TMR_Reader *reader)
00060 {
00061 #ifdef SINGLE_THREAD_ASYNC_READ
00062 TMR_Status ret;
00063 reader->continuousReading = true;
00064 ret = TMR_read(reader, 500, NULL);
00065 if(TMR_SUCCESS != ret)
00066 return ret;
00067 #else
00068 #ifdef TMR_ENABLE_BACKGROUND_READS
00069 int ret;
00070 bool createParser = true;
00071
00072 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00073 {
00074 #ifdef TMR_ENABLE_SERIAL_READER
00075
00080 if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)
00081 {
00082 uint8_t loop = 0;
00083 TMR_MultiReadPlan *multi;
00084
00085 multi = &reader->readParams.readPlan->u.multi;
00086
00087 for (loop = 0; loop < multi->planCount; loop++)
00088 {
00089 if (multi->plans[loop]->u.simple.stopOnCount.stopNTriggerStatus)
00090 {
00091
00092 return TMR_ERROR_UNSUPPORTED;
00093 }
00094 }
00095 }
00096 else if (TMR_READ_PLAN_TYPE_SIMPLE == reader->readParams.readPlan->type)
00097 {
00098 if (reader->readParams.readPlan->u.simple.stopOnCount.stopNTriggerStatus)
00099 {
00100
00101 return TMR_ERROR_UNSUPPORTED;
00102 }
00103 }
00104 else
00105 {
00106
00107 }
00108
00114 if (
00115 ((TMR_SR_MODEL_M6E == reader->u.serialReader.versionInfo.hardware[0])||
00116 (TMR_SR_MODEL_M6E_I == reader->u.serialReader.versionInfo.hardware[0]) ||
00117 (TMR_SR_MODEL_MICRO == reader->u.serialReader.versionInfo.hardware[0]) ||
00118 (TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0])) &&
00119 (reader->readParams.asyncOffTime == 0 || (reader->readParams.asyncOffTime != 0 && IsDutyCycleEnabled(reader)) ) &&
00120 ((TMR_READ_PLAN_TYPE_SIMPLE == reader->readParams.readPlan->type) ||
00121 ((TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type) &&
00122 (compareAntennas(&reader->readParams.readPlan->u.multi))))
00123 )
00124 {
00125 if (reader->readParams.asyncOffTime == 0)
00126 {
00127 reader->dutyCycle = false;
00128 }
00129 else
00130 {
00131 reader->dutyCycle = true;
00132 }
00133 }
00134 else
00135 {
00136 createParser = false;
00137 reader->dutyCycle = false;
00138 }
00139 #else
00140 return TMR_ERROR_UNSUPPORTED;
00141 #endif
00142 }
00143 #ifdef TMR_ENABLE_LLRP_READER
00144 if (TMR_READER_TYPE_LLRP == reader->readerType)
00145 {
00150 TMR_LLRP_setBackgroundReceiverState(reader, false);
00156 reader->u.llrpReader.ka_start = tmr_gettime();
00157 }
00158 #endif
00159
00163 pthread_mutex_lock(&reader->backgroundLock);
00164 reader->readState = TMR_READ_STATE_STARTING;
00165 pthread_cond_broadcast(&reader->readCond);
00166 pthread_mutex_unlock(&reader->backgroundLock);
00167
00168 if (true == createParser)
00169 {
00176 pthread_mutex_lock(&reader->parserLock);
00177
00178 if (false == reader->parserSetup)
00179 {
00180 ret = pthread_create(&reader->backgroundParser, NULL,
00181 parse_tag_reads, reader);
00182 if (0 != ret)
00183 {
00184 pthread_mutex_unlock(&reader->parserLock);
00185 return TMR_ERROR_NO_THREADS;
00186 }
00187 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00188 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00189 pthread_detach(reader->backgroundParser);
00193 reader->queue_depth = 0;
00194 sem_init(&reader->queue_length, 0, 0);
00195 sem_init(&reader->queue_slots, 0, TMR_MAX_QUEUE_SLOTS);
00196 reader->parserSetup = true;
00197 }
00198
00199 reader->parserEnabled = true;
00200
00201
00202
00203 reader->continuousReading = true;
00204 reader->finishedReading = false;
00205 pthread_cond_signal(&reader->parserCond);
00206 pthread_mutex_unlock(&reader->parserLock);
00207 }
00208
00209
00210 pthread_mutex_lock(&reader->backgroundLock);
00211
00212 if (false == reader->backgroundSetup)
00213 {
00214 ret = pthread_create(&reader->backgroundReader, NULL,
00215 do_background_reads, reader);
00216 if (0 != ret)
00217 {
00218 pthread_mutex_unlock(&reader->backgroundLock);
00219 return TMR_ERROR_NO_THREADS;
00220 }
00221 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00222 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00223 reader->backgroundSetup = true;
00224 }
00225
00226 reader->backgroundEnabled = true;
00227 reader->searchStatus = true;
00228
00229 #ifdef TMR_ENABLE_SERIAL_READER
00230 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00231 {
00232 reader->u.serialReader.tagopFailureCount = 0;
00233 reader->u.serialReader.tagopSuccessCount = 0;
00234 }
00235 #endif
00236 pthread_cond_signal(&reader->backgroundCond);
00237 pthread_mutex_unlock(&reader->backgroundLock);
00238
00239
00245 pthread_mutex_lock(&reader->backgroundLock);
00246 while (TMR_READ_STATE_STARTING == reader->readState)
00247 {
00248 pthread_cond_wait(&reader->readCond, &reader->backgroundLock);
00249 }
00250 pthread_mutex_unlock(&reader->backgroundLock);
00251 #endif
00252 #endif
00253
00254 return TMR_SUCCESS;
00255 }
00256 #ifdef TMR_ENABLE_BACKGROUND_READS
00257 bool IsDutyCycleEnabled(struct TMR_Reader *reader)
00258 {
00259 uint16_t i;
00260 uint8_t *readerVersion = reader->u.serialReader.versionInfo.fwVersion ;
00261 uint8_t checkVersion[4];
00262 switch (reader->u.serialReader.versionInfo.hardware[0])
00263 {
00264 case TMR_SR_MODEL_M6E:
00265 case TMR_SR_MODEL_M6E_I:
00266 checkVersion[0] = 0x01; checkVersion[1] = 0x21; checkVersion[2] = 0x01; checkVersion[3] = 0x07;
00267 break;
00268 case TMR_SR_MODEL_MICRO:
00269 checkVersion[0] = 0x01; checkVersion[1] = 0x09; checkVersion[2] = 0x00; checkVersion[3] = 0x02;
00270 break;
00271 case TMR_SR_MODEL_M6E_NANO:
00272 checkVersion[0] = 0x01; checkVersion[1] = 0x07; checkVersion[2] = 0x00; checkVersion[3] = 0x02;
00273 break;
00274 default:
00275 checkVersion[0] = 0xFF; checkVersion[1] = 0xFF; checkVersion[2] = 0xFF; checkVersion[3] = 0xFF;
00276 }
00277 for (i = 0; i < 4; i++)
00278 {
00279 if (readerVersion[i] < checkVersion[i])
00280 {
00281 return false;
00282 }
00283 }
00284 return true;
00285 }
00286
00287 #endif
00288
00289 void
00290 reset_continuous_reading(struct TMR_Reader *reader, bool dueToError)
00291 {
00292 if (true == reader->continuousReading)
00293 {
00294 #ifndef SINGLE_THREAD_ASYNC_READ
00295 #ifdef TMR_ENABLE_LLRP_READER
00296 if (TMR_READER_TYPE_LLRP == reader->readerType)
00297 {
00302 TMR_LLRP_setBackgroundReceiverState(reader, true);
00303 }
00304 #endif
00305
00306 #ifdef TMR_ENABLE_SERIAL_READER
00307 if ((false == dueToError) && (TMR_READER_TYPE_SERIAL == reader->readerType))
00308 {
00312 TMR_Status ret;
00313 bool value = reader->u.serialReader.enableReadFiltering;
00314 reader->hasContinuousReadStarted = false;
00315 ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &value);
00316 if (TMR_SUCCESS != ret)
00317 {
00318 #ifndef BARE_METAL
00319 notify_exception_listeners(reader, ret);
00320 #endif
00321 }
00322 }
00323 #endif
00324 #endif
00325
00326 reader->continuousReading = false;
00327 }
00328 }
00329
00330 TMR_Status
00331 TMR_stopReading(struct TMR_Reader *reader)
00332 {
00333 reader->hasContinuousReadStarted = false;
00334 #ifdef SINGLE_THREAD_ASYNC_READ
00335 reader->cmdStopReading(reader);
00336 #else
00337 #ifdef TMR_ENABLE_BACKGROUND_READS
00338
00339
00340 pthread_mutex_lock(&reader->backgroundLock);
00341
00342 if (false == reader->backgroundSetup)
00343 {
00344 pthread_mutex_unlock(&reader->backgroundLock);
00345 return TMR_SUCCESS;
00346 }
00347
00348 if (false == reader->searchStatus)
00349 {
00354 pthread_mutex_unlock(&reader->backgroundLock);
00355 return TMR_SUCCESS;
00356 }
00361 reader->searchStatus = false;
00362 pthread_mutex_unlock(&reader->backgroundLock);
00363
00367 pthread_mutex_lock(&reader->backgroundLock);
00368 while (TMR_READ_STATE_STARTING == reader->readState)
00369 {
00370 pthread_cond_wait(&reader->readCond, &reader->backgroundLock);
00371 }
00372 pthread_mutex_unlock(&reader->backgroundLock);
00373
00374 if ((true == reader->continuousReading) && (true == reader->trueAsyncflag))
00375 {
00380 if(!isBufferOverFlow)
00381 {
00382 reader->cmdStopReading(reader);
00383 }
00384
00389 pthread_mutex_lock(&reader->backgroundLock);
00390 while (TMR_READ_STATE_DONE != reader->readState)
00391 {
00392 pthread_cond_wait(&reader->readCond, &reader->backgroundLock);
00393 }
00394 pthread_mutex_unlock(&reader->backgroundLock);
00400 }
00401
00407 pthread_mutex_lock(&reader->backgroundLock);
00408 reader->backgroundEnabled = false;
00409 while (true == reader->backgroundRunning)
00410 {
00411 pthread_cond_wait(&reader->backgroundCond, &reader->backgroundLock);
00412 }
00413 pthread_mutex_unlock(&reader->backgroundLock);
00414
00420 #else
00421 reader->cmdStopReading(reader);
00422 #endif
00423 reset_continuous_reading(reader, false);
00424 #endif
00425 return TMR_SUCCESS;
00426 }
00427
00428 void
00429 notify_read_listeners(TMR_Reader *reader, TMR_TagReadData *trd)
00430 {
00431 TMR_ReadListenerBlock *rlb;
00432
00433
00434 if (NULL != reader)
00435 {
00436 #ifndef SINGLE_THREAD_ASYNC_READ
00437 pthread_mutex_lock(&reader->listenerLock);
00438 #endif
00439 rlb = reader->readListeners;
00440 while (rlb)
00441 {
00442 rlb->listener(reader, trd, rlb->cookie);
00443 rlb = rlb->next;
00444 }
00445 #ifndef SINGLE_THREAD_ASYNC_READ
00446 pthread_mutex_unlock(&reader->listenerLock);
00447 #endif
00448 }
00449 }
00450
00451 void
00452 notify_stats_listeners(TMR_Reader *reader, TMR_Reader_StatsValues *stats)
00453 {
00454 TMR_StatsListenerBlock *slb;
00455
00456
00457 #ifndef SINGLE_THREAD_ASYNC_READ
00458 pthread_mutex_lock(&reader->listenerLock);
00459 #endif
00460 slb = reader->statsListeners;
00461 while (slb)
00462 {
00463 slb->listener(reader, stats, slb->cookie);
00464 slb = slb->next;
00465 }
00466 #ifndef SINGLE_THREAD_ASYNC_READ
00467 pthread_mutex_unlock(&reader->listenerLock);
00468 #endif
00469 }
00470
00471 #ifdef TMR_ENABLE_BACKGROUND_READS
00472
00473
00474
00475 void
00476 notify_authreq_listeners(TMR_Reader *reader, TMR_TagReadData *trd, TMR_TagAuthentication *auth)
00477 {
00478 TMR_AuthReqListenerBlock *arlb;
00479
00480
00481 pthread_mutex_lock(&reader->listenerLock);
00482 arlb = reader->authReqListeners;
00483 while (arlb)
00484 {
00485 arlb->listener(reader, trd, arlb->cookie, auth);
00486 arlb = arlb->next;
00487 }
00488 pthread_mutex_unlock(&reader->listenerLock);
00489 }
00490 #endif
00491
00492 TMR_Status
00493 TMR_addReadExceptionListener(TMR_Reader *reader,
00494 TMR_ReadExceptionListenerBlock *b)
00495 {
00496 #ifndef SINGLE_THREAD_ASYNC_READ
00497 if (0 != pthread_mutex_lock(&reader->listenerLock))
00498 return TMR_ERROR_TRYAGAIN;
00499 #endif
00500 b->next = reader->readExceptionListeners;
00501 reader->readExceptionListeners = b;
00502
00503 #ifndef SINGLE_THREAD_ASYNC_READ
00504 pthread_mutex_unlock(&reader->listenerLock);
00505 #endif
00506 return TMR_SUCCESS;
00507 }
00508
00509 #ifdef TMR_ENABLE_BACKGROUND_READS
00510 TMR_Status
00511 TMR_removeReadExceptionListener(TMR_Reader *reader,
00512 TMR_ReadExceptionListenerBlock *b)
00513 {
00514 TMR_ReadExceptionListenerBlock *block, **prev;
00515
00516 if (0 != pthread_mutex_lock(&reader->listenerLock))
00517 return TMR_ERROR_TRYAGAIN;
00518
00519 prev = &reader->readExceptionListeners;
00520 block = reader->readExceptionListeners;
00521 while (NULL != block)
00522 {
00523 if (block == b)
00524 {
00525 *prev = block->next;
00526 break;
00527 }
00528 prev = &block->next;
00529 block = block->next;
00530 }
00531
00532 pthread_mutex_unlock(&reader->listenerLock);
00533
00534 if (block == NULL)
00535 {
00536 return TMR_ERROR_INVALID;
00537 }
00538
00539 return TMR_SUCCESS;
00540 }
00541 #endif
00542
00543 void
00544 notify_exception_listeners(TMR_Reader *reader, TMR_Status status)
00545 {
00546 TMR_ReadExceptionListenerBlock *relb;
00547
00548 if (NULL != reader)
00549 {
00550 #ifndef SINGLE_THREAD_ASYNC_READ
00551 pthread_mutex_lock(&reader->listenerLock);
00552 #endif
00553 relb = reader->readExceptionListeners;
00554 while (relb)
00555 {
00556 relb->listener(reader, status, relb->cookie);
00557 relb = relb->next;
00558 }
00559 #ifndef SINGLE_THREAD_ASYNC_READ
00560 pthread_mutex_unlock(&reader->listenerLock);
00561 #endif
00562 }
00563 }
00564
00565 #ifdef TMR_ENABLE_BACKGROUND_READS
00566 TMR_Queue_tagReads *
00567 dequeue(TMR_Reader *reader)
00568 {
00569 TMR_Queue_tagReads *tagRead = NULL;
00570 pthread_mutex_lock(&reader->queue_lock);
00571 if (NULL != reader->tagQueueHead)
00572 {
00573
00574 tagRead = reader->tagQueueHead;
00575 reader->tagQueueHead = reader->tagQueueHead->next;
00576 }
00577 reader->queue_depth --;
00578 pthread_mutex_unlock(&reader->queue_lock);
00579 return(tagRead);
00580 }
00581
00582
00583 void enqueue(TMR_Reader *reader, TMR_Queue_tagReads *tagRead)
00584 {
00585 pthread_mutex_lock(&reader->queue_lock);
00586 if (NULL == reader->tagQueueHead)
00587 {
00588
00589 reader->tagQueueHead = tagRead;
00590 reader->tagQueueHead->next = NULL;
00591 reader->tagQueueTail = reader->tagQueueHead;
00592 }
00593 else
00594 {
00595 reader->tagQueueTail->next = tagRead;
00596 reader->tagQueueTail = tagRead;
00597 tagRead->next = NULL;
00598 }
00599 reader->queue_depth ++;
00600 pthread_mutex_unlock(&reader->queue_lock);
00601 }
00602
00603 static void *
00604 parse_tag_reads(void *arg)
00605 {
00606 TMR_Reader *reader;
00607 TMR_Queue_tagReads *tagRead;
00608 reader = arg;
00609
00610 while (1)
00611 {
00612 pthread_mutex_lock(&reader->parserLock);
00613 reader->parserRunning = false;
00614 pthread_cond_broadcast(&reader->parserCond);
00615 while (false == reader->parserEnabled)
00616 {
00617 pthread_cond_wait(&reader->parserCond, &reader->parserLock);
00618 }
00619
00620 reader->parserRunning = true;
00621 pthread_mutex_unlock(&reader->parserLock);
00622
00627 sem_wait(&reader->queue_length);
00628
00629 if (NULL != reader->tagQueueHead)
00630 {
00635 tagRead = dequeue(reader);
00636 if (false == tagRead->isStatusResponse)
00637 {
00638
00639
00640 #ifdef TMR_ENABLE_SERIAL_READER
00641 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00642 {
00647 notify_read_listeners(reader, &tagRead->trd);
00648 }
00649 #endif
00650 #ifdef TMR_ENABLE_LLRP_READER
00651 if (TMR_READER_TYPE_LLRP == reader->readerType)
00652 {
00653
00654 LLRP_tSRO_ACCESS_REPORT *pReport;
00655 LLRP_tSTagReportData *pTagReportData;
00656
00657 pReport = (LLRP_tSRO_ACCESS_REPORT *)tagRead->tagEntry.lMsg;
00658
00659 for(pTagReportData = pReport->listTagReportData;
00660 NULL != pTagReportData;
00661 pTagReportData = (LLRP_tSTagReportData *)pTagReportData->hdr.pNextSubParameter)
00662 {
00663 TMR_TagReadData trd;
00664
00665 TMR_TRD_init(&trd);
00666 TMR_LLRP_parseMetadataFromMessage(reader, &trd, pTagReportData);
00667
00668 trd.reader = reader;
00669 notify_read_listeners(reader, &trd);
00670 }
00671 }
00672 #endif
00673 }
00674 else
00675 {
00676
00677
00678 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00679 {
00680 TMR_Reader_StatsValues stats;
00681 uint8_t offset, i,j;
00682 uint16_t flags = 0;
00683
00684 TMR_STATS_init(&stats);
00685 offset = tagRead->bufPointer;
00686
00687 if (NULL != reader->statusListeners && NULL== reader->statsListeners)
00688 {
00689
00690 TMR_StatusListenerBlock *slb;
00691 uint8_t index = 0, j;
00692 TMR_SR_StatusReport report[TMR_SR_STATUS_MAX];
00693
00694
00695
00696 flags = GETU16(tagRead->tagEntry.sMsg, offset);
00697
00698 if (0 != (flags & TMR_SR_STATUS_FREQUENCY))
00699 {
00700 report[index].type = TMR_SR_STATUS_FREQUENCY;
00701 report[index].u.fsr.freq = (uint32_t)(GETU24(tagRead->tagEntry.sMsg, offset));
00702 index ++;
00703 }
00704 if (0 != (flags & TMR_SR_STATUS_TEMPERATURE))
00705 {
00706 report[index].type = TMR_SR_STATUS_TEMPERATURE;
00707 report[index].u.tsr.temp = GETU8(tagRead->tagEntry.sMsg, offset);
00708 index ++;
00709 }
00710 if (0 != (flags & TMR_SR_STATUS_ANTENNA))
00711 {
00712 uint8_t tx, rx;
00713 report[index].type = TMR_SR_STATUS_ANTENNA;
00714 tx = GETU8(tagRead->tagEntry.sMsg, offset);
00715 rx = GETU8(tagRead->tagEntry.sMsg, offset);
00716
00717 for (j = 0; j < reader->u.serialReader.txRxMap->len; j++)
00718 {
00719 if ((rx == reader->u.serialReader.txRxMap->list[j].rxPort) && (tx == reader->u.serialReader.txRxMap->list[j].txPort))
00720 {
00721 report[index].u.asr.ant = reader->u.serialReader.txRxMap->list[j].antenna;
00722 break;
00723 }
00724 }
00725 index ++;
00726 }
00727
00728 report[index].type = TMR_SR_STATUS_NONE;
00729
00730 pthread_mutex_lock(&reader->listenerLock);
00731 slb = reader->statusListeners;
00732 while (slb)
00733 {
00734 slb->listener(reader, report, slb->cookie);
00735 slb = slb->next;
00736 }
00737 pthread_mutex_unlock(&reader->listenerLock);
00738
00739 }
00740 else if (NULL != reader->statsListeners && NULL== reader->statusListeners)
00741 {
00742
00743 if ((0x80) > reader->statsFlag)
00744 {
00745 offset += 1;
00746 }
00747 else
00748 {
00749 offset += 2;
00750 }
00751
00756 for (i = 0; i < stats.perAntenna.max; i++)
00757 {
00758 stats.perAntenna.list[i].antenna = 0;
00759 stats.perAntenna.list[i].rfOnTime = 0;
00760 stats.perAntenna.list[i].noiseFloor = 0;
00761 }
00762
00763 TMR_fillReaderStats(reader, &stats, flags, tagRead->tagEntry.sMsg, offset);
00764
00770 for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)
00771 {
00772 if (!stats.perAntenna.list[i].antenna)
00773 {
00774 for (j = i + 1; j < reader->u.serialReader.txRxMap->len; j++)
00775 {
00776 if (stats.perAntenna.list[j].antenna)
00777 {
00778 stats.perAntenna.list[i].antenna = stats.perAntenna.list[j].antenna;
00779 stats.perAntenna.list[i].rfOnTime = stats.perAntenna.list[j].rfOnTime;
00780 stats.perAntenna.list[i].noiseFloor = stats.perAntenna.list[j].noiseFloor;
00781 stats.perAntenna.list[j].antenna = 0;
00782 stats.perAntenna.list[j].rfOnTime = 0;
00783 stats.perAntenna.list[j].noiseFloor = 0;
00784
00785 stats.perAntenna.len++;
00786 break;
00787 }
00788 }
00789 }
00790 else
00791 {
00792
00793 stats.perAntenna.len++;
00794 }
00795 }
00796
00797
00798 stats.valid = reader->statsFlag;
00799
00800
00801 notify_stats_listeners(reader, &stats);
00802 }
00803 else
00804 {
00809 TMR_Status ret;
00810 ret = TMR_ERROR_UNSUPPORTED;
00811 notify_exception_listeners(reader, ret);
00812 }
00813 }
00814 #ifdef TMR_ENABLE_LLRP_READER
00815 else
00816 {
00821 }
00822 #endif
00823 }
00824
00825
00826 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00827 {
00828 free(tagRead->tagEntry.sMsg);
00829 }
00830 #ifdef TMR_ENABLE_LLRP_READER
00831 else
00832 {
00833 TMR_LLRP_freeMessage(tagRead->tagEntry.lMsg);
00834 }
00835 #endif
00836 free(tagRead);
00837
00838
00839 sem_post(&reader->queue_slots);
00840 }
00841 }
00842 return NULL;
00843 }
00844
00845
00846 static void
00847 process_async_response(TMR_Reader *reader)
00848 {
00849 TMR_Queue_tagReads *tagRead;
00850 uint16_t flags = 0;
00851
00852
00853 sem_wait(&reader->queue_slots);
00854
00855 tagRead = (TMR_Queue_tagReads *) malloc(sizeof(TMR_Queue_tagReads));
00856 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00857 {
00858 tagRead->tagEntry.sMsg = (uint8_t *) malloc(TMR_SR_MAX_PACKET_SIZE);
00859 memcpy(tagRead->tagEntry.sMsg, reader->u.serialReader.bufResponse, TMR_SR_MAX_PACKET_SIZE);
00860 tagRead->bufPointer = reader->u.serialReader.bufPointer;
00861 }
00862 #ifdef TMR_ENABLE_LLRP_READER
00863 else
00864 {
00865 tagRead->tagEntry.lMsg = reader->u.llrpReader.bufResponse[0];
00866 reader->u.llrpReader.bufResponse[0] = NULL;
00867 }
00868 #endif
00869
00870 tagRead->isStatusResponse = reader->isStatusResponse;
00875 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00876 {
00877 if (false == tagRead->isStatusResponse)
00878 {
00879 TMR_TRD_init(&tagRead->trd);
00880 flags = GETU16AT(tagRead->tagEntry.sMsg, 8);
00881 TMR_SR_parseMetadataFromMessage(reader, &tagRead->trd, flags, &tagRead->bufPointer, tagRead->tagEntry.sMsg);
00882 TMR_SR_postprocessReaderSpecificMetadata(&tagRead->trd, &reader->u.serialReader);
00883 tagRead->trd.reader = reader;
00884 }
00885 }
00886
00887
00888 enqueue(reader, tagRead);
00889
00890 sem_post(&reader->queue_length);
00891
00892 if ((false == reader->isStatusResponse) && (TMR_READER_TYPE_SERIAL == reader->readerType))
00893 {
00894 reader->u.serialReader.tagsRemainingInBuffer--;
00895 }
00896 }
00897
00898 static void *
00899 do_background_reads(void *arg)
00900 {
00901 TMR_Status ret;
00902 TMR_Reader *reader;
00903 uint32_t onTime, offTime;
00904 int32_t sleepTime;
00905 uint64_t end, now, difftime;
00906
00907 reader = arg;
00908 reader->trueAsyncflag = false;
00909
00910 TMR_paramGet(reader, TMR_PARAM_READ_ASYNCOFFTIME, &offTime);
00911
00912 while (1)
00913 {
00914
00915 pthread_mutex_lock(&reader->backgroundLock);
00916 reader->backgroundRunning = false;
00917
00918 pthread_cond_broadcast(&reader->backgroundCond);
00919 while (false == reader->backgroundEnabled)
00920 {
00921 reader->trueAsyncflag = false;
00922 pthread_cond_wait(&reader->backgroundCond, &reader->backgroundLock);
00923 if (true == reader->backgroundThreadCancel)
00924 {
00929 goto EXIT;
00930 }
00931 }
00932
00933 TMR_paramGet(reader, TMR_PARAM_READ_ASYNCONTIME, &onTime);
00934
00935 if (!reader->trueAsyncflag)
00936 {
00937 ret = TMR_read(reader, onTime, NULL);
00938 if (TMR_SUCCESS != ret)
00939 {
00940 if ((TMR_ERROR_TIMEOUT == ret) || (TMR_ERROR_CRC_ERROR == ret) ||
00941 (TMR_ERROR_SYSTEM_UNKNOWN_ERROR == ret) || (TMR_ERROR_TM_ASSERT_FAILED == ret))
00942 {
00943 if (TMR_READER_TYPE_SERIAL == reader->readerType)
00944 {
00945 reader->u.serialReader.transport.flush(&reader->u.serialReader.transport);
00946 }
00947 reader->backgroundEnabled = false;
00948 }
00949
00956 if (((TMR_ERROR_HIGH_RETURN_LOSS == ret) || (TMR_ERROR_NO_ANTENNA == ret))
00957 &&
00958 ((TMR_SR_MODEL_M6E != reader->u.serialReader.versionInfo.hardware[0]) &&
00959 (TMR_SR_MODEL_MICRO != reader->u.serialReader.versionInfo.hardware[0]) &&
00960 (TMR_SR_MODEL_M6E_NANO != reader->u.serialReader.versionInfo.hardware[0]) &&
00961 (TMR_SR_MODEL_M6E_I != reader->u.serialReader.versionInfo.hardware[0])))
00962 {
00963 reader->backgroundEnabled = false;
00964 reader->readState = TMR_READ_STATE_DONE;
00965 pthread_mutex_unlock(&reader->backgroundLock);
00966 notify_exception_listeners(reader, ret);
00967 break;
00968 }
00969
00970 notify_exception_listeners(reader, ret);
00971 if(false == reader->searchStatus)
00972 {
00979 reader->readState = TMR_READ_STATE_STARTED;
00980 pthread_cond_broadcast(&reader->readCond);
00981 reader->backgroundEnabled = false;
00982 }
00983 pthread_mutex_unlock(&reader->backgroundLock);
00984 continue;
00985 }
00986 if(reader->continuousReading)
00987 {
00992 reader->trueAsyncflag = true;
00993 }
00994
00998 reader->readState = TMR_READ_STATE_ACTIVE;
00999 pthread_cond_broadcast(&reader->readCond);
01000 }
01001
01002 reader->backgroundRunning = true;
01003 pthread_mutex_unlock(&reader->backgroundLock);
01004
01005 if (true == reader->continuousReading)
01006 {
01011
01012 while (true)
01013 {
01014 if (TMR_READER_TYPE_SERIAL == reader->readerType)
01015 {
01016 if (false == reader->u.serialReader.isBasetimeUpdated)
01017 {
01018
01019 TMR_SR_updateBaseTimeStamp(reader);
01020 reader->u.serialReader.isBasetimeUpdated = true;
01021 }
01022 }
01023 ret = TMR_hasMoreTags(reader);
01024 if (TMR_SUCCESS == ret)
01025 {
01026
01027
01028
01029
01030 if (TMR_READER_TYPE_SERIAL == reader->readerType)
01031 {
01032 int slotsFree = 0;
01033 int semret;
01034
01035 semret = sem_getvalue(&reader->queue_slots, &slotsFree);
01036 if (0 == semret)
01037 {
01038 if (10 > slotsFree)
01039 {
01040 tmr_sleep(20);
01041 }
01042 if (0 >= slotsFree)
01043 {
01044
01045
01046
01047
01048
01049
01050 if (true == reader->searchStatus)
01051 {
01052 isBufferOverFlow = true;
01053 ret = TMR_ERROR_BUFFER_OVERFLOW;
01054 notify_exception_listeners(reader, ret);
01055 ret = verifySearchStatus(reader);
01056
01057
01058
01059
01060
01061
01062
01063
01064 while(slotsFree < TMR_MAX_QUEUE_SLOTS)
01065 {
01066 tmr_sleep(20);
01067 semret = sem_getvalue(&reader->queue_slots, &slotsFree);
01068 }
01069 reader->trueAsyncflag = false;
01070 break;
01071 }
01072 }
01073 }
01074 }
01075
01076
01077 process_async_response(reader);
01078 }
01079 else if (TMR_ERROR_CRC_ERROR == ret)
01080 {
01081
01082
01083
01084
01085
01086 notify_exception_listeners(reader, ret);
01087 }
01088 else if (TMR_ERROR_TAG_ID_BUFFER_FULL == ret)
01089 {
01090
01091 notify_exception_listeners(reader, ret);
01092
01097 if (true == reader->searchStatus)
01098 {
01104 ret = TMR_hasMoreTags(reader);
01105 reader->trueAsyncflag = false;
01106 break;
01107 }
01108 }
01109 else
01110 {
01111 if ((TMR_ERROR_TIMEOUT == ret) || (TMR_ERROR_SYSTEM_UNKNOWN_ERROR == ret) ||
01112 (TMR_ERROR_TM_ASSERT_FAILED == ret) || (TMR_ERROR_LLRP_READER_CONNECTION_LOST == ret))
01113 {
01114 notify_exception_listeners(reader, ret);
01119 if (TMR_READER_TYPE_SERIAL == reader->readerType)
01120 {
01121
01122 reader->u.serialReader.transport.flush(&reader->u.serialReader.transport);
01123 }
01124
01129 if (!reader->finishedReading)
01130 {
01131 reader->cmdStopReading(reader);
01132 }
01133
01134 pthread_mutex_lock(&reader->backgroundLock);
01135 reader->backgroundEnabled = false;
01136 reader->readState = TMR_READ_STATE_DONE;
01137 pthread_cond_broadcast(&reader->readCond);
01138 pthread_mutex_unlock(&reader->backgroundLock);
01139
01140
01147 reader->searchStatus = false;
01148 reset_continuous_reading(reader, true);
01149 }
01150 else if (TMR_ERROR_END_OF_READING == ret)
01151 {
01152 while(0 < reader->queue_depth)
01153 {
01160 tmr_sleep(5);
01161 }
01162
01167 pthread_mutex_lock(&reader->backgroundLock);
01168 reader->backgroundEnabled = false;
01169 reader->readState = TMR_READ_STATE_DONE;
01170 pthread_cond_broadcast(&reader->readCond);
01171 pthread_mutex_unlock(&reader->backgroundLock);
01172 break;
01173 }
01174 else if ((TMR_ERROR_NO_TAGS_FOUND != ret) && (TMR_ERROR_NO_TAGS != ret) && (TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST != ret) && (TMR_ERROR_TOO_BIG != ret))
01175 {
01176
01177 notify_exception_listeners(reader, ret);
01178 }
01179 break;
01180 }
01181 }
01182 }
01183 else
01184 {
01192 end = tmr_gettime();
01193
01194 while (TMR_SUCCESS == TMR_hasMoreTags(reader))
01195 {
01196 TMR_TagReadData trd;
01197 TMR_ReadListenerBlock *rlb;
01198
01199 TMR_TRD_init(&trd);
01200
01201 ret = TMR_getNextTag(reader, &trd);
01202 if (TMR_SUCCESS != ret)
01203 {
01204 pthread_mutex_lock(&reader->backgroundLock);
01205 reader->backgroundEnabled = false;
01206 pthread_mutex_unlock(&reader->backgroundLock);
01207 notify_exception_listeners(reader, ret);
01208 break;
01209 }
01210
01211 pthread_mutex_lock(&reader->listenerLock);
01212 rlb = reader->readListeners;
01213 while (rlb)
01214 {
01215 rlb->listener(reader, &trd, rlb->cookie);
01216 rlb = rlb->next;
01217 }
01218 pthread_mutex_unlock(&reader->listenerLock);
01219 }
01220
01221
01222 now = tmr_gettime();
01223 difftime = now - end;
01224
01225 sleepTime = offTime - (uint32_t)difftime;
01226 if(sleepTime > 0)
01227 {
01228 tmr_sleep(sleepTime);
01229 }
01230 }
01231 EXIT:
01232 if (reader->backgroundThreadCancel)
01233 {
01237 pthread_exit(NULL);
01238 }
01239 }
01240 return NULL;
01241 }
01242 #endif
01243
01244 TMR_Status
01245 TMR_addReadListener(TMR_Reader *reader, TMR_ReadListenerBlock *b)
01246 {
01247 #ifndef SINGLE_THREAD_ASYNC_READ
01248 if (0 != pthread_mutex_lock(&reader->listenerLock))
01249 return TMR_ERROR_TRYAGAIN;
01250 #endif
01251 b->next = reader->readListeners;
01252 reader->readListeners = b;
01253 #ifndef SINGLE_THREAD_ASYNC_READ
01254 pthread_mutex_unlock(&reader->listenerLock);
01255 #endif
01256 return TMR_SUCCESS;
01257 }
01258 #ifdef TMR_ENABLE_BACKGROUND_READS
01259
01260 TMR_Status
01261 TMR_removeReadListener(TMR_Reader *reader, TMR_ReadListenerBlock *b)
01262 {
01263 TMR_ReadListenerBlock *block, **prev;
01264
01265 if (0 != pthread_mutex_lock(&reader->listenerLock))
01266 return TMR_ERROR_TRYAGAIN;
01267
01268 prev = &reader->readListeners;
01269 block = reader->readListeners;
01270 while (NULL != block)
01271 {
01272 if (block == b)
01273 {
01274 *prev = block->next;
01275 break;
01276 }
01277 prev = &block->next;
01278 block = block->next;
01279 }
01280
01281 pthread_mutex_unlock(&reader->listenerLock);
01282
01283 if (block == NULL)
01284 {
01285 return TMR_ERROR_INVALID;
01286 }
01287
01288 return TMR_SUCCESS;
01289 }
01290
01291
01292 TMR_Status
01293 TMR_addAuthReqListener(TMR_Reader *reader, TMR_AuthReqListenerBlock *b)
01294 {
01295
01296 if (0 != pthread_mutex_lock(&reader->listenerLock))
01297 return TMR_ERROR_TRYAGAIN;
01298
01299 b->next = reader->authReqListeners;
01300 reader->authReqListeners = b;
01301
01302 pthread_mutex_unlock(&reader->listenerLock);
01303
01304 return TMR_SUCCESS;
01305 }
01306
01307
01308 TMR_Status
01309 TMR_removeAuthReqListener(TMR_Reader *reader, TMR_AuthReqListenerBlock *b)
01310 {
01311 TMR_AuthReqListenerBlock *block, **prev;
01312
01313 if (0 != pthread_mutex_lock(&reader->listenerLock))
01314 return TMR_ERROR_TRYAGAIN;
01315
01316 prev = &reader->authReqListeners;
01317 block = reader->authReqListeners;
01318 while (NULL != block)
01319 {
01320 if (block == b)
01321 {
01322 *prev = block->next;
01323 break;
01324 }
01325 prev = &block->next;
01326 block = block->next;
01327 }
01328
01329 pthread_mutex_unlock(&reader->listenerLock);
01330
01331 if (block == NULL)
01332 {
01333 return TMR_ERROR_INVALID;
01334 }
01335
01336 return TMR_SUCCESS;
01337 }
01338
01339 TMR_Status
01340 TMR_addStatusListener(TMR_Reader *reader, TMR_StatusListenerBlock *b)
01341 {
01342
01343 if (0 != pthread_mutex_lock(&reader->listenerLock))
01344 return TMR_ERROR_TRYAGAIN;
01345
01346 b->next = reader->statusListeners;
01347 reader->statusListeners = b;
01348
01349
01350
01351 pthread_mutex_unlock(&reader->listenerLock);
01352
01353 return TMR_SUCCESS;
01354 }
01355 #endif
01356
01357 TMR_Status
01358 TMR_addStatsListener(TMR_Reader *reader, TMR_StatsListenerBlock *b)
01359 {
01360 #ifndef SINGLE_THREAD_ASYNC_READ
01361 if (0 != pthread_mutex_lock(&reader->listenerLock))
01362 return TMR_ERROR_TRYAGAIN;
01363 #endif
01364 b->next = reader->statsListeners;
01365 reader->statsListeners = b;
01366
01367
01368 #ifndef SINGLE_THREAD_ASYNC_READ
01369 pthread_mutex_unlock(&reader->listenerLock);
01370 #endif
01371 return TMR_SUCCESS;
01372 }
01373 #ifdef TMR_ENABLE_BACKGROUND_READS
01374
01375 TMR_Status
01376 TMR_removeStatsListener(TMR_Reader *reader, TMR_StatsListenerBlock *b)
01377 {
01378 TMR_StatsListenerBlock *block, **prev;
01379
01380 if (0 != pthread_mutex_lock(&reader->listenerLock))
01381 return TMR_ERROR_TRYAGAIN;
01382
01383 prev = &reader->statsListeners;
01384 block = reader->statsListeners;
01385 while (NULL != block)
01386 {
01387 if (block == b)
01388 {
01389 *prev = block->next;
01390 break;
01391 }
01392 prev = &block->next;
01393 block = block->next;
01394 }
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 pthread_mutex_unlock(&reader->listenerLock);
01409
01410 if (block == NULL)
01411 {
01412 return TMR_ERROR_INVALID;
01413 }
01414
01415 return TMR_SUCCESS;
01416 }
01417
01418 TMR_Status
01419 TMR_removeStatusListener(TMR_Reader *reader, TMR_StatusListenerBlock *b)
01420 {
01421 TMR_StatusListenerBlock *block, **prev;
01422
01423 if (0 != pthread_mutex_lock(&reader->listenerLock))
01424 return TMR_ERROR_TRYAGAIN;
01425
01426 prev = &reader->statusListeners;
01427 block = reader->statusListeners;
01428 while (NULL != block)
01429 {
01430 if (block == b)
01431 {
01432 *prev = block->next;
01433 break;
01434 }
01435 prev = &block->next;
01436 block = block->next;
01437 }
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451 pthread_mutex_unlock(&reader->listenerLock);
01452
01453 if (block == NULL)
01454 {
01455 return TMR_ERROR_INVALID;
01456 }
01457
01458 return TMR_SUCCESS;
01459 }
01460
01461 void cleanup_background_threads(TMR_Reader *reader)
01462 {
01463 if (NULL != reader)
01464 {
01465 pthread_mutex_lock(&reader->backgroundLock);
01466 pthread_mutex_lock(&reader->listenerLock);
01467 reader->readExceptionListeners = NULL;
01468 reader->statsListeners = NULL;
01469 if (true == reader->backgroundSetup)
01470 {
01475 reader->backgroundThreadCancel = true;
01476 pthread_cond_broadcast(&reader->backgroundCond);
01477 }
01478 pthread_mutex_unlock(&reader->listenerLock);
01479 pthread_mutex_unlock(&reader->backgroundLock);
01480
01481 if (true == reader->backgroundSetup)
01482 {
01486 pthread_join(reader->backgroundReader, NULL);
01487 }
01488
01489 pthread_mutex_lock(&reader->parserLock);
01490 pthread_mutex_lock(&reader->listenerLock);
01491 reader->readListeners = NULL;
01492 if (true == reader->parserSetup)
01493 {
01494 pthread_cancel(reader->backgroundParser);
01495 }
01496 pthread_mutex_unlock(&reader->listenerLock);
01497 pthread_mutex_unlock(&reader->parserLock);
01498 }
01499 }
01500
01501 void*
01502 do_background_receiveAutonomousReading(void * arg)
01503 {
01504 TMR_Status ret;
01505 TMR_TagReadData trd;
01506 TMR_Reader *reader;
01507 TMR_Reader_StatsValues stats;
01508
01509 reader = arg;
01510 TMR_TRD_init(&trd);
01511
01512 while (1)
01513 {
01514 ret = TMR_SR_receiveAutonomousReading(reader, &trd, &stats);
01515 if (TMR_SUCCESS == ret)
01516 {
01517 if (false == reader->isStatusResponse)
01518 {
01519
01520 notify_read_listeners(reader, &trd);
01521 }
01522 else
01523 {
01524 notify_stats_listeners(reader, &stats);
01525 }
01526 }
01527 }
01528 return NULL;
01529 }
01530 #endif
01531