00001
00007 #include <tm_reader.h>
00008 #include <time.h>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <stdarg.h>
00012 #include <string.h>
00013 #include <inttypes.h>
00014
00015 #ifndef BARE_METAL
00016 #if WIN32
00017 #define snprintf sprintf_s
00018 #endif
00019
00020
00021 #ifndef USE_TRANSPORT_LISTENER
00022 #define USE_TRANSPORT_LISTENER 0
00023 #endif
00024 #define PRINT_TAG_METADATA 0
00025 #define numberof(x) (sizeof((x))/sizeof((x)[0]))
00026
00027 #define usage() {errx(1, "read readerURL [--ant antenna_list] [--pow read_power]\n"\
00028 "Please provide reader URL, such as:\n"\
00029 "tmr:///com4 or tmr:///com4 --ant 1,2 --pow 2300\n"\
00030 "tmr://my-reader.example.com or tmr://my-reader.example.com --ant 1,2 --pow 2300\n"\
00031 );}
00032
00033 void errx(int exitval, const char *fmt, ...)
00034 {
00035 va_list ap;
00036
00037 va_start(ap, fmt);
00038 vfprintf(stderr, fmt, ap);
00039
00040 exit(exitval);
00041 }
00042
00043 void checkerr(TMR_Reader* rp, TMR_Status ret, int exitval, const char *msg)
00044 {
00045 if (TMR_SUCCESS != ret)
00046 {
00047 errx(exitval, "Error %s: %s\n", msg, TMR_strerr(rp, ret));
00048 }
00049 }
00050
00051 void serialPrinter(bool tx, uint32_t dataLen, const uint8_t data[],
00052 uint32_t timeout, void *cookie)
00053 {
00054 FILE *out = cookie;
00055 uint32_t i;
00056
00057 fprintf(out, "%s", tx ? "Sending: " : "Received:");
00058 for (i = 0; i < dataLen; i++)
00059 {
00060 if (i > 0 && (i & 15) == 0)
00061 {
00062 fprintf(out, "\n ");
00063 }
00064 fprintf(out, " %02x", data[i]);
00065 }
00066 fprintf(out, "\n");
00067 }
00068
00069 void stringPrinter(bool tx,uint32_t dataLen, const uint8_t data[],uint32_t timeout, void *cookie)
00070 {
00071 FILE *out = cookie;
00072
00073 fprintf(out, "%s", tx ? "Sending: " : "Received:");
00074 fprintf(out, "%s\n", data);
00075 }
00076
00077 void parseAntennaList(uint8_t *antenna, uint8_t *antennaCount, char *args)
00078 {
00079 char *token = NULL;
00080 char *str = ",";
00081 uint8_t i = 0x00;
00082 int scans;
00083
00084
00085 if (NULL == args)
00086 {
00087 fprintf(stdout, "Missing argument\n");
00088 usage();
00089 }
00090
00091 token = strtok(args, str);
00092 if (NULL == token)
00093 {
00094 fprintf(stdout, "Missing argument after %s\n", args);
00095 usage();
00096 }
00097
00098 while(NULL != token)
00099 {
00100 scans = sscanf(token, "%"SCNu8, &antenna[i]);
00101 if (1 != scans)
00102 {
00103 fprintf(stdout, "Can't parse '%s' as an 8-bit unsigned integer value\n", token);
00104 usage();
00105 }
00106 i++;
00107 token = strtok(NULL, str);
00108 }
00109 *antennaCount = i;
00110 }
00111 #endif
00112
00113 int main(int argc, char *argv[])
00114 {
00115 TMR_Reader r, *rp;
00116 TMR_Status ret;
00117 TMR_ReadPlan plan;
00118 TMR_Region region;
00119 uint8_t *antennaList = NULL;
00120 #define READPOWER_NULL (-12345)
00121 int readpower = READPOWER_NULL;
00122 uint8_t buffer[20];
00123 uint8_t i;
00124 uint8_t antennaCount = 0x0;
00125 TMR_String model;
00126 char str[64];
00127 TMR_TRD_MetadataFlag metadata = TMR_TRD_METADATA_FLAG_ALL;
00128
00129 #ifndef BARE_METAL
00130 #if USE_TRANSPORT_LISTENER
00131 TMR_TransportListenerBlock tb;
00132 #endif
00133
00134 if (argc < 2)
00135 {
00136 fprintf(stdout, "Not enough arguments. Please provide reader URL.\n");
00137 usage();
00138 }
00139
00140 for (i = 2; i < argc; i+=2)
00141 {
00142 if(0x00 == strcmp("--ant", argv[i]))
00143 {
00144 if (NULL != antennaList)
00145 {
00146 fprintf(stdout, "Duplicate argument: --ant specified more than once\n");
00147 usage();
00148 }
00149 parseAntennaList(buffer, &antennaCount, argv[i+1]);
00150 antennaList = buffer;
00151 }
00152 else if (0 == strcmp("--pow", argv[i]))
00153 {
00154 long retval;
00155 char *startptr;
00156 char *endptr;
00157 startptr = argv[i+1];
00158 retval = strtol(startptr, &endptr, 0);
00159 if (endptr != startptr)
00160 {
00161 readpower = retval;
00162 fprintf(stdout, "Requested read power: %d cdBm\n", readpower);
00163 }
00164 else
00165 {
00166 fprintf(stdout, "Can't parse read power: %s\n", argv[i+1]);
00167 }
00168 }
00169 else
00170 {
00171 fprintf(stdout, "Argument %s is not recognized\n", argv[i]);
00172 usage();
00173 }
00174 }
00175 #endif
00176
00177 rp = &r;
00178 #ifndef BARE_METAL
00179 ret = TMR_create(rp, argv[1]);
00180 #else
00181 ret = TMR_create(rp, "tmr:///com1");
00182 buffer[0] = 1;
00183 antennaList = buffer;
00184 antennaCount = 0x01;
00185 #endif
00186
00187 #ifndef BARE_METAL
00188 checkerr(rp, ret, 1, "creating reader");
00189
00190 #if USE_TRANSPORT_LISTENER
00191
00192 if (TMR_READER_TYPE_SERIAL == rp->readerType)
00193 {
00194 tb.listener = serialPrinter;
00195 }
00196 else
00197 {
00198 tb.listener = stringPrinter;
00199 }
00200 tb.cookie = stdout;
00201
00202 TMR_addTransportListener(rp, &tb);
00203 #endif
00204 #endif
00205
00206 ret = TMR_connect(rp);
00207
00208 #ifndef BARE_METAL
00209 checkerr(rp, ret, 1, "connecting reader");
00210 #endif
00211 region = TMR_REGION_NONE;
00212 ret = TMR_paramGet(rp, TMR_PARAM_REGION_ID, ®ion);
00213 #ifndef BARE_METAL
00214 checkerr(rp, ret, 1, "getting region");
00215 #endif
00216
00217 if (TMR_REGION_NONE == region)
00218 {
00219 TMR_RegionList regions;
00220 TMR_Region _regionStore[32];
00221 regions.list = _regionStore;
00222 regions.max = sizeof(_regionStore)/sizeof(_regionStore[0]);
00223 regions.len = 0;
00224
00225 ret = TMR_paramGet(rp, TMR_PARAM_REGION_SUPPORTEDREGIONS, ®ions);
00226 #ifndef BARE_METAL
00227 checkerr(rp, ret, __LINE__, "getting supported regions");
00228
00229 if (regions.len < 1)
00230 {
00231 checkerr(rp, TMR_ERROR_INVALID_REGION, __LINE__, "Reader doesn't support any regions");
00232 }
00233 #endif
00234 region = regions.list[0];
00235 ret = TMR_paramSet(rp, TMR_PARAM_REGION_ID, ®ion);
00236 #ifndef BARE_METAL
00237 checkerr(rp, ret, 1, "setting region");
00238 #endif
00239 }
00240
00241 if (READPOWER_NULL != readpower)
00242 {
00243 int value;
00244
00245 ret = TMR_paramGet(rp, TMR_PARAM_RADIO_READPOWER, &value);
00246 #ifndef BARE_METAL
00247 checkerr(rp, ret, 1, "getting read power");
00248 printf("Old read power = %d dBm\n", value);
00249 #endif
00250 value = readpower;
00251 ret = TMR_paramSet(rp, TMR_PARAM_RADIO_READPOWER, &value);
00252 #ifndef BARE_METAL
00253 checkerr(rp, ret, 1, "setting read power");
00254 #endif
00255 }
00256
00257 {
00258 int value;
00259 ret = TMR_paramGet(rp, TMR_PARAM_RADIO_READPOWER, &value);
00260 #ifndef BARE_METAL
00261 checkerr(rp, ret, 1, "getting read power");
00262 printf("Read power = %d dBm\n", value);
00263 #endif
00264 }
00265
00266 model.value = str;
00267 model.max = 64;
00268 TMR_paramGet(rp, TMR_PARAM_VERSION_MODEL, &model);
00269 if (((0 == strcmp("Sargas", model.value)) || (0 == strcmp("M6e Micro", model.value)) ||(0 == strcmp("M6e Nano", model.value)))
00270 && (NULL == antennaList))
00271 {
00272 #ifndef BARE_METAL
00273 fprintf(stdout, "Reader doesn't support antenna detection. Please provide antenna list.\n");
00274 usage();
00275 #endif
00276 }
00277
00285 if (rp->readerType == TMR_READER_TYPE_SERIAL)
00286 {
00287
00288
00289 ret = TMR_paramSet(rp, TMR_PARAM_METADATAFLAG, &metadata);
00290 #ifndef BARE_METAL
00291 checkerr(rp, ret, 1, "Setting Metadata Flags");
00292 #endif
00293 }
00294
00295
00296 ret = TMR_RP_init_simple(&plan, antennaCount, antennaList, TMR_TAG_PROTOCOL_GEN2, 1000);
00297 #ifndef BARE_METAL
00298 checkerr(rp, ret, 1, "initializing the read plan");
00299 #endif
00300
00301
00302 ret = TMR_paramSet(rp, TMR_PARAM_READ_PLAN, &plan);
00303 #ifndef BARE_METAL
00304 checkerr(rp, ret, 1, "setting read plan");
00305 #endif
00306 ret = TMR_read(rp, 500, NULL);
00307
00308 #ifndef BARE_METAL
00309 if (TMR_ERROR_TAG_ID_BUFFER_FULL == ret)
00310 {
00311
00312
00313
00314 fprintf(stdout, "reading tags:%s\n", TMR_strerr(rp, ret));
00315 }
00316 else
00317 {
00318 checkerr(rp, ret, 1, "reading tags");
00319 }
00320 #endif
00321 while (TMR_SUCCESS == TMR_hasMoreTags(rp))
00322 {
00323 TMR_TagReadData trd;
00324 char epcStr[128];
00325 char timeStr[128];
00326
00327 ret = TMR_getNextTag(rp, &trd);
00328 #ifndef BARE_METAL
00329 checkerr(rp, ret, 1, "fetching tag");
00330 #endif
00331 TMR_bytesToHex(trd.tag.epc, trd.tag.epcByteCount, epcStr);
00332
00333 #ifndef BARE_METAL
00334 #ifdef WIN32
00335 {
00336 FILETIME ft, utc;
00337 SYSTEMTIME st;
00338 char* timeEnd;
00339 char* end;
00340
00341 utc.dwHighDateTime = trd.timestampHigh;
00342 utc.dwLowDateTime = trd.timestampLow;
00343
00344 FileTimeToLocalFileTime( &utc, &ft );
00345 FileTimeToSystemTime( &ft, &st );
00346 timeEnd = timeStr + sizeof(timeStr)/sizeof(timeStr[0]);
00347 end = timeStr;
00348 end += sprintf(end, "%d-%d-%d", st.wYear,st.wMonth,st.wDay);
00349 end += sprintf(end, "T%d:%d:%d %d", st.wHour,st.wMinute,st.wSecond, st.wMilliseconds);
00350 end += sprintf(end, ".%06d", trd.dspMicros);
00351 }
00352 #else
00353 {
00354 uint8_t shift;
00355 uint64_t timestamp;
00356 time_t seconds;
00357 int micros;
00358 char* timeEnd;
00359 char* end;
00360
00361 shift = 32;
00362 timestamp = ((uint64_t)trd.timestampHigh<<shift) | trd.timestampLow;
00363 seconds = timestamp / 1000;
00364 micros = (timestamp % 1000) * 1000;
00365
00366
00367
00368
00369
00370 micros -= trd.dspMicros / 1000;
00371 micros += trd.dspMicros;
00372
00373 timeEnd = timeStr + sizeof(timeStr)/sizeof(timeStr[0]);
00374 end = timeStr;
00375 end += strftime(end, timeEnd-end, "%FT%H:%M:%S", localtime(&seconds));
00376 end += snprintf(end, timeEnd-end, ".%06d", micros);
00377 end += strftime(end, timeEnd-end, "%z", localtime(&seconds));
00378 }
00379 #endif
00380
00381 printf("EPC:%s ", epcStr);
00382
00383 #if PRINT_TAG_METADATA
00384 {
00385 uint16_t j = 0;
00386 for (j = 0; j < 9; j++)
00387 {
00388 if ((TMR_TRD_MetadataFlag)trd.metadataFlags & (1<<j))
00389 {
00390 switch ((TMR_TRD_MetadataFlag)trd.metadataFlags & (1<<j))
00391 {
00392 case TMR_TRD_METADATA_FLAG_READCOUNT:
00393 printf("Read Count : %d ", trd.readCount);
00394 break;
00395 case TMR_TRD_METADATA_FLAG_RSSI:
00396 printf("RSSI : %d ", trd.rssi);
00397 break;
00398 case TMR_TRD_METADATA_FLAG_ANTENNAID:
00399 printf("Antenna ID : %d ", trd.antenna);
00400 break;
00401 case TMR_TRD_METADATA_FLAG_FREQUENCY:
00402 printf("Frequency : %d ", trd.frequency);
00403 break;
00404 case TMR_TRD_METADATA_FLAG_TIMESTAMP:
00405 printf("Timestamp : %s ", timeStr);
00406 break;
00407 case TMR_TRD_METADATA_FLAG_PHASE:
00408 printf("Phase : %d ", trd.phase);
00409 break;
00410 case TMR_TRD_METADATA_FLAG_PROTOCOL:
00411 printf("Protocol : %d ", trd.tag.protocol);
00412 break;
00413 case TMR_TRD_METADATA_FLAG_DATA:
00414
00415 if (0 < trd.data.len)
00416 {
00417 char dataStr[255];
00418 TMR_bytesToHex(trd.data.list, trd.data.len, dataStr);
00419 printf("Data(%d): %s\n", trd.data.len, dataStr);
00420 }
00421 break;
00422 case TMR_TRD_METADATA_FLAG_GPIO_STATUS:
00423 {
00424 TMR_GpioPin state[16];
00425 uint8_t i, stateCount = numberof(state);
00426 ret = TMR_gpiGet(rp, &stateCount, state);
00427 if (TMR_SUCCESS != ret)
00428 {
00429 fprintf(stdout, "Error reading GPIO pins:%s\n", TMR_strerr(rp, ret));
00430 return ret;
00431 }
00432 printf("GPIO stateCount: %d\n", stateCount);
00433 for (i = 0 ; i < stateCount ; i++)
00434 {
00435 printf("Pin %d: %s\n", state[i].id, state[i].high ? "High" : "Low");
00436 }
00437 }
00438 break;
00439 default:
00440 break;
00441 }
00442 }
00443 }
00444 }
00445 #endif
00446 printf ("\n");
00447 #endif
00448 }
00449
00450 TMR_destroy(rp);
00451 return 0;
00452 }