mercury-api-0.1.0.0: cbits/api/serial_reader.c
/**
* @file serial_reader.c
* @brief Mercury API - serial reader high level implementation
* @author Nathan Williams
* @date 10/28/2009
*/
/*
* Copyright (c) 2009 ThingMagic, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "tm_reader.h"
#include "serial_reader_imp.h"
#include "tmr_utils.h"
#include "osdep.h"
#define HASPORT(mask, port) ((1 << ((port)-1)) & (mask))
#define TMR_MAX_PROTOCOLS (32)
#ifdef TMR_ENABLE_SERIAL_READER
static TMR_Status
initTxRxMapFromPorts(TMR_Reader *reader)
{
TMR_Status ret;
TMR_SR_PortDetect ports[TMR_SR_MAX_ANTENNA_PORTS];
uint8_t i, numPorts;
TMR_SR_SerialReader *sr;
numPorts = numberof(ports);
sr = &reader->u.serialReader;
/* Need number of ports to set up Tx-Rx map */
ret = TMR_SR_cmdAntennaDetect(reader, &numPorts, ports);
if (TMR_SUCCESS != ret)
{
return ret;
}
sr->portMask = 0;
/* Modify TxRxMap according to reader product */
switch (sr->productId)
{
case 0x0001:
{
/* Ruggedized Reader (Tool Link, Vega) */
TMR_AntennaMap newMap[] = {{1,2,2}, {2,5,5}, {3,1,1}};
numPorts = 3;
for (i = 0; i < numPorts; i++)
{
sr->portMask |= 1 << (newMap[i].antenna - 1);
sr->staticTxRxMapData[i].antenna = newMap[i].antenna;
sr->staticTxRxMapData[i].rxPort = newMap[i].rxPort;
sr->staticTxRxMapData[i].txPort = newMap[i].txPort;
if (0 == reader->tagOpParams.antenna && ports[i].detected)
{
reader->tagOpParams.antenna = ports[i].port;
}
}
break;
}
case 0x0002:
/*
* USB Reader -- Default map is okay
* M5e-C only has 1 antenna port, anyway
*
* However, M6eMicro USB has 2 ports and no auto antenna detection,
* so manually limit to first port for now.
* TODO: Revisit if M6eMicro USB starts supporting port 2 in future.
* port for now.
*/
if ((TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) &&
(sr->versionInfo.hardware[3] == TMR_SR_MODEL_M6E_MICRO_USB))
{
numPorts = 1;
/* skip the antenna port 2 */
for (i = 0; i < numPorts; i++)
{
sr->portMask |= 1 << (ports[i].port - 1);
sr->staticTxRxMapData[i].antenna = ports[i].port;
sr->staticTxRxMapData[i].txPort = ports[i].port;
sr->staticTxRxMapData[i].rxPort = ports[i].port;
if (0 == reader->tagOpParams.antenna && ports[i].detected)
{
reader->tagOpParams.antenna = ports[i].port;
}
}
break;
}
default:
{
for (i = 0; i < numPorts; i++)
{
sr->portMask |= 1 << (ports[i].port - 1);
sr->staticTxRxMapData[i].antenna = ports[i].port;
sr->staticTxRxMapData[i].txPort = ports[i].port;
sr->staticTxRxMapData[i].rxPort = ports[i].port;
if (0 == reader->tagOpParams.antenna && ports[i].detected)
{
reader->tagOpParams.antenna = ports[i].port;
}
}
break;
}
}
sr->staticTxRxMap.max = TMR_SR_MAX_ANTENNA_PORTS;
sr->staticTxRxMap.len = numPorts;
sr->staticTxRxMap.list = sr->staticTxRxMapData;
sr->txRxMap = &sr->staticTxRxMap;
return TMR_SUCCESS;
}
static TMR_Status
TMR_SR_configPreamble(TMR_SR_SerialReader *sr)
{
TMR_Status ret = TMR_SUCCESS;
bool value;
/* Only some readers support wakeup preambles */
switch (sr->versionInfo.hardware[0])
{
case TMR_SR_MODEL_M6E:
case TMR_SR_MODEL_MICRO:
case TMR_SR_MODEL_M6E_I:
value = true;
break;
case TMR_SR_MODEL_M6E_NANO:
value = false;
break;
default:
value = false;
break;
}
sr->supportsPreamble = value;
return ret;
}
static TMR_Status
TMR_SR_boot(TMR_Reader *reader, uint32_t currentBaudRate)
{
TMR_Status ret;
uint8_t program;
bool boolval;
TMR_SR_SerialReader *sr;
TMR_SR_SerialTransport *transport;
int i;
bool value;
ret = TMR_SUCCESS;
sr = &reader->u.serialReader;
transport = &sr->transport;
/* Get current program */
ret = TMR_SR_cmdGetCurrentProgram(reader, &program);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* If bootloader, enter app */
if ((program & 0x3) == 1)
{
ret = TMR_SR_cmdBootFirmware(reader);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
/*
* Once out of bootloader, configure for wakeup preambles.
* Bootloader doesn't support preambles, and some versions
* fail to respond to normal commands afterwards.
*
* It is safe to avoid preambles up to this point because
* TMR_SR_connect has already been talking to the module
* to keep it awake.
*/
ret = TMR_SR_configPreamble(sr);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Initialize cached power mode value */
/* Should read power mode as soon as possible.
* Default mode assumes module is in deep sleep and
* adds a lengthy "wake-up preamble" to every command.
*/
if (sr->powerMode == TMR_SR_POWER_MODE_INVALID)
{
ret = TMR_paramGet(reader, TMR_PARAM_POWERMODE, &sr->powerMode);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
/**
* In case for M6E and its variant check for CRC
**/
if ((TMR_SR_MODEL_M6E == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == reader->u.serialReader.versionInfo.hardware[0]))
{
/**
* Get the transport/BUS type
**/
ret = TMR_SR_cmdGetReaderConfiguration(reader, TMR_SR_CONFIGURATION_CURRENT_MSG_TRANSPORT, &reader->u.serialReader.transportType);
if (TMR_SUCCESS != ret)
{
return ret;
}
/**
* In case of USB port disable the CRC
**/
if (TMR_SR_MSG_SOURCE_USB == reader->u.serialReader.transportType)
{
value = false;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_SEND_CRC, &value);
if (TMR_SUCCESS == ret)
{
reader->u.serialReader.crcEnabled = false;
}
else
{
/**
* Not Fatal, Going ahead with CRC enabled
**/
}
}
}
if (sr->baudRate != currentBaudRate)
{
if (NULL != transport->setBaudRate)
{
/**
* some transport layer does not support baud rate settings.
* for ex: TCP transport. In that case skip the baud rate
* settings.
*/
/* Bring baud rate up to the parameterized value */
ret = TMR_SR_cmdSetBaudRate(reader, sr->baudRate);
if (TMR_SUCCESS != ret)
{
return ret;
}
ret = transport->setBaudRate(transport, sr->baudRate);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
}
/*ret = TMR_SR_cmdVersion(reader, &sr->versionInfo);
if (TMR_SUCCESS != ret)
{
return ret;
}*/
/* If we need to check the version information for something operational,
this is the place to do it. */
sr->gpioDirections = -1; /* Needs fetching */
reader->continuousReading = ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]));
reader->continuousReading = false; //fix bug 1745 in the current release temporarily
/**
* This version check is required for the new reader stats.
* Older firmwares does not support this. Currently, firmware version
* 1.21.1.2 has support for new reader stats.
**/
if (
(((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) || (TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
&& compareVersion(reader, 1, 21, 1, 2))
|| ((TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) && compareVersion(reader, 1, 3, 0, 20))
|| ((TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) && compareVersion(reader, 1, 3, 2, 74))
)
{
reader->_storeSupportsResetStats = true;
reader->pSupportsResetStats = &(reader->_storeSupportsResetStats);
}
else
{
reader->_storeSupportsResetStats = false;
reader->pSupportsResetStats = &(reader->_storeSupportsResetStats);
}
/* Initialize the paramPresent and paramConfirmed bits. */
/* This block is expected to be collapsed by the compiler into a
* small number of constant-value writes into the sr->paramPresent
* array.
*/
for (i = 0 ; i < TMR_PARAMWORDS; i++)
{
sr->paramPresent[i] = 0;
}
BITSET(sr->paramPresent, TMR_PARAM_BAUDRATE);
BITSET(sr->paramPresent, TMR_PARAM_PROBEBAUDRATES);
BITSET(sr->paramPresent, TMR_PARAM_COMMANDTIMEOUT);
BITSET(sr->paramPresent, TMR_PARAM_TRANSPORTTIMEOUT);
BITSET(sr->paramPresent, TMR_PARAM_POWERMODE);
BITSET(sr->paramPresent, TMR_PARAM_USERMODE);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_CHECKPORT);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_PORTLIST);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_CONNECTEDPORTLIST);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_PORTSWITCHGPOS);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_SETTLINGTIMELIST);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_RETURNLOSS);
BITSET(sr->paramPresent, TMR_PARAM_ANTENNA_TXRXMAP);
BITSET(sr->paramPresent, TMR_PARAM_GPIO_INPUTLIST);
BITSET(sr->paramPresent, TMR_PARAM_GPIO_OUTPUTLIST);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_ACCESSPASSWORD);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_Q);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_BAP);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_TAGENCODING);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_SESSION);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_TARGET);
BITSET(sr->paramPresent, TMR_PARAM_GEN2_PROTOCOLEXTENSION);
BITSET(sr->paramPresent, TMR_PARAM_READ_ASYNCOFFTIME);
BITSET(sr->paramPresent, TMR_PARAM_READ_ASYNCONTIME);
BITSET(sr->paramPresent, TMR_PARAM_READ_PLAN);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_ENABLEPOWERSAVE);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_POWERMAX);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_POWERMIN);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_PORTREADPOWERLIST);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_PORTWRITEPOWERLIST);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_READPOWER);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_WRITEPOWER);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_TEMPERATURE);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_UNIQUEBYDATA);
BITSET(sr->paramPresent, TMR_PARAM_TAGOP_ANTENNA);
BITSET(sr->paramPresent, TMR_PARAM_TAGOP_PROTOCOL);
BITSET(sr->paramPresent, TMR_PARAM_VERSION_HARDWARE);
BITSET(sr->paramPresent, TMR_PARAM_VERSION_MODEL);
BITSET(sr->paramPresent, TMR_PARAM_VERSION_SOFTWARE);
BITSET(sr->paramPresent, TMR_PARAM_VERSION_SERIAL);
BITSET(sr->paramPresent, TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS);
BITSET(sr->paramPresent, TMR_PARAM_REGION_ID);
BITSET(sr->paramPresent, TMR_PARAM_REGION_SUPPORTEDREGIONS);
BITSET(sr->paramPresent, TMR_PARAM_REGION_HOPTABLE);
BITSET(sr->paramPresent, TMR_PARAM_REGION_HOPTIME);
BITSET(sr->paramPresent, TMR_PARAM_REGION_LBT_ENABLE);
BITSET(sr->paramPresent, TMR_PARAM_EXTENDEDEPC);
BITSET(sr->paramPresent, TMR_PARAM_READER_STATS);
BITSET(sr->paramPresent, TMR_PARAM_READER_STATISTICS);
BITSET(sr->paramPresent, TMR_PARAM_URI);
BITSET(sr->paramPresent, TMR_PARAM_PRODUCT_GROUP_ID);
BITSET(sr->paramPresent, TMR_PARAM_PRODUCT_GROUP);
BITSET(sr->paramPresent, TMR_PARAM_PRODUCT_ID);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_ENABLEREADFILTER);
BITSET(sr->paramPresent, TMR_PARAM_READER_WRITE_REPLY_TIMEOUT);
BITSET(sr->paramPresent, TMR_PARAM_READER_WRITE_EARLY_EXIT);
BITSET(sr->paramPresent, TMR_PARAM_ISO180006B_DELIMITER);
BITSET(sr->paramPresent, TMR_PARAM_ISO180006B_MODULATION_DEPTH);
BITSET(sr->paramPresent, TMR_PARAM_READER_STATS_ENABLE);
BITSET(sr->paramPresent, TMR_PARAM_TRIGGER_READ_GPI);
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
BITSET(sr->paramPresent, TMR_PARAM_LICENSE_KEY);
BITSET(sr->paramPresent, TMR_PARAM_USER_CONFIG);
BITSET(sr->paramPresent, TMR_PARAM_RADIO_ENABLESJC);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT);
BITSET(sr->paramPresent, TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL);
}
for (i = 0 ; i < TMR_PARAMWORDS; i++)
{
sr->paramConfirmed[i] = sr->paramPresent[i];
}
/* Get productGroupID early, so other params (e.g., txRxMap) can use it */
{
ret = TMR_SR_cmdGetReaderConfiguration(reader, TMR_SR_CONFIGURATION_PRODUCT_GROUP_ID, &sr->productId);
if (TMR_SUCCESS != ret)
{
if (TMR_ERROR_MSG_INVALID_PARAMETER_VALUE == ret)
{
/*
* Modules with firmware older than wilder will throw 0x105 error, as it was not
* implemented. Catch this error but do not return.
*/
sr->productId = 0xFFFF;
}
else
{
return ret;
}
}
/*
* If product is ruggedized reader,
* set reader's GPO pin which is used for antenna port switching
*/
if (1 == sr->productId)
{
uint8_t pin = 1;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO, &pin);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
}
/* Set region if user set the param */
if (TMR_REGION_NONE != sr->regionId)
{
ret = TMR_SR_cmdSetRegion(reader, sr->regionId);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
ret = TMR_SR_cmdGetCurrentProtocol(reader, &sr->currentProtocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (TMR_TAG_PROTOCOL_NONE == sr->currentProtocol)
{
TMR_TagProtocolList protocolList;
TMR_TagProtocol protocols[TMR_MAX_PROTOCOLS];
uint8_t index;
protocolList.list = &protocols[0];
protocolList.max = TMR_MAX_PROTOCOLS;
/*
* Serach whether GEN2 Protocol is supported by reader in its protocol list.
* If so set it as current protocol, else leave protocol selection to user.
*/
ret = TMR_SR_cmdGetAvailableProtocols(reader, &protocolList);
for(index = 0; index < protocolList.len; index++)
{
if(TMR_TAG_PROTOCOL_GEN2 == protocolList.list[index])
{
ret = TMR_SR_cmdSetProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
sr->currentProtocol = TMR_TAG_PROTOCOL_GEN2;
break;
}
}
}
reader->tagOpParams.protocol = sr->currentProtocol;
reader->tagOpParams.antenna = 0;
ret = initTxRxMapFromPorts(reader);
/**
* Enable the extended EPC flag in case
* of M5E and its variants
*/
if ((TMR_SR_MODEL_M6E != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_MICRO != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_M6E_NANO != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_M6E_I != sr->versionInfo.hardware[0]))
{
/* Do this only if the module is other than M6e*/
boolval = true;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_EXTENDED_EPC, &boolval);
if (TMR_SUCCESS != ret)
{
return ret;
}
reader->u.serialReader.extendedEPC = boolval;
}
/* Report RSSI in dbm */
if ((TMR_SR_MODEL_M6E != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_MICRO != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_M6E_NANO != sr->versionInfo.hardware[0]) &&
(TMR_SR_MODEL_M6E_I != sr->versionInfo.hardware[0]))
{
/* Do this only if the module is other than M6e*/
boolval = true;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_RSSI_IN_DBM, &boolval);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
else
{ /* Do this only in case of M6e */
int32_t timeout = 0;
/* Get reader's enable read filter setting */
ret = TMR_SR_cmdGetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &reader->u.serialReader.enableReadFiltering);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Get reader's read filter entry timeout */
ret = TMR_SR_cmdGetReaderConfiguration(reader, TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT, &timeout);
if (TMR_SUCCESS != ret)
{
return ret;
}
reader->u.serialReader.readFilterTimeout = (0 == timeout) ? TMR_DEFAULT_READ_FILTER_TIMEOUT : timeout;
}
return ret;
}
/**
* Probing the correct baudrate to communicate with the serial reader.
*
* @param reader The reader
* @param currentBaudRate the baud rate at which module is communicating.
*/
TMR_Status
TMR_SR_cmdProbeBaudRate(TMR_Reader *reader, uint32_t *currentBaudRate)
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
TMR_SR_SerialTransport *transport;
uint32_t rate = 0x00;
int i,count = 2;
ret = TMR_SUCCESS;
sr = &reader->u.serialReader;
transport = &reader->u.serialReader.transport;
for (i = 0; (uint32_t)i < sr->probeBaudRates.len; i++)
{
if (i <= 1 && count)
{
rate = sr->baudRate; /* Try this first */
/* Module might be in deep sleep mode, if there is no response for the
* first attempt, Try the same baudrate again. i = 0 and i = 1
*/
count--;
/* Hold i=0 (undo increment) until count has expired */
i--;
}
else
{
rate = sr->probeBaudRates.list[i];
if (rate == sr->baudRate)
continue; /* We already tried this one */
}
if (NULL != transport->setBaudRate)
{
/**
* some transport layer does not support baud rate settings.
* for ex: TCP transport. In that case skip the baud rate
* settings.
*/
ret = transport->setBaudRate(transport, rate);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
ret = transport->flush(transport);
if ((TMR_SUCCESS != ret) && (TMR_ERROR_UNIMPLEMENTED != ret))
{
return ret;
}
contact:
ret = TMR_SR_cmdVersion(reader, &(reader->u.serialReader.versionInfo));
if (TMR_SUCCESS == ret)
{
/* Got a reply? Then this is the right baud rate! */
break;
}
/* Timeouts are okay -- they usually mean "wrong baud rate",
* so just try the next one. All other errors are real
* and should be forwarded immediately. */
else if (TMR_ERROR_TIMEOUT != ret)
{
if (TMR_ERROR_COMM(ret))
{
ret = verifySearchStatus(reader);
if (TMR_SUCCESS == ret)
{
goto contact;
}
else
{
return ret;
}
}
else
{
return ret;
}
}
}
if (i == sr->probeBaudRates.len)
{
return TMR_ERROR_TIMEOUT;
}
/* copy the baud rate */
*currentBaudRate = rate;
return ret;
}
TMR_Status
TMR_SR_connect(TMR_Reader *reader)
{
TMR_Status ret;
uint32_t rate;
TMR_SR_SerialReader *sr;
TMR_SR_SerialTransport *transport;
ret = TMR_SUCCESS;
sr = &reader->u.serialReader;
transport = &reader->u.serialReader.transport;
ret = transport->open(transport);
if (TMR_SUCCESS != ret)
{
return ret;
}
rate = sr->probeBaudRates.list[0]; //this fixes the compilation errors in some compilers
ret = TMR_SR_cmdProbeBaudRate(reader, &rate);
if (TMR_SUCCESS != ret)
{
return ret;
}
reader->connected = true;
/* Boot */
ret = TMR_SR_boot(reader, rate);
if(ret !=TMR_SUCCESS)
{
if(ret == TMR_ERROR_AUTOREAD_ENABLED)
{
ret = verifySearchStatus(reader);
if (TMR_SUCCESS != ret)
{
return ret;
}
ret = TMR_SR_boot(reader, rate);
}
}
return ret;
}
TMR_Status
TMR_SR_destroy(TMR_Reader *reader)
{
TMR_SR_SerialTransport *transport;
reader->hasContinuousReadStarted = false;
transport = &reader->u.serialReader.transport;
/**
* Enable the CRC, in case it is disabled
**/
if (false == reader->u.serialReader.crcEnabled)
{
reader->u.serialReader.crcEnabled = true;
TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_SEND_CRC, &reader->u.serialReader.crcEnabled);
}
transport->shutdown(transport);
reader->connected = false;
#ifdef TMR_ENABLE_BACKGROUND_READS
/* Cleanup background threads */
cleanup_background_threads(reader);
#endif
return TMR_SUCCESS;
}
static TMR_Status
autoDetectAntennaList(struct TMR_Reader *reader)
{
TMR_Status ret;
TMR_SR_PortDetect ports[TMR_SR_MAX_ANTENNA_PORTS];
TMR_SR_PortPair searchList[TMR_SR_MAX_ANTENNA_PORTS];
uint8_t i, listLen, numPorts;
uint16_t j;
TMR_AntennaMapList *map;
ret = TMR_SUCCESS;
map = reader->u.serialReader.txRxMap;
/* 1. Detect current set of antennas */
numPorts = TMR_SR_MAX_ANTENNA_PORTS;
ret = TMR_SR_cmdAntennaDetect(reader, &numPorts, ports);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* 2. Set antenna list based on detected antennas (Might be clever
* to cache this and not bother sending the set-list command
* again, but it's more code and data space).
*/
for (i = 0, listLen = 0; i < numPorts; i++)
{
if (ports[i].detected)
{
/* Ensure that the port exists in the map */
for (j = 0; j < map->len; j++)
if (ports[i].port == map->list[j].txPort)
{
searchList[listLen].txPort = map->list[j].txPort;
searchList[listLen].rxPort = map->list[j].rxPort;
listLen++;
break;
}
}
}
if (0 == listLen) /* No ports auto-detected */
{
return TMR_ERROR_NO_ANTENNA;
}
ret = TMR_SR_cmdSetAntennaSearchList(reader, listLen, searchList);
return ret;
}
static TMR_Status
setAntennaList(struct TMR_Reader *reader, TMR_uint8List *antennas)
{
TMR_SR_PortPair searchList[16];
uint16_t i, j, listLen;
TMR_AntennaMapList *map;
map = reader->u.serialReader.txRxMap;
/** @todo cache the set list and don't reset it if it hasn't changed */
listLen = 0;
for (i = 0; i < antennas->len ; i++)
{
for (j = 0; j < map->len; j++)
{
if (antennas->list[i] == map->list[j].antenna)
{
searchList[listLen].txPort = map->list[j].txPort;
searchList[listLen].rxPort = map->list[j].rxPort;
listLen++;
break;
}
}
}
return TMR_SR_cmdSetAntennaSearchList(reader,(uint8_t)listLen, searchList);
}
static TMR_Status
setProtocol(struct TMR_Reader *reader, TMR_TagProtocol protocol)
{
TMR_Status ret;
if(reader->u.serialReader.currentProtocol != protocol)
{
ret = TMR_SR_cmdSetProtocol(reader, protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Set extended EPC -- This bit is reset when the protocol changes */
if (reader->u.serialReader.extendedEPC)
{
bool boolval;
boolval = true;
ret = TMR_SR_cmdSetReaderConfiguration(reader,
TMR_SR_CONFIGURATION_EXTENDED_EPC,
&boolval);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
reader->u.serialReader.currentProtocol = protocol;
/* Set enable filtering -- module automatically resets this when protocol is changed */
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &reader->u.serialReader.enableReadFiltering);
if (TMR_SUCCESS != ret)
{
return ret;
}
{
/* Set the read filter timeout */
uint32_t moduleValue = (TMR_DEFAULT_READ_FILTER_TIMEOUT == reader->u.serialReader.readFilterTimeout) ?
0 : reader->u.serialReader.readFilterTimeout;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT, &moduleValue);
if (TMR_SUCCESS != ret)
{
return ret;
}
reader->u.serialReader.readFilterTimeout = moduleValue;
}
}
return TMR_SUCCESS;
}
/**
* Compare two firmware versions, return true current firmware is higher than refernced firmware.
* else return false;
**/
bool
compareVersion(TMR_Reader *reader, uint8_t firstByte, uint8_t secondByte, uint8_t thirdByte, uint8_t fourthByte)
{
TMR_SR_SerialReader *sr = &reader->u.serialReader;
uint8_t temp;
/* compre the first byte */
temp = sr->versionInfo.fwVersion[0];
if (temp > firstByte)
{
/* Higher version, return true */
return true;
}
else if (temp < firstByte)
{
/* lower version, return flase */
return false;
}
else
{
/* Compare the second byte */
temp = sr->versionInfo.fwVersion[1];
if (temp > secondByte)
{
/* Higher version, return true */
return true;
}
else if (temp < secondByte)
{
/* lower version, return flase */
return false;
}
else
{
/* compare the third byte */
temp = sr->versionInfo.fwVersion[2];
if (temp > thirdByte)
{
/* Higher version, return true */
return true;
}
else if (temp < thirdByte)
{
/* lower version, return flase */
return false;
}
else
{
/* compare the fourth byte */
temp = sr->versionInfo.fwVersion[3];
if (temp > fourthByte)
{
return true;
}
else if (temp < fourthByte)
{
/* lower version, return flase */
return false;
}
else
{
/* both the firmwares are equal */
return true;
}
}
}
}
}
/**
* Compare antenna list in readplans list, return true if antenna
* list are consistent across the entire set of read plans.
**/
bool
compareAntennas(TMR_MultiReadPlan *multi)
{
TMR_ReadPlan *plan1, *plan2;
uint8_t allAntennasNull = 0;
uint8_t matchingPlanCount = 0;
uint8_t i;
bool status = false;
for (i = 0; i < multi->planCount; i++)
{
plan1 = multi->plans[0];
plan2 = multi->plans[i];
if ((0 != plan1->u.simple.antennas.len) && (0 != plan2->u.simple.antennas.len))
{
uint8_t j;
if (plan1->u.simple.antennas.len == plan2->u.simple.antennas.len)
{
for (j = 0; j < plan1->u.simple.antennas.len; j++)
{
if (plan1->u.simple.antennas.list[j] != plan2->u.simple.antennas.list[j])
{
status = false;
break;
}
}
if (j == plan1->u.simple.antennas.len)
{
matchingPlanCount++;
}
}
}
else if ((0 == plan1->u.simple.antennas.len) && (0 == plan2->u.simple.antennas.len))
{
allAntennasNull++;
}
else
{
status = false;
break;
}
}
if ((matchingPlanCount == multi->planCount) || (allAntennasNull == multi->planCount))
{
status = true;
}
return status;
}
TMR_Status
prepForSearch(TMR_Reader *reader, TMR_uint8List *antennaList)
{
TMR_Status ret;
if (antennaList->len == 0)
{
ret = autoDetectAntennaList(reader);
}
else
{
ret = setAntennaList(reader, antennaList);
}
return ret;
}
static TMR_Status
prepEmbReadTagMultiple(TMR_Reader *reader, uint8_t *msg, uint8_t *i,
uint16_t timeout, TMR_SR_SearchFlag searchFlag,
const TMR_TagFilter *filter, TMR_TagProtocol protocol,
TMR_GEN2_Password accessPassword, uint8_t *lenbyte)
{
TMR_Status ret;
ret = TMR_SR_msgSetupReadTagMultiple(reader,
msg, i, (uint16_t)timeout, searchFlag, filter, protocol, accessPassword);
/* Embedded command count (Currently supports only one command)*/
SETU8(msg, *i, 1);
*lenbyte = (*i)++;
return ret;
}
static TMR_Status
TMR_SR_read_internal(struct TMR_Reader *reader, uint32_t timeoutMs,
int32_t *tagCount, TMR_ReadPlan *rp)
{
TMR_Status ret = TMR_SUCCESS;
TMR_SR_SerialReader *sr;
TMR_SR_MultipleStatus multipleStatus = {0};
uint32_t count, elapsed, elapsed_tagop;
uint32_t readTimeMs, starttimeLow, starttimeHigh;
TMR_uint8List *antennaList = NULL;
sr = &reader->u.serialReader;
if (TMR_READ_PLAN_TYPE_MULTI == rp->type)
{
int i;
TMR_TagProtocolList p;
TMR_TagProtocolList *protocolList = &p;
TMR_TagFilter *filters[TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH];
TMR_TagProtocol protocols[TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH];
if (TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH < rp->u.multi.planCount)
{
return TMR_ERROR_TOO_BIG ;
}
protocolList->len = rp->u.multi.planCount;
protocolList->max = rp->u.multi.planCount;
protocolList->list = protocols;
for (i = 0; i < rp->u.multi.planCount; i++)
{
protocolList->list[i] = rp->u.multi.plans[i]->u.simple.protocol;
filters[i]= rp->u.multi.plans[i]->u.simple.filter;
}
if (
((0 < rp->u.multi.planCount) &&
(rp->u.multi.plans[0]->type == TMR_READ_PLAN_TYPE_SIMPLE) &&
(compareAntennas(&rp->u.multi)) &&
((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0])))
|| (true == reader->continuousReading)
)
{
TMR_SR_SearchFlag antennas = TMR_SR_SEARCH_FLAG_CONFIGURED_LIST;
antennas |= ((reader->continuousReading)? TMR_SR_SEARCH_FLAG_TAG_STREAMING : 0);
antennaList = &(rp->u.multi.plans[0]->u.simple.antennas);
ret = prepForSearch(reader, antennaList);
if (TMR_SUCCESS != ret)
{
return ret;
}
/**
* take the time stamp only in case of sync read,
* async read does not depend on this
**/
if (!reader->continuousReading)
{
/* Cache the read time so it can be put in tag read data later */
tm_gettime_consistent(&starttimeHigh, &starttimeLow);
sr->readTimeHigh = starttimeHigh;
sr->readTimeLow = starttimeLow;
sr->lastSentTagTimestampHigh = starttimeHigh;
sr->lastSentTagTimestampLow = starttimeLow;
}
if (reader->continuousReading)
{
bool value = false;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &value);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
ret = TMR_SR_cmdMultipleProtocolSearch(reader,
TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE,
protocolList, reader->userMetadataFlag,
antennas,
filters,
(uint16_t)timeoutMs, &count);
if (NULL != tagCount)
{
*tagCount += count;
}
return ret;
}
}
if (TMR_READ_PLAN_TYPE_SIMPLE == rp->type)
{
antennaList = &rp->u.simple.antennas;
reader->fastSearch = rp->u.simple.useFastSearch;
reader->triggerRead = rp->u.simple.triggerRead.enable;
if (!reader->continuousReading)
{
/* Currently only supported for sync read case */
reader->isStopNTags = rp->u.simple.stopOnCount.stopNTriggerStatus;
reader->numberOfTagsToRead = rp->u.simple.stopOnCount.noOfTags;
}
}
else if (TMR_READ_PLAN_TYPE_MULTI == rp->type)
{
uint32_t subTimeout;
int i;
subTimeout = 0;
if (0 == rp->u.multi.totalWeight)
{
subTimeout = timeoutMs / rp->u.multi.planCount;
}
for (i = 0; i < rp->u.multi.planCount; i++)
{
if (rp->u.multi.totalWeight)
{
subTimeout = rp->u.multi.plans[i]->weight * timeoutMs
/ rp->u.multi.totalWeight;
}
ret = TMR_SR_read_internal(reader, subTimeout, tagCount,
rp->u.multi.plans[i]);
if (TMR_SUCCESS != ret && TMR_ERROR_NO_TAGS_FOUND != ret)
{
return ret;
}
}
return ret;
}
else
{
return TMR_ERROR_INVALID;
}
/* At this point we're guaranteed to have a simple read plan */
ret = prepForSearch(reader, antennaList);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Set protocol to that specified by the read plan. */
ret = setProtocol(reader, rp->u.simple.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (reader->continuousReading)
{
bool value = false;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &value);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
/* Cache the read time so it can be put in tag read data later */
tm_gettime_consistent(&starttimeHigh, &starttimeLow);
sr->readTimeHigh = starttimeHigh;
sr->readTimeLow = starttimeLow;
sr->lastSentTagTimestampHigh = starttimeHigh;
sr->lastSentTagTimestampLow = starttimeLow;
/* Cache search timeout for later call to streaming receive */
sr->searchTimeoutMs = timeoutMs;
elapsed = tm_time_subtract(tmr_gettime_low(), starttimeLow);
elapsed_tagop = elapsed;
/**
* Ignoring the elapsed time calculation in case of true
* continuous reading,
*/
if ((reader->continuousReading) && (0 != timeoutMs))
{
elapsed = timeoutMs - 1;
}
while (elapsed <= timeoutMs)
{
readTimeMs = timeoutMs - elapsed;
if (readTimeMs > 65535)
{
readTimeMs = 65535;
}
if (NULL == rp->u.simple.tagop)
{
if(reader->continuousReading)
{
TMR_TagProtocolList p;
TMR_TagProtocolList *protocolList = &p;
TMR_TagFilter *filters[TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH];
TMR_TagProtocol protocols[TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH];
TMR_SR_SearchFlag antennas;
protocolList->len = 1;
protocolList->max = 1;
protocolList->list = protocols;
protocolList->list[0] = rp->u.simple.protocol;
filters[0]= rp->u.simple.filter;
antennas = TMR_SR_SEARCH_FLAG_CONFIGURED_LIST;
antennas |= ((reader->continuousReading)? TMR_SR_SEARCH_FLAG_TAG_STREAMING : 0);
antennaList = &(rp->u.simple.antennas);
ret = TMR_SR_cmdMultipleProtocolSearch(reader,
TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE,
protocolList, reader->userMetadataFlag,
antennas,
filters,
(uint16_t)timeoutMs, &count);
}
else
{
ret = TMR_SR_cmdReadTagMultiple(reader,(uint16_t)readTimeMs,
(TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter,
rp->u.simple.protocol,
&count);
}
}
else
{
uint8_t msg[256];
uint8_t i, lenbyte;
/* Since this is embedded tagop, removing elapsed time based on
* continuous reading should not be done
*/
readTimeMs = timeoutMs - elapsed_tagop;
if (readTimeMs > 65535)
{
readTimeMs = 65535;
}
i = 2;
/**
* add the tagoperation
**/
ret = TMR_SR_addTagOp(reader, rp->u.simple.tagop, rp, msg, &i, readTimeMs, &lenbyte);
if (TMR_SUCCESS != ret)
{
return ret;
}
msg[lenbyte] = i - (lenbyte + 2); /* Install length of subcommand */
msg[1] = i - 3; /* Install length */
ret = TMR_SR_executeEmbeddedRead(reader, msg, (uint16_t)timeoutMs, &multipleStatus);
count = multipleStatus.tagsFound;
/* Update embedded tagop success/failure count */
reader->u.serialReader.tagopSuccessCount += multipleStatus.successCount;
reader->u.serialReader.tagopFailureCount += multipleStatus.failureCount;
}
if (TMR_ERROR_NO_TAGS_FOUND == ret)
{
count = 0;
ret = TMR_SUCCESS;
}
else if (TMR_ERROR_TM_ASSERT_FAILED == ret)
{
return ret;
}
else if (TMR_ERROR_TIMEOUT == ret)
{
return ret;
}
else if (TMR_SUCCESS != ret)
{
uint16_t remainingTagsCount;
TMR_Status ret1;
reader->isStopNTags = false;
/* Check for the tag count (in case of module error)*/
ret1 = TMR_SR_cmdGetTagsRemaining(reader, &remainingTagsCount);
if (TMR_SUCCESS != ret1)
{
return ret1;
}
sr->tagsRemaining += remainingTagsCount;
if (NULL != tagCount)
{
*tagCount += remainingTagsCount;
}
return ret;
}
sr->tagsRemaining += count;
if (NULL != tagCount)
{
*tagCount += count;
}
if (reader->continuousReading)
{
sr->tagsRemaining = 1;
break;
}
else if (reader->isStopNTags && !reader->continuousReading)
{
/**
* No need to loop back for stop N tags
**/
break;
}
else
{
elapsed = tm_time_subtract(tmr_gettime_low(), starttimeLow);
}
}
return ret;
}
/* Reset reader stats (unless command not supported by reader)
*/
static
TMR_Status
_resetReaderStats(TMR_Reader *reader, TMR_Reader_StatsFlag statFlags)
{
TMR_Status ret;
if ((NULL != reader->pSupportsResetStats) && (false == *(reader->pSupportsResetStats)))
{
/* Command not supported, just skip it */
ret = TMR_SUCCESS;
}
else
{
ret = TMR_SR_cmdResetReaderStats(reader, statFlags);
/* Initialize reader->pSupportsResetStats, if necessary*/
if (NULL == reader->pSupportsResetStats)
{
switch (ret)
{
case TMR_SUCCESS:
reader->_storeSupportsResetStats = true;
reader->pSupportsResetStats = &(reader->_storeSupportsResetStats);
break;
case TMR_ERROR_MSG_WRONG_NUMBER_OF_DATA:
case TMR_ERROR_INVALID_OPCODE:
case TMR_ERROR_UNIMPLEMENTED_OPCODE:
case TMR_ERROR_UNIMPLEMENTED_FEATURE:
case TMR_ERROR_INVALID:
case TMR_ERROR_UNIMPLEMENTED:
case TMR_ERROR_UNSUPPORTED:
case TMR_ERROR_UNSUPPORTED_READER_TYPE:
/* If command unsupported, make a note not to do it again then
* proceed normally */
reader->_storeSupportsResetStats = false;
reader->pSupportsResetStats = &(reader->_storeSupportsResetStats);
ret = TMR_SUCCESS;
break;
}
}
}
return ret;
}
TMR_Status
TMR_SR_read(struct TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount)
{
TMR_Status ret;
TMR_ReadPlan *rp;
/**
* Reset the reader statistics at the beginning of every search,
* currently reader statistics only supports in m6e..
* TO DO: Enable this for other readers in future.
*/
ret = _resetReaderStats(reader, TMR_READER_STATS_FLAG_ALL);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (!reader->continuousReading)
{
/**
* In case of sync read only
* clear tag buffer
*/
ret = TMR_SR_cmdClearTagBuffer(reader);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
reader->u.serialReader.tagsRemaining = 0;
#ifdef TMR_ENABLE_BACKGROUND_READS
if (false == reader->backgroundEnabled)
/**
* if TMR_ENABLE_BACKGROUND_READS is not defined, then
* only sync read is possible. (Continuous and pseudo async reads
* are not available)
**/
#endif
{
/* If sync read, then reset tagop result count here */
reader->u.serialReader.tagopSuccessCount = 0;
reader->u.serialReader.tagopFailureCount = 0;
}
rp = reader->readParams.readPlan;
if (tagCount)
{
*tagCount = 0;
}
ret = TMR_SR_read_internal(reader, timeoutMs, tagCount, rp);
if (ret != TMR_SUCCESS)
{
return ret;
}
if (reader->continuousReading)
reader->hasContinuousReadStarted = true;
return ret;
}
TMR_Status
verifySearchStatus(TMR_Reader *reader)
{
TMR_SR_SerialReader *sr;
TMR_Status ret;
uint8_t *msg;
uint32_t timeoutMs;
bool crcEnable;
sr = &reader->u.serialReader;
msg = sr->bufResponse;
timeoutMs = sr->searchTimeoutMs;
reader->u.serialReader.crcEnabled = false;
TMR_SR_cmdStopReading(reader);
while(true)
{
ret = TMR_SR_receiveMessage(reader, msg, TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE, timeoutMs);
if(TMR_SUCCESS == ret || TMR_ERROR_DEVICE_RESET == ret)
{
if ((0x2F == msg[2]) && (0x02 == msg[5]))
{
/**
* 0x2F with type 0x02 means stop continuous reading.
* Module has already pushed all the tagreads before
* sending this response. i.e., reading is finished
**/
if (TMR_SR_MSG_SOURCE_USB == reader->u.serialReader.transportType)
{
crcEnable = false;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_SEND_CRC, &crcEnable);
if (TMR_SUCCESS == ret)
reader->u.serialReader.crcEnabled = false;
else
reader->u.serialReader.crcEnabled = true;
}
else
{
reader->u.serialReader.crcEnabled = true;
}
return TMR_SUCCESS;
}
else if ((0x2F == msg[2]) && (0x01 == msg[3] && (0x00 == msg[4])))
{
/**
* 0x2F with error status can also be treated as response for
* stop continuous reading.
**/
return TMR_SUCCESS;
}
}
else
{
/**
* We might get comm errors here, either CRC or TIMEOUT errors
* What should we do here??
**/
if (TMR_ERROR_CRC_ERROR == ret)
{
/**
* When the module is pushing all tags out, just don't bother about
* CRC and keep waiting for response for stopReading
**/
continue;
}
if (TMR_ERROR_TIMEOUT == ret)
{
return ret;
}
}
}
}
TMR_Status
TMR_SR_hasMoreTags(struct TMR_Reader *reader)
{
TMR_SR_SerialReader* sr;
TMR_Status ret;
sr = &reader->u.serialReader;
//#ifdef TMR_ENABLE_BACKGROUND_READS
if ((reader->continuousReading) && (0 == sr->tagsRemainingInBuffer))
{
uint8_t *msg;
uint32_t timeoutMs;
uint8_t response_type_pos;
uint8_t response_type;
msg = sr->bufResponse;
timeoutMs = sr->searchTimeoutMs;
ret = TMR_SR_receiveMessage(reader, msg, TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE, timeoutMs);
if (TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST == ret)
{
/* Tag password needed to complete tagop.
* Parse TagReadData and pass to password-generating callback,
* which will return the appropriate authentication. */
uint16_t flags = 0;
uint8_t bufptr;
TMR_TagReadData trd;
TMR_TagAuthentication tauth;
TMR_TRD_init(&trd);
/* In case of streaming the flags always start at position 8 */
bufptr = 8;
flags = GETU16AT(msg, bufptr);
bufptr += 2;
bufptr++; /* Skip tag count (always = 1) */
TMR_SR_parseMetadataFromMessage(reader, &trd, flags, &bufptr, msg);
TMR_SR_postprocessReaderSpecificMetadata(&trd, sr);
trd.reader = reader;
#ifndef BARE_METAL
// printf("Parsed 0604 TagReadData: readCount=%d rssi=%d ant=%d, freq=%d, t_hi=%X, t_lo=%X\n",
//trd.readCount, trd.rssi, trd.antenna, trd.frequency, trd.timestampHigh, trd.timestampLow, trd.phase);
{
notify_authreq_listeners(reader, &trd, &tauth);
}
#endif
/* TODO: Factor out password generation into callback */
reader->hasContinuousReadStarted = false;
ret = TMR_SR_cmdAuthReqResponse(reader, &tauth);
if (reader->continuousReading)
reader->hasContinuousReadStarted = true;
if (TMR_SUCCESS != ret)
{
return ret;
}
else
{
return TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST;
}
}
if ((TMR_SUCCESS != ret) && (TMR_ERROR_TAG_ID_BUFFER_FULL != ret)
&& ((TMR_ERROR_NO_TAGS_FOUND != ret)
|| ((TMR_ERROR_NO_TAGS_FOUND == ret) && (0 == msg[1]))))
{
if (msg[5] != 0x04 || msg[2] != 0x2f)
{
reader->u.serialReader.isBasetimeUpdated = false;
return ret;
}
}
ret = (0 == GETU16AT(msg, 3)) ? TMR_SUCCESS : TMR_ERROR_CODE(GETU16AT(msg, 3));
if ((TMR_SUCCESS == ret) && (0 == msg[1]))
{
/**
* In case of streaming and ISO protocol after every search cycle
* module sends the response for embedded operation status as
* FF 00 22 00 00.
* In this case return back with 0x400 error, because success response will deceive
* the read thread to process it. For GEN2 case we got the response with 0x400 status.
**/
return TMR_ERROR_NO_TAGS_FOUND;
}
if (((0x2F == msg[2]) && (TMR_ERROR_TAG_ID_BUFFER_FULL == ret))
||((0x22 == msg[2]) && (TMR_ERROR_TAG_ID_BUFFER_FULL == ret)))
{
return ret;
}
if (0x2F == msg[2])
{
if (0x02 == msg[5])
{
/**
* 0x2F with type 0x02 means stop continuous reading.
* Module has already pushed all the tagreads before
* sending this response. i.e., reading is finished
**/
reader->finishedReading = true;
reader->u.serialReader.isBasetimeUpdated = false;
return TMR_ERROR_END_OF_READING;
}
else if (0x03 == msg[5])
{
/**
* 0x2F with type 0x03 means left over client Auth message/response, ignore it.
**/
return TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST;
}
else if (0x04 == msg[5])
{
memcpy(&reader->paramMessage[0], msg, (msg[1] + 5) * sizeof(uint8_t));
reader->paramWait = false;
}
/**
* Control comes here in case of the response received
* for start continuous reading command. (0x2F with type 0x01)
**/
return TMR_ERROR_NO_TAGS;
}
else if (msg[1] < 6)
{ /* Need at least enough bytes to get to Response Type field */
return TMR_ERROR_PARSE;
}
response_type_pos = (0x10 == (msg[5] & 0x10)) ? 10 : 8;
response_type = msg[response_type_pos];
switch (response_type)
{
case 0x02:
/* Handle status stream responses */
reader->isStatusResponse = true;
sr->bufPointer = 9;
return TMR_SUCCESS;
case 0x01:
/* Stream continues after this message */
reader->isStatusResponse = false;
sr->tagsRemainingInBuffer = 1;
sr->bufPointer = 11;
return TMR_SUCCESS;
case 0x00:
/* while fixing bug#4190, Missed updating base timestamp for embedded read.
Because of this time stamps are falling back.To fix this issue updated base time stamp. */
reader->u.serialReader.isBasetimeUpdated = false;
/* Stream ends with this message */
sr->tagsRemaining = 0;
if (sr->oldQ.type != TMR_SR_GEN2_Q_INVALID)
{
ret = TMR_paramSet(reader, TMR_PARAM_GEN2_Q, &(sr->oldQ));
if (TMR_SUCCESS != ret)
{
return ret;
}
sr->oldQ.type = TMR_SR_GEN2_Q_INVALID;
}
if (NULL != reader->readParams.readPlan->u.simple.tagop)
{
response_type_pos += 7;
sr->tagopSuccessCount += GETU16(msg, response_type_pos);
sr->tagopFailureCount += GETU16(msg, response_type_pos);
}
if (TMR_SUCCESS == ret)
{ /* If things look good so far, signal that we are done with tags */
return TMR_ERROR_NO_TAGS;
}
/* otherwise feed the error back (should only be TMR_ERROR_TAG_ID_BUFFER_FULL) */
return ret;
default:
/* Unknown response type */
return TMR_ERROR_PARSE;
}
}
else
//#endif
{
/**
* TMR_SR_hasMoreTags control comes here only in case of sync reading
* And in case of pseudo async reading when TMR_ENABLE_BACKGROUND_READS
* is defined.
**/
ret = (sr->tagsRemaining > 0) ? TMR_SUCCESS : TMR_ERROR_NO_TAGS;
return ret;
}
}
TMR_Status
TMR_SR_getNextTag(struct TMR_Reader *reader, TMR_TagReadData *read)
{
TMR_SR_SerialReader *sr;
TMR_Status ret;
uint8_t *msg;
uint8_t i;
uint16_t flags = 0;
uint32_t timeoutMs;
uint8_t subResponseLen = 0;
uint8_t crclen = 2 ;
uint8_t epclen = 0;
sr = &reader->u.serialReader;
timeoutMs = sr->searchTimeoutMs;
{
msg = sr->bufResponse;
if (sr->tagsRemaining == 0)
{
return TMR_ERROR_NO_TAGS;
}
if (sr->tagsRemainingInBuffer == 0)
{
/* Fetch the next set of tags from the reader */
if (reader->continuousReading)
{
ret = TMR_SR_hasMoreTags(reader);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
else
{
if (reader->u.serialReader.opCode == TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE)
{
i = 2;
SETU8(msg, i, TMR_SR_OPCODE_GET_TAG_ID_BUFFER);
SETU16(msg, i, reader->userMetadataFlag);
SETU8(msg, i, 0); /* read options */
msg[1] = i-3; /* Install length */
ret = TMR_SR_send(reader, msg);
if (TMR_SUCCESS != ret)
{
return ret;
}
sr->tagsRemainingInBuffer = msg[8];
sr->bufPointer = 9;
}
else if (reader->u.serialReader.opCode == TMR_SR_OPCODE_READ_TAG_ID_SINGLE)
{
TMR_SR_receiveMessage(reader, msg, reader->u.serialReader.opCode, timeoutMs);
sr->tagsRemainingInBuffer = (uint8_t)GETU32AT(msg , 9);
sr->tagsRemaining = sr->tagsRemainingInBuffer;
sr->bufPointer = 13 ;
}
else
{
return TMR_ERROR_INVALID_OPCODE;
}
}
}
i = sr->bufPointer;
if (reader->u.serialReader.opCode == TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE)
{
flags = GETU16AT(msg, reader->continuousReading ? 8 : 5);
TMR_SR_parseMetadataFromMessage(reader, read, flags, &i, msg);
}
if (reader->u.serialReader.opCode == TMR_SR_OPCODE_READ_TAG_ID_SINGLE)
{
flags = GETU16AT(msg, i + 6);
subResponseLen = msg[i+1];
i += 7;
TMR_SR_parseMetadataOnly(reader, read, flags, &i, msg);
epclen = subResponseLen + 4 - (i - sr->bufPointer) - crclen;
read->tag.epcByteCount=epclen;
memcpy(&(read->tag.epc), &msg[i], read->tag.epcByteCount);
i+=epclen;
read->tag.crc = GETU16(msg, i);
}
sr->bufPointer = i;
TMR_SR_postprocessReaderSpecificMetadata(read, sr);
sr->tagsRemainingInBuffer--;
if (false == reader->continuousReading)
{
sr->tagsRemaining--;
}
read->reader = reader;
return TMR_SUCCESS;
}
}
TMR_Status
TMR_SR_writeTag(struct TMR_Reader *reader, const TMR_TagFilter *filter,
const TMR_TagData *data)
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (TMR_TAG_PROTOCOL_GEN2 == reader->tagOpParams.protocol)
{
return TMR_SR_cmdWriteGen2TagEpc(reader, filter, sr->gen2AccessPassword, (uint16_t)(sr->commandTimeout),
data->epcByteCount, data->epc, 0);
}
else
{
return TMR_ERROR_UNIMPLEMENTED;
}
}
TMR_Status
TMR_SR_readTagMemWords(TMR_Reader *reader, const TMR_TagFilter *target,
uint32_t bank, uint32_t wordAddress,
uint16_t wordCount, uint16_t data[])
{
TMR_Status ret;
ret = TMR_SR_readTagMemBytes(reader, target, bank, wordAddress * 2,
wordCount * 2, (uint8_t *)data);
if (TMR_SUCCESS != ret)
{
return ret;
}
#ifndef TMR_BIG_ENDIAN_HOST
{
uint16_t i;
uint8_t *data8;
/* We used the uint16_t data as temporary storage for the values read,
but we need to adjust for possible endianness differences.
This is technically correct on all platforms, though it's a no-op
on big-endian ones. */
data8 = (uint8_t *)data;
for (i = 0; i < wordCount; i++)
{
data[i] = (data8[2*i] << 8) | data8[2*i + 1];
}
}
#endif
return TMR_SUCCESS;
}
static TMR_Status
TMR_SR_readTagMemBytesUnaligned(TMR_Reader *reader,
const TMR_TagFilter *target,
uint32_t bank, uint32_t byteAddress,
uint16_t byteCount, uint8_t data[])
{
TMR_Status ret;
TMR_TagReadData read;
uint16_t wordCount;
uint8_t buf[254];
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
wordCount = (uint16_t)((byteCount + 1 + (byteAddress & 1) ) / 2);
read.data.max = 254;
read.data.list = buf;
read.metadataFlags = 0;
ret = TMR_SR_cmdGEN2ReadTagData(reader, (uint16_t)(sr->commandTimeout),
(TMR_GEN2_Bank)bank, byteAddress / 2, (uint8_t)wordCount,
sr->gen2AccessPassword, target, &read);
if (TMR_SUCCESS != ret)
{
return ret;
}
memcpy(data, buf + (byteAddress & 1), byteCount);
return TMR_SUCCESS;
}
TMR_Status
TMR_SR_readTagMemBytes(TMR_Reader *reader, const TMR_TagFilter *target,
uint32_t bank, uint32_t byteAddress,
uint16_t byteCount, uint8_t data[])
{
TMR_Status ret;
TMR_TagReadData read;
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
read.data.max = byteCount;
read.data.list = (uint8_t *)data;
read.metadataFlags = 0;
if (TMR_TAG_PROTOCOL_GEN2 == reader->tagOpParams.protocol)
{
/*
* Handling unaligned reads takes spare memory; avoid allocating that
* (on that stack) if not necessary.
*/
if ((byteAddress & 1) || (byteCount & 1))
{
return TMR_SR_readTagMemBytesUnaligned(reader, target, bank, byteAddress,
byteCount, data);
}
return TMR_SR_cmdGEN2ReadTagData(reader, (uint16_t)(sr->commandTimeout),
(TMR_GEN2_Bank)bank, byteAddress / 2, byteCount / 2,
sr->gen2AccessPassword, target, &read);
}
#ifdef TMR_ENABLE_ISO180006B
else if (TMR_TAG_PROTOCOL_ISO180006B == reader->tagOpParams.protocol)
{
return TMR_SR_cmdISO180006BReadTagData(reader,(uint16_t)(sr->commandTimeout),
(uint8_t)byteAddress, (uint8_t)byteCount, target,
&read);
}
#endif /* TMR_ENABLE_ISO180006B */
else
{
return TMR_ERROR_UNIMPLEMENTED;
}
}
TMR_Status
TMR_SR_modifyFlash(TMR_Reader *reader, uint8_t sector, uint32_t address,
uint32_t password, uint8_t length, const uint8_t data[],
uint32_t offset)
{
/**
* As only M6e reader and it's varient supports modifying the flash in
* application mode.Hence, this check is required.
*/
if ((TMR_SR_MODEL_M6E == reader->u.serialReader.versionInfo.hardware[0])||
(TMR_SR_MODEL_MICRO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == reader->u.serialReader.versionInfo.hardware[0]))
{
return TMR_SR_cmdModifyFlashSector(reader, sector, address, password, length,
data, offset);
}
else
return TMR_ERROR_UNSUPPORTED;
}
TMR_Status
TMR_SR_writeTagMemWords(struct TMR_Reader *reader, const TMR_TagFilter *filter,
uint32_t bank, uint32_t address,
uint16_t count, const uint16_t data[])
{
const uint8_t *dataPtr;
#ifndef TMR_BIG_ENDIAN_HOST
uint8_t buf[254];
int i;
for (i = 0 ; i < count ; i++)
{
buf[2*i ] = data[i] >> 8;
buf[2*i + 1] = data[i] & 0xff;
}
dataPtr = buf;
#else
dataPtr = (const uint8_t *)data;
#endif
return TMR_SR_writeTagMemBytes(reader, filter, bank, address * 2, count * 2,
dataPtr);
}
TMR_Status
TMR_SR_writeTagMemBytes(struct TMR_Reader *reader, const TMR_TagFilter *filter,
uint32_t bank, uint32_t address,
uint16_t count, const uint8_t data[])
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
TMR_GEN2_WriteMode mode;
TMR_GEN2_WriteMode *value = &mode;
sr = &reader->u.serialReader;
TMR_paramGet(reader, TMR_PARAM_GEN2_WRITEMODE, value);
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (TMR_TAG_PROTOCOL_GEN2 == reader->tagOpParams.protocol)
{
/* Buffer for converting to Gen2 native word size.
* A waste of space, but the only way to do byte/word conversions without
* munging the original data input. ReadTagMemBytes is deprecated, anyway,
* along with all the other protocol-independent methods, so avoid using it,
* if possible. */
uint16_t data16[TMR_SR_MAX_PACKET_SIZE/2];
uint16_t wordCount;
uint16_t iWord;
/* Misaligned writes are not permitted */
if ((address & 1) || (count & 1))
{
return TMR_ERROR_INVALID;
}
wordCount = count/2;
for (iWord=0; iWord<wordCount; iWord++)
{
data16[iWord] = 0;
data16[iWord] |= data[(2*iWord)+0];
data16[iWord] <<= 8;
data16[iWord] |= data[(2*iWord)+1];
}
switch (mode)
{
case TMR_GEN2_WORD_ONLY:
return TMR_SR_cmdGEN2WriteTagData(reader, (uint16_t)(sr->commandTimeout),
(TMR_GEN2_Bank)bank, address / 2, (uint8_t)count, data,
sr->gen2AccessPassword, filter);
case TMR_GEN2_BLOCK_ONLY:
return TMR_SR_cmdBlockWrite(reader,(uint16_t)sr->commandTimeout, (TMR_GEN2_Bank)bank, address / 2, (uint8_t)(count/2), data16, sr->gen2AccessPassword, filter);
case TMR_GEN2_BLOCK_FALLBACK:
ret = TMR_SR_cmdBlockWrite(reader,(uint16_t)sr->commandTimeout, (TMR_GEN2_Bank)bank, address / 2, (uint8_t)(count/2), data16, sr->gen2AccessPassword, filter);
if (TMR_SUCCESS == ret)
{
return ret;
}
else
{
return TMR_SR_cmdGEN2WriteTagData(reader, (uint16_t)(sr->commandTimeout),
(TMR_GEN2_Bank)bank, address / 2, (uint8_t)count, data,
sr->gen2AccessPassword, filter);
}
default:
return TMR_ERROR_INVALID_WRITE_MODE;
}
}
#ifdef TMR_ENABLE_ISO180006B
else if (TMR_TAG_PROTOCOL_ISO180006B == reader->tagOpParams.protocol)
{
if (count != 1)
{
return TMR_ERROR_INVALID;
}
return TMR_SR_cmdISO180006BWriteTagData(reader, (uint16_t)(sr->commandTimeout),
(uint8_t)address, 1, data, filter);
}
#endif
else
{
return TMR_ERROR_INVALID;
}
}
TMR_Status
TMR_SR_lockTag(struct TMR_Reader *reader, const TMR_TagFilter *filter,
TMR_TagLockAction *action)
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (TMR_TAG_PROTOCOL_GEN2 == reader->tagOpParams.protocol)
{
if (TMR_LOCK_ACTION_TYPE_GEN2_LOCK_ACTION != action->type)
{
/* Lock type doesn't match tagop protocol */
return TMR_ERROR_INVALID;
}
return TMR_SR_cmdGEN2LockTag(reader, (uint16_t)sr->commandTimeout,
action->u.gen2LockAction.mask,
action->u.gen2LockAction.action,
sr->gen2AccessPassword,
filter);
}
#ifdef TMR_ENABLE_ISO180006B
else if (TMR_TAG_PROTOCOL_ISO180006B == reader->tagOpParams.protocol)
{
if (TMR_LOCK_ACTION_TYPE_ISO180006B_LOCK_ACTION != action->type)
{
/* Lock type doesn't match tagop protocol */
return TMR_ERROR_INVALID;
}
return TMR_SR_cmdISO180006BLockTag(reader, (uint16_t)(sr->commandTimeout),
action->u.iso180006bLockAction.address,
filter);
}
#endif
else
{
return TMR_ERROR_UNIMPLEMENTED;
}
}
TMR_Status
TMR_SR_reboot(TMR_Reader *reader)
{
TMR_Status ret;
ret = TMR_SR_cmdrebootReader(reader);
return ret;
}
TMR_Status
TMR_SR_killTag(struct TMR_Reader *reader, const TMR_TagFilter *filter,
const TMR_TagAuthentication *auth)
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (TMR_TAG_PROTOCOL_GEN2 == reader->tagOpParams.protocol)
{
if (TMR_AUTH_TYPE_GEN2_PASSWORD != auth->type)
{
/* Auth type doesn't match tagop protocol */
return TMR_ERROR_INVALID;
}
return TMR_SR_cmdKillTag(reader,
(uint16_t)(sr->commandTimeout),
auth->u.gen2Password,
filter);
}
else
{
return TMR_ERROR_UNIMPLEMENTED;
}
}
TMR_Status
TMR_SR_gpoSet(struct TMR_Reader *reader, uint8_t count,
const TMR_GpioPin state[])
{
TMR_Status ret;
int i;
for (i = 0; i < count; i++)
{
ret = TMR_SR_cmdSetGPIO(reader, state[i].id, state[i].high);
if (TMR_SUCCESS != ret)
return ret;
}
return TMR_SUCCESS;
}
TMR_Status TMR_SR_gpiGet(struct TMR_Reader *reader, uint8_t *count,
TMR_GpioPin state[])
{
TMR_Status ret;
TMR_GpioPin pinStates[4];
uint8_t i,j, numPins;
numPins = numberof(pinStates);
ret = TMR_SR_cmdGetGPIO(reader, &numPins, pinStates);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (numPins > *count)
{
numPins = *count;
}
*count = 0;
j = 0;
for (i = 0 ; i < numPins ; i++)
{
if (!pinStates[i].output)
{
/* If pin is input, only then copy to output */
state[j].id = pinStates[i].id;
state[j].high = pinStates[i].high;
state[j].output = pinStates[i].output;
(*count)++;
j ++;
}
}
return TMR_SUCCESS;
}
#ifdef TMR_ENABLE_STDIO
TMR_Status
TMR_SR_firmwareLoad(struct TMR_Reader *reader, void *cookie,
TMR_FirmwareDataProvider provider)
{
static const uint8_t magic[] =
{ 0x54, 0x4D, 0x2D, 0x53, 0x50, 0x61, 0x69, 0x6B, 0x00, 0x00, 0x00, 0x02 };
TMR_Status ret;
uint8_t buf[256];
uint16_t packetLen, packetRemaining, size, offset;
uint32_t len, rate, address, remaining;
TMR_SR_SerialReader *sr;
TMR_SR_SerialTransport *transport;
sr = &reader->u.serialReader;
transport = &sr->transport;
remaining = numberof(magic) + 4;
offset = 0;
while (remaining > 0)
{
size = (uint16_t)remaining;
if (false == provider(cookie, &size, buf + offset))
{
return TMR_ERROR_FIRMWARE_FORMAT;
}
remaining -= size;
offset += size;
}
if (0 != memcmp(buf, magic, numberof(magic)))
{
return TMR_ERROR_FIRMWARE_FORMAT;
}
len = GETU32AT(buf, 12);
/* @todo get any params we want to reset */
/*
* Drop baud to 9600 so we know for sure what it will be after going
* back to the bootloader. (Older firmwares always revert to 9600.
* Newer ones keep the current baud rate.)
*/
if (NULL != transport->setBaudRate)
{
/**
* some transport layer does not support baud rate settings.
* for ex: TCP transport. In that case skip the baud rate
* settings.
*/
ret = TMR_SR_cmdSetBaudRate(reader, 9600);
if (TMR_SUCCESS != ret)
{
return ret;
}
ret = transport->setBaudRate(transport, 9600);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
ret = TMR_SR_cmdBootBootloader(reader);
if ((TMR_SUCCESS != ret)
/* Invalid Opcode okay -- means "already in bootloader" */
&& (TMR_ERROR_INVALID_OPCODE != ret))
{
return ret;
}
/*
* Wait for the bootloader to be entered. 200ms is enough.
*/
tmr_sleep(200);
/* Bootloader doesn't support wakeup preambles */
sr->supportsPreamble = false;
/* Bootloader doesn't support high speed operation */
rate = sr->baudRate;
if (rate > 115200)
{
rate = 115200;
}
if (NULL != transport->setBaudRate)
{
/**
* some transport layer does not support baud rate settings.
* for ex: TCP transport. In that case skip the baud rate
* settings.
*/
ret = TMR_SR_cmdSetBaudRate(reader, rate);
if (TMR_SUCCESS != ret)
{
return ret;
}
ret = transport->setBaudRate(transport, rate);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
ret = TMR_SR_cmdEraseFlash(reader, 2, 0x08959121);
if (TMR_SUCCESS != ret)
{
return ret;
}
address = 0;
remaining = len;
while (remaining > 0)
{
packetLen = 240;
if (packetLen > remaining)
{
packetLen = (uint16_t)remaining;
}
offset = 0;
packetRemaining = packetLen;
while (packetRemaining > 0)
{
size = packetRemaining;
if (false == provider(cookie, &size, buf + offset))
{
return TMR_ERROR_FIRMWARE_FORMAT;
}
packetRemaining -= size;
offset += size;
}
ret = TMR_SR_cmdWriteFlashSector(reader, 2, address, 0x02254410,(uint8_t) packetLen,
buf, 0);
if (TMR_SUCCESS != ret)
{
return ret;
}
address += packetLen;
remaining -= packetLen;
}
ret = TMR_SR_boot(reader, rate);
if(ret != TMR_SUCCESS)
{
if(ret == TMR_ERROR_AUTOREAD_ENABLED)
{
ret = TMR_ERROR_FIRMWARE_UPDATE_ON_AUTOREAD;
return ret;
}
}
return ret;
}
#endif
static TMR_Status
getHardwareInfo(struct TMR_Reader *reader, void *value)
{
//TMR_Status ret;
//uint8_t buf[127];
char tmp[255];
//uint8_t count;
TMR_SR_VersionInfo *info;
info = &reader->u.serialReader.versionInfo;
TMR_hexDottedQuad(info->hardware, tmp);
/**
* Commented below code to fix the Bug#2117
*/
/*
tmp[11] = '-';
count = 127;
ret = TMR_SR_cmdGetHardwareVersion(reader, 0, 0, &count, buf);
if (TMR_SUCCESS != ret)
{
count = 0;
tmp[11] = '\0';
}
TMR_bytesToHex(buf, count, tmp + 12);
TMR_stringCopy(value, tmp, 12 + 2*count);*/
TMR_stringCopy(value, tmp, (int)strlen(tmp));
return TMR_SUCCESS;
}
static TMR_Status
getSerialNumber(struct TMR_Reader *reader, void *value)
{
/* See http://trac/swtree/changeset/6498 for previous implementation */
TMR_Status ret;
uint8_t buf[127];
uint8_t count;
char tmp[127];
int tmplen;
count = 127;
tmplen = 0;
ret = TMR_SR_cmdGetHardwareVersion(reader, 0, 0x40, &count, buf);
if (TMR_SUCCESS != ret)
{
count = 0;
}
else
{
int idx;
uint8_t len;
idx = 3;
len = buf[idx++];
if (len > (count-3))
{
ret = TMR_ERROR_UNIMPLEMENTED;
}
else
{
for (tmplen=0; tmplen<len; tmplen++)
{
tmp[tmplen] = (char)buf[idx+tmplen];
}
}
}
if (0 == count)
{
TMR_String *serial = (TMR_String *)value;
/**
* Command failure:
* Serial number not implemented on this reader
* Leave value at default "no value"
*/
serial->value[0] = '\0';
return TMR_SUCCESS;
}
TMR_stringCopy(value, tmp, tmplen);
return ret;
}
/* Abuse the structure layout of TMR_SR_PortPowerAndSettlingTime a bit
* so that this can be one function instead of three only slightly
* different pieces of code. Since all three per-port values are
* represented as uint16_t, take an additional 'offset' parameter that
* gives the pointer distance from the first element to the element
* (readPower, writePower, settlingTime) that we actually want to set.
*/
static TMR_Status
setPortValues(struct TMR_Reader *reader, const TMR_PortValueList *list,
int offset)
{
TMR_Status ret;
TMR_SR_PortPowerAndSettlingTime ports[TMR_SR_MAX_ANTENNA_PORTS];
uint8_t count;
uint16_t i, j;
count = numberof(ports);
ret = TMR_SR_cmdGetAntennaPortPowersAndSettlingTime(reader, &count, ports);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* If a value is left out, 0 is assumed */
/*for (j = 0; j < count; j++)
{
*(&ports[j].readPower + offset) = 0;
}*/
/*
* For each settling time in the user's list, try to find an
* existing entry in the list returned from the reader.
*/
for (i = 0; i < list->len; i++)
{
for (j = 0 ; j < count ; j++)
{
if (list->list[i].port == ports[j].port)
{
break;
}
}
if (j == count)
{
if (count == TMR_SR_MAX_ANTENNA_PORTS)
{
return TMR_ERROR_TOO_BIG;
}
ports[j].port = list->list[i].port;
ports[j].readPower = 0;
ports[j].writePower = 0;
ports[j].settlingTime = 0;
count++;
}
if (list->list[i].value > 32767 || list->list[i].value < -32768)
{
return TMR_ERROR_ILLEGAL_VALUE;
}
*(&ports[j].readPower + offset) = (int16_t)(list->list[i].value);
}
return TMR_SR_cmdSetAntennaPortPowersAndSettlingTime(reader, count, ports);
}
/* See comment before setPortValues() for the meaning of offset */
static TMR_Status
getPortValues(struct TMR_Reader *reader, TMR_PortValueList *list, int offset)
{
TMR_Status ret;
TMR_SR_PortPowerAndSettlingTime ports[TMR_SR_MAX_ANTENNA_PORTS];
uint8_t count;
uint16_t i, j;
count = numberof(ports);
ret = TMR_SR_cmdGetAntennaPortPowersAndSettlingTime(reader, &count, ports);
if (TMR_SUCCESS != ret)
{
return ret;
}
for (i = 0, j = 0; i < count; i++)
{
if ((0 == *(&ports[i].readPower + offset) && ((TMR_SR_MODEL_MICRO != reader->u.serialReader.versionInfo.hardware[0])
|| (TMR_SR_MODEL_M6E_NANO != reader->u.serialReader.versionInfo.hardware[0])))
|| (((TMR_SR_MODEL_MICRO == reader->u.serialReader.versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0]))
&& (-32768 == *(&ports[i].readPower + offset))))
{
continue;
}
if (j < list->max)
{
list->list[j].port = ports[i].port;
list->list[j].value = (int32_t)*(&ports[i].readPower + offset);
}
j++;
}
list->len = (uint8_t)j;
return TMR_SUCCESS;
}
static TMR_Status
TMR_SR_paramSet(struct TMR_Reader *reader, TMR_Param key, const void *value)
{
TMR_Status ret;
TMR_SR_Configuration readerkey;
TMR_SR_ProtocolConfiguration protokey;
TMR_SR_SerialReader *sr;
TMR_SR_SerialTransport *transport;
ret = TMR_SUCCESS;
sr = &reader->u.serialReader;
readerkey = TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE;
protokey.protocol = TMR_TAG_PROTOCOL_GEN2;
if (0 == BITGET(sr->paramConfirmed, key))
{
TMR_paramProbe(reader, key);
}
if (BITGET(sr->paramConfirmed, key) && (0 == BITGET(sr->paramPresent, key)))
{
return TMR_ERROR_NOT_FOUND;
}
switch (key)
{
case TMR_PARAM_REGION_ID:
sr->regionId = *(TMR_Region*)value;
if (reader->connected)
{
ret = TMR_SR_cmdSetRegion(reader, sr->regionId);
}
break;
case TMR_PARAM_URI:
case TMR_PARAM_PRODUCT_GROUP_ID:
case TMR_PARAM_PRODUCT_GROUP:
case TMR_PARAM_PRODUCT_ID:
case TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT:
case TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT:
{
ret = TMR_ERROR_READONLY;
break;
}
case TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT:
{
*(bool *)value ? (reader->streamStats |= TMR_SR_STATUS_ANTENNA) :
(reader->streamStats &= ~TMR_SR_STATUS_ANTENNA) ;
break;
}
case TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT:
{
*(bool *)value ? (reader->streamStats |= TMR_SR_STATUS_FREQUENCY) :
(reader->streamStats &= ~TMR_SR_STATUS_FREQUENCY) ;
break;
}
case TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT:
{
*(bool *)value ? (reader->streamStats |= TMR_SR_STATUS_TEMPERATURE) :
(reader->streamStats &= ~TMR_SR_STATUS_TEMPERATURE) ;
break;
}
case TMR_PARAM_BAUDRATE:
{
uint32_t rate;
transport = &sr->transport;
rate = *(uint32_t *)value;
if (reader->connected)
{
if (NULL != transport->setBaudRate)
{
/**
* some transport layer does not support baud rate settings.
* for ex: TCP transport. In that case skip the baud rate
* settings.
*/
ret = TMR_SR_cmdSetBaudRate(reader, rate);
if (TMR_SUCCESS != ret)
{
break;
}
sr->baudRate = rate;
transport->setBaudRate(transport, sr->baudRate);
}
}
else
{
sr->baudRate = rate;
}
break;
}
case TMR_PARAM_PROBEBAUDRATES:
{
const TMR_uint32List *u32List;
uint8_t i;
u32List = value;
if (u32List->len > sr->probeBaudRates.max)
{
ret = TMR_ERROR_TOO_BIG;
break;
}
for(i = 0; i < u32List->len; i++)
{
sr->probeBaudRates.list[i] = u32List->list[i];
}
sr->probeBaudRates.len = u32List->len;
break;
}
case TMR_PARAM_COMMANDTIMEOUT:
{
uint32_t val = *(uint32_t*)value;
if (((uint32_t)1<<31) & val)
{
ret = TMR_ERROR_ILLEGAL_VALUE;
}
else
{
sr->commandTimeout = *(uint32_t *)value;
}
}
break;
case TMR_PARAM_TRANSPORTTIMEOUT:
{
uint32_t val = *(uint32_t*)value;
if (((uint32_t)1<<31) & val)
{
ret = TMR_ERROR_ILLEGAL_VALUE;
}
else
{
/**
* In case user specified the timeout value for connect
* Enable the usrTimoutEnable option
*/
sr->transportTimeout = *(uint32_t *)value;
sr->usrTimeoutEnable = true;
}
}
break;
case TMR_PARAM_RADIO_ENABLEPOWERSAVE:
readerkey = TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE;
break;
case TMR_PARAM_RADIO_ENABLESJC:
readerkey = TMR_SR_CONFIGURATION_SELF_JAMMER_CANCELLATION;
break;
case TMR_PARAM_EXTENDEDEPC:
readerkey = TMR_SR_CONFIGURATION_EXTENDED_EPC;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_UNIQUE_BY_PROTOCOL, value);
}
else
{
ret = TMR_ERROR_NOT_FOUND;
}
break;
case TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
int32_t timeout = (TMR_DEFAULT_READ_FILTER_TIMEOUT == *(int32_t *)value) ? 0 : *(int32_t *)value;
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT, &timeout);
if (TMR_SUCCESS == ret)
{
reader->u.serialReader.readFilterTimeout = timeout;
}
}
else
{
ret = TMR_ERROR_NOT_FOUND;
}
break;
case TMR_PARAM_TAGREADDATA_ENABLEREADFILTER:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) || (TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, value);
if (TMR_SUCCESS == ret)
{
reader->u.serialReader.enableReadFiltering = *(bool *)value;
}
}
else
{
ret = TMR_ERROR_READONLY;
}
break;
case TMR_PARAM_RADIO_READPOWER:
ret = TMR_SR_cmdSetReadTxPower(reader, *(int32_t *)value);
break;
case TMR_PARAM_RADIO_WRITEPOWER:
ret = TMR_SR_cmdSetWriteTxPower(reader, *(int32_t *)value);
break;
case TMR_PARAM_RADIO_PORTREADPOWERLIST:
ret = setPortValues(reader, value, 0);
break;
case TMR_PARAM_RADIO_PORTWRITEPOWERLIST:
ret = setPortValues(reader, value, 1);
break;
case TMR_PARAM_ANTENNA_SETTLINGTIMELIST:
ret = setPortValues(reader, value, 2);
break;
case TMR_PARAM_ANTENNA_CHECKPORT:
readerkey = TMR_SR_CONFIGURATION_SAFETY_ANTENNA_CHECK;
break;
case TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI:
readerkey = TMR_SR_CONFIGURATION_RECORD_HIGHEST_RSSI;
break;
case TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM:
readerkey = TMR_SR_CONFIGURATION_RSSI_IN_DBM;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA:
readerkey = TMR_SR_CONFIGURATION_UNIQUE_BY_ANTENNA;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYDATA:
readerkey = TMR_SR_CONFIGURATION_UNIQUE_BY_DATA;
break;
case TMR_PARAM_ANTENNA_PORTSWITCHGPOS:
{
const TMR_uint8List *u8list;
uint16_t i;
u8list = value;
reader->portmask = 0;
for (i = 0 ; i < u8list->len && i < u8list->max ; i++)
{
reader->portmask |= 1 << (u8list->list[i] - 1);
}
ret = TMR_SR_cmdSetReaderConfiguration(
reader, TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO, &reader->portmask);
if (TMR_SUCCESS != ret)
{
break;
}
ret = initTxRxMapFromPorts(reader);
break;
}
case TMR_PARAM_TRIGGER_READ_GPI:
{
uint8_t portmask;
const TMR_uint8List *u8list;
uint16_t i;
u8list = value;
portmask = 0;
for (i = 0 ; i < u8list->len && i < u8list->max ; i++)
{
portmask |= 1 << (u8list->list[i] - 1);
}
ret = TMR_SR_cmdSetReaderConfiguration(
reader, TMR_SR_CONFIGURATION_TRIGGER_READ_GPIO, &portmask);
break;
}
case TMR_PARAM_ANTENNA_TXRXMAP:
{
const TMR_AntennaMapList *map;
TMR_AntennaMapList *mymap;
uint8_t len;
uint16_t i, j;
map = value;
mymap = sr->txRxMap;
if (map->len > mymap->max)
{
ret = TMR_ERROR_TOO_BIG;
break;
}
len = 0;
for (i = 0 ; i < map->len ; i++)
{
if (!HASPORT(sr->portMask, map->list[i].txPort) ||
!HASPORT(sr->portMask, map->list[i].rxPort))
{
return TMR_ERROR_NO_ANTENNA;
}
/* Error check for txrxmap */
for (j = i+1; j < map->len; j++)
{
if (map->list[i].antenna == map->list[j].antenna)
{
return TMR_ERROR_INVALID_ANTENNA_CONFIG;
}
}
len = i+1;
}
for (i = 0; i < len; i ++)
{
mymap->list[i] = map->list[i];
}
mymap->len = len;
break;
}
case TMR_PARAM_REGION_HOPTABLE:
{
const TMR_uint32List *u32list;
u32list = value;
ret = TMR_SR_cmdSetFrequencyHopTable(reader, (uint8_t)u32list->len, u32list->list);
break;
}
case TMR_PARAM_REGION_HOPTIME:
ret = TMR_SR_cmdSetFrequencyHopTime(reader, *(uint32_t *)value);
break;
case TMR_PARAM_REGION_LBT_ENABLE:
{
uint32_t hopTable[64];
uint8_t count;
count = numberof(hopTable);
ret = TMR_SR_cmdGetFrequencyHopTable(reader, &count, hopTable);
if (TMR_SUCCESS != ret)
{
break;
}
ret = TMR_SR_cmdSetRegionLbt(reader, sr->regionId, *(bool *)value);
if (TMR_SUCCESS != ret)
{
break;
}
ret = TMR_SR_cmdSetFrequencyHopTable(reader, count, hopTable);
break;
}
case TMR_PARAM_TAGOP_ANTENNA:
{
uint16_t i;
TMR_AntennaMapList *map;
uint8_t antenna;
uint8_t txPort, rxPort;
map = sr->txRxMap;
antenna = *(uint8_t *)value;
txPort = rxPort = 0;
for (i = 0; i < map->len && i < map->max; i++)
{
if (map->list[i].antenna == antenna)
{
txPort = map->list[i].txPort;
rxPort = map->list[i].rxPort;
reader->tagOpParams.antenna = antenna;
break;
}
}
if (txPort == 0)
{
ret = TMR_ERROR_NO_ANTENNA;
}
else
{
ret = TMR_SR_cmdSetTxRxPorts(reader, txPort, rxPort);
}
break;
}
case TMR_PARAM_TAGOP_PROTOCOL:
if (0 == ((1 << (*(TMR_TagProtocol *)value - 1)) &
sr->versionInfo.protocols))
{
ret = TMR_ERROR_UNSUPPORTED;
}
else
{
reader->tagOpParams.protocol = *(TMR_TagProtocol *)value;
if (reader->connected)
{
ret = setProtocol(reader, reader->tagOpParams.protocol);
if (TMR_SUCCESS == ret)
{
reader->u.serialReader.currentProtocol = reader->tagOpParams.protocol;
}
}
}
break;
case TMR_PARAM_READ_PLAN:
{
const TMR_ReadPlan *plan;
TMR_ReadPlan tmpPlan;
plan = value;
tmpPlan = *plan;
ret = validateReadPlan(reader, &tmpPlan,
sr->txRxMap, sr->versionInfo.protocols);
if (TMR_SUCCESS != ret)
{
return ret;
}
*reader->readParams.readPlan = tmpPlan;
break;
}
case TMR_PARAM_GPIO_INPUTLIST:
case TMR_PARAM_GPIO_OUTPUTLIST:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]))
{
const TMR_uint8List *u8list;
int bit, i, newDirections, pin;
u8list = value;
if (key == TMR_PARAM_GPIO_OUTPUTLIST)
{
newDirections = 0;
}
else
{
newDirections = 0x1e;
}
for (i = 0 ; i < u8list->len && i < u8list->max ; i++)
{
if (key == TMR_PARAM_GPIO_OUTPUTLIST)
{
newDirections |= (1 << u8list->list[i]);
}
else
{
newDirections &= ~(1 << u8list->list[i]);
}
}
for (pin = 0 ; pin < u8list->len ; pin++)
{
bit = 1 << (u8list->list[pin]);
ret = TMR_SR_cmdSetGPIODirection(reader, u8list->list[pin],
(newDirections & bit) != 0);
if (TMR_SUCCESS != ret)
{
return ret;
}
}
break;
}
case TMR_PARAM_RADIO_POWERMAX:
case TMR_PARAM_RADIO_POWERMIN:
case TMR_PARAM_REGION_SUPPORTEDREGIONS:
case TMR_PARAM_ANTENNA_PORTLIST:
case TMR_PARAM_ANTENNA_CONNECTEDPORTLIST:
case TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS:
case TMR_PARAM_RADIO_TEMPERATURE:
case TMR_PARAM_VERSION_HARDWARE:
case TMR_PARAM_VERSION_MODEL:
case TMR_PARAM_VERSION_SOFTWARE:
case TMR_PARAM_ANTENNA_RETURNLOSS:
case TMR_PARAM_GEN2_PROTOCOLEXTENSION:
ret = TMR_ERROR_READONLY;
break;
case TMR_PARAM_POWERMODE:
if (reader->connected)
{
ret = TMR_SR_cmdSetPowerMode(reader, *(TMR_SR_PowerMode *)value);
if (TMR_SUCCESS == ret)
{
sr->powerMode = *(TMR_SR_PowerMode *)value;
}
}
else
{
sr->powerMode = *(TMR_SR_PowerMode *)value;
}
break;
case TMR_PARAM_USERMODE:
ret = TMR_SR_cmdSetUserMode(reader, *(TMR_SR_UserMode *)value);
break;
case TMR_PARAM_GEN2_Q:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_Q;
break;
case TMR_PARAM_GEN2_TAGENCODING:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TAGENCODING;
break;
case TMR_PARAM_GEN2_SESSION:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_SESSION;
break;
case TMR_PARAM_GEN2_TARGET:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TARGET;
break;
case TMR_PARAM_GEN2_BLF:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_LINKFREQUENCY;
break;
case TMR_PARAM_GEN2_TARI:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TARI;
break;
case TMR_PARAM_GEN2_WRITEMODE:
sr->writeMode = *(TMR_GEN2_WriteMode *)value;
break;
case TMR_PARAM_GEN2_BAP:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_BAP;
break;
#ifdef TMR_ENABLE_ISO180006B
case TMR_PARAM_ISO180006B_BLF:
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_LINKFREQUENCY;
break;
case TMR_PARAM_ISO180006B_MODULATION_DEPTH:
{
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_MODULATION_DEPTH;
break;
}
case TMR_PARAM_ISO180006B_DELIMITER:
{
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_DELIMITER;
break;
}
#endif /* TMR_ENABLE_ISO180006B */
case TMR_PARAM_GEN2_ACCESSPASSWORD:
sr->gen2AccessPassword = *(TMR_GEN2_Password *)value;
break;
case TMR_PARAM_LICENSE_KEY:
{
uint32_t supportedProtocols;
TMR_uint8List *license = (TMR_uint8List *)value;
ret = TMR_SR_cmdSetProtocolLicenseKey(reader, TMR_SR_SET_LICENSE_KEY, license->list, license->len, &supportedProtocols);
}
break;
case TMR_PARAM_USER_CONFIG:
{
TMR_SR_UserConfigOp *config = (TMR_SR_UserConfigOp *)value;
switch(config->op)
{
case TMR_USERCONFIG_SAVE:
/* Save the configuration section to flash */
ret = TMR_SR_cmdSetUserProfile(reader, TMR_USERCONFIG_SAVE, config->category, TMR_SR_CUSTOM_CONFIGURATION);
break;
case TMR_USERCONFIG_RESTORE:
/* Restore the saved configuration section from flash */
ret = TMR_SR_cmdSetUserProfile(reader, TMR_USERCONFIG_RESTORE, config->category, TMR_SR_CUSTOM_CONFIGURATION);
break;
case TMR_USERCONFIG_CLEAR:
/* Clear configuration section from flash, and restore default configuration section */
ret = TMR_SR_cmdSetUserProfile(reader, TMR_USERCONFIG_CLEAR, config->category, TMR_SR_CUSTOM_CONFIGURATION);
break;
case TMR_USERCONFIG_VERIFY:
ret = TMR_SR_cmdSetUserProfile(reader, TMR_USERCONFIG_VERIFY, config->category, TMR_SR_CUSTOM_CONFIGURATION);
break;
case TMR_USERCONFIG_SAVE_WITH_READPLAN:
/* Save the read plan configuration section to flash */
ret = TMR_SR_cmdSetUserProfile(reader, TMR_USERCONFIG_SAVE_WITH_READPLAN, config->category, TMR_SR_CUSTOM_CONFIGURATION);
break;
default:
ret = TMR_ERROR_NOT_FOUND;
}
}
break;
case TMR_PARAM_READER_STATISTICS:
/* Only RF On time statistic can be reset to 0 */
ret = TMR_SR_cmdResetReaderStatistics(reader, TMR_SR_READER_STATS_ALL);
break;
case TMR_PARAM_READER_STATS:
{
if ((NULL != reader->pSupportsResetStats) && (false == *(reader->pSupportsResetStats)))
{
/* Command not supported, pop up the error */
return TMR_ERROR_UNSUPPORTED;
}
/* Only RF On time statistic can be reset to 0 */
ret = TMR_SR_cmdResetReaderStats(reader, TMR_READER_STATS_FLAG_ALL);
break;
}
case TMR_PARAM_READER_STATS_ENABLE:
{
if ((NULL != reader->pSupportsResetStats) && (false == *(reader->pSupportsResetStats)))
{
/* Command not supported, pop up the error */
return TMR_ERROR_UNSUPPORTED;
}
/* Store the statitics flags requested by the user */
reader->statsFlag = *(TMR_Reader_StatsFlag *)value;
break;
}
case TMR_PARAM_READER_WRITE_REPLY_TIMEOUT:
case TMR_PARAM_READER_WRITE_EARLY_EXIT:
{
TMR_SR_Gen2ReaderWriteTimeOut timeout;
/* in case of timeout check for range */
switch (key)
{
case TMR_PARAM_READER_WRITE_REPLY_TIMEOUT:
{
if ( *(uint16_t *)value < 1000 || *(uint16_t *)value > 21000)
return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;
break;
}
default:
;
}
/* Get the values before setting it */
ret = TMR_SR_cmdGetReaderWriteTimeOut(reader, protokey.protocol, &timeout);
if (TMR_SUCCESS != ret)
{
break;
}
/* set the parameter asked by the user */
switch (key)
{
case TMR_PARAM_READER_WRITE_REPLY_TIMEOUT:
{
timeout.writetimeout = *(uint16_t *)value;
break;
}
case TMR_PARAM_READER_WRITE_EARLY_EXIT:
{
timeout.earlyexit = !(*(bool *)value);
break;
}
default:
ret = TMR_ERROR_NOT_FOUND;
}
/* set the vakue */
ret = TMR_SR_cmdSetReaderWriteTimeOut (reader,protokey.protocol, &timeout);
break;
}
case TMR_PARAM_METADATAFLAG:
{
if (*(TMR_TRD_MetadataFlag *)value & TMR_TRD_METADATA_FLAG_PROTOCOL)
reader->userMetadataFlag = *(TMR_TRD_MetadataFlag *)value;
else
ret = TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;
break;
}
default:
ret = TMR_ERROR_NOT_FOUND;
}
switch (key)
{
case TMR_PARAM_ANTENNA_CHECKPORT:
case TMR_PARAM_RADIO_ENABLEPOWERSAVE:
case TMR_PARAM_RADIO_ENABLESJC:
case TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI:
case TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM:
case TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA:
case TMR_PARAM_TAGREADDATA_UNIQUEBYDATA:
ret = TMR_SR_cmdSetReaderConfiguration(reader, readerkey, value);
break;
case TMR_PARAM_EXTENDEDEPC:
{
if ((TMR_SR_MODEL_M6E == reader->u.serialReader.versionInfo.hardware[0])||
(TMR_SR_MODEL_MICRO == reader->u.serialReader.versionInfo.hardware[0])||
(TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0])||
(TMR_SR_MODEL_M6E_I == reader->u.serialReader.versionInfo.hardware[0]))
{
ret = TMR_ERROR_UNSUPPORTED;
}
else
{
ret = TMR_SR_cmdSetReaderConfiguration(reader, readerkey, value);
if(TMR_SUCCESS == ret)
{
/* cache the extended epc setting */
reader->u.serialReader.extendedEPC = *(bool *)value;
}
}
}
break;
case TMR_PARAM_GEN2_BAP:
{
TMR_GEN2_Bap *bap;
bap = (TMR_GEN2_Bap *)value;
if (NULL == (TMR_GEN2_Bap *)value)
{
/** It means user is disabling the bap support, make the flag down
* and skip the command sending
**/
sr->isBapEnabled = false;
break;
}
else if ((-1 > bap->powerUpDelayUs) || (-1 > bap->freqHopOfftimeUs))
{
/*
* Invalid values for BAP parameters,
* Accepts only positive values or -1 for NULL
*/
return TMR_ERROR_ILLEGAL_VALUE;
}
else if ((-1 == bap->powerUpDelayUs) && (-1 == bap->freqHopOfftimeUs))
{
/**
* Here -1 signifies NULL. API should skips the parameter and does not sent the matching
* command to the reader. Let reader use its own default
**/
sr->isBapEnabled = true;
break;
}
else
{
/*
* do a paramGet of BAP parameters. This serves two purposes.
* 1. API knows wheather module supports the BAP options or not.
* 2. API can assign default values to the fields, are not set by the user.
*/
TMR_GEN2_Bap getBapParams;
ret = TMR_SR_cmdGetProtocolConfiguration(reader, protokey.protocol,
protokey, &getBapParams);
if (TMR_SUCCESS != ret)
{
/* throw the error and come out from the loop */
break;
}
else
{
/*
* Modify the get BAP structure if either of the set BAP params are -1
*/
sr->isBapEnabled = true;
if (-1 == bap->powerUpDelayUs)
{
bap->powerUpDelayUs = getBapParams.powerUpDelayUs;
}
if (-1 == bap->freqHopOfftimeUs)
{
bap->freqHopOfftimeUs = getBapParams.freqHopOfftimeUs;
}
}
}
// No break -- fall through to regular Gen2 param handler
}
case TMR_PARAM_GEN2_Q:
case TMR_PARAM_GEN2_TAGENCODING:
case TMR_PARAM_GEN2_SESSION:
case TMR_PARAM_GEN2_TARGET:
case TMR_PARAM_GEN2_BLF:
case TMR_PARAM_GEN2_TARI:
#ifdef TMR_ENABLE_ISO180006B
case TMR_PARAM_ISO180006B_BLF:
case TMR_PARAM_ISO180006B_MODULATION_DEPTH:
case TMR_PARAM_ISO180006B_DELIMITER:
#endif /* TMR_ENABLE_ISO180006B */
ret = TMR_SR_cmdSetProtocolConfiguration(reader, protokey.protocol,
protokey, value);
break;
default:
;
}
return ret;
}
static TMR_Status
TMR_SR_paramGet(struct TMR_Reader *reader, TMR_Param key, void *value)
{
TMR_Status ret;
TMR_SR_Configuration readerkey;
TMR_SR_ProtocolConfiguration protokey;
TMR_SR_SerialReader *sr;
ret = TMR_SUCCESS;
sr = &reader->u.serialReader;
readerkey = TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE;
protokey.protocol = TMR_TAG_PROTOCOL_GEN2;
if (BITGET(sr->paramConfirmed, key) && 0 == BITGET(sr->paramPresent, key))
{
return TMR_ERROR_NOT_FOUND;
}
switch (key)
{
case TMR_PARAM_BAUDRATE:
*(uint32_t *)value = sr->baudRate;
break;
case TMR_PARAM_PROBEBAUDRATES:
{
TMR_uint32List *uint32List;
uint8_t i;
uint32List = value;
if (sr->probeBaudRates.len > uint32List->max)
{
sr->probeBaudRates.len = uint32List->max;
}
if (sr->probeBaudRates.len)
{
for(i = 0; i < sr->probeBaudRates.len; i++)
{
uint32List->list[i] = sr->probeBaudRates.list[i];
}
uint32List->len = sr->probeBaudRates.len;
}
else
{
//list is empty
}
break;
}
case TMR_PARAM_URI:
if (NULL != value)
{
TMR_stringCopy((TMR_String *)value, reader->uri, (int)strlen(reader->uri));
}
else
{
ret = TMR_ERROR_ILLEGAL_VALUE;
}
break;
case TMR_PARAM_COMMANDTIMEOUT:
*(uint32_t *)value = sr->commandTimeout;
break;
case TMR_PARAM_TRANSPORTTIMEOUT:
*(uint32_t *)value = sr->transportTimeout;
break;
case TMR_PARAM_REGION_ID:
{
if ((TMR_REGION_NONE == sr->regionId) && (reader->connected))
{
ret = TMR_SR_cmdGetRegion(reader, &sr->regionId);
}
*(TMR_Region *)value = sr->regionId;
}
break;
case TMR_PARAM_RADIO_ENABLEPOWERSAVE:
readerkey = TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE;
break;
case TMR_PARAM_RADIO_ENABLESJC:
readerkey = TMR_SR_CONFIGURATION_SELF_JAMMER_CANCELLATION;
break;
case TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
*(int32_t *)value = sr->readFilterTimeout;
}
else
{
ret = TMR_ERROR_NOT_FOUND;
}
break;
case TMR_PARAM_TAGREADDATA_ENABLEREADFILTER:
*(bool *)value = sr->enableReadFiltering;
break;
case TMR_PARAM_EXTENDEDEPC:
readerkey = TMR_SR_CONFIGURATION_EXTENDED_EPC;
break;
case TMR_PARAM_RADIO_POWERMAX:
{
TMR_SR_PowerWithLimits power;
ret = TMR_SR_cmdGetReadTxPowerWithLimits(reader, &power);
if (TMR_SUCCESS != ret)
{
break;
}
*(int16_t *)value = power.maxPower;
break;
}
case TMR_PARAM_RADIO_POWERMIN:
{
TMR_SR_PowerWithLimits power;
ret = TMR_SR_cmdGetReadTxPowerWithLimits(reader, &power);
if (TMR_SUCCESS != ret)
break;
*(int16_t *)value = power.minPower;
break;
}
case TMR_PARAM_RADIO_READPOWER:
ret = TMR_SR_cmdGetReadTxPower(reader, (int32_t *)value);
break;
case TMR_PARAM_RADIO_WRITEPOWER:
ret = TMR_SR_cmdGetWriteTxPower(reader, (int32_t *)value);
break;
case TMR_PARAM_ANTENNA_CHECKPORT:
readerkey = TMR_SR_CONFIGURATION_SAFETY_ANTENNA_CHECK;
break;
case TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI:
readerkey = TMR_SR_CONFIGURATION_RECORD_HIGHEST_RSSI;
break;
case TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM:
readerkey = TMR_SR_CONFIGURATION_RSSI_IN_DBM;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA:
readerkey = TMR_SR_CONFIGURATION_UNIQUE_BY_ANTENNA;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYDATA:
readerkey = TMR_SR_CONFIGURATION_UNIQUE_BY_DATA;
break;
case TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL:
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]))
{
ret = TMR_SR_cmdGetReaderConfiguration(reader, TMR_SR_CONFIGURATION_UNIQUE_BY_PROTOCOL, value);
}
else
{
ret = TMR_ERROR_NOT_FOUND;
}
break;
case TMR_PARAM_PRODUCT_GROUP_ID:
readerkey = TMR_SR_CONFIGURATION_PRODUCT_GROUP_ID;
break;
case TMR_PARAM_PRODUCT_ID:
readerkey = TMR_SR_CONFIGURATION_PRODUCT_ID;
break;
case TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT:
*(bool *)value = (reader->streamStats & TMR_SR_STATUS_ANTENNA) ? true : false;
break;
case TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT:
*(bool *)value = (reader->streamStats & TMR_SR_STATUS_FREQUENCY) ? true : false;
break;
case TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT:
*(bool *)value = (reader->streamStats & TMR_SR_STATUS_TEMPERATURE) ? true : false;
break;
case TMR_PARAM_ANTENNA_PORTSWITCHGPOS:
{
TMR_uint8List *u8list;
u8list = value;
ret = TMR_SR_cmdGetReaderConfiguration(
reader, TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO, &reader->portmask);
if (TMR_SUCCESS != ret)
{
break;
}
u8list->len = 0;
if (reader->portmask & 1)
{
LISTAPPEND(u8list, 1);
}
if (reader->portmask & 2)
{
LISTAPPEND(u8list, 2);
}
if (reader->portmask & 3)
{
LISTAPPEND(u8list, 3);
}
break;
}
case TMR_PARAM_TRIGGER_READ_GPI:
{
uint8_t portmask;
TMR_uint8List *u8list;
u8list = value;
ret = TMR_SR_cmdGetReaderConfiguration(
reader, TMR_SR_CONFIGURATION_TRIGGER_READ_GPIO, &portmask);
if (TMR_SUCCESS != ret)
{
break;
}
u8list->len = 0;
if (portmask & 1)
{
LISTAPPEND(u8list, 1);
}
if (portmask & 2)
{
LISTAPPEND(u8list, 2);
}
break;
}
case TMR_PARAM_ANTENNA_SETTLINGTIMELIST:
ret = getPortValues(reader, value, 2);
break;
case TMR_PARAM_RADIO_PORTREADPOWERLIST:
ret = getPortValues(reader, value, 0);
break;
case TMR_PARAM_RADIO_PORTWRITEPOWERLIST:
ret = getPortValues(reader, value, 1);
break;
case TMR_PARAM_ANTENNA_RETURNLOSS:
ret = TMR_SR_cmdGetAntennaReturnLoss(reader, value);
break;
case TMR_PARAM_GPIO_INPUTLIST:
case TMR_PARAM_GPIO_OUTPUTLIST:
{
TMR_uint8List *u8list;
u8list = value;
u8list->len = 0;
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]))
{
int pin, wantout;
bool out;
TMR_GpioPin pinStates[16];
uint8_t numPins;
sr->gpioDirections = -1;
numPins = numberof(pinStates);
ret = TMR_SR_cmdGetGPIO(reader, &numPins, pinStates);
if (TMR_SUCCESS != ret)
{
return ret;
}
wantout = (key == TMR_PARAM_GPIO_OUTPUTLIST) ? 1 : 0;
if (-1 == sr->gpioDirections)
{
/* Cache the current state */
sr->gpioDirections = 0;
for (pin = 1; pin <= numPins ; pin++)
{
ret = TMR_SR_cmdGetGPIODirection(reader, pin, &out);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (out)
{
sr->gpioDirections |= 1 << pin;
}
}
}
for (pin = 1; pin <= numPins ; pin++)
{
if (wantout == ((sr->gpioDirections >> pin) & 1))
{
LISTAPPEND(u8list, pin);
}
}
}
else
{
LISTAPPEND(u8list, 1);
LISTAPPEND(u8list, 2);
}
break;
}
case TMR_PARAM_ANTENNA_PORTLIST:
{
uint8_t i;
TMR_uint8List *u8list;
u8list = value;
u8list->len = 0;
for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)
{
LISTAPPEND(u8list, reader->u.serialReader.txRxMap->list[i].antenna);
}
break;
}
case TMR_PARAM_ANTENNA_CONNECTEDPORTLIST:
{
// Store detected ports in array for quick lookup
bool detected[TMR_SR_MAX_ANTENNA_PORTS+1];
uint8_t i;
TMR_uint8List *u8list;
for (i=0; i<TMR_SR_MAX_ANTENNA_PORTS; i++)
{
detected[i] = false;
}
u8list = value;
{
TMR_SR_PortDetect ports[TMR_SR_MAX_ANTENNA_PORTS];
uint8_t numPorts;
numPorts = numberof(ports);
ret = TMR_SR_cmdAntennaDetect(reader, &numPorts, ports);
if (TMR_SUCCESS != ret)
{
break;
}
for (i=0; i<numPorts; i++)
{
detected[ports[i].port] = ports[i].detected;
}
}
u8list->len = 0;
for (i=0; i<reader->u.serialReader.txRxMap->len; i++)
{
int ant = reader->u.serialReader.txRxMap->list[i].antenna;
int tx = reader->u.serialReader.txRxMap->list[i].txPort;
int rx = reader->u.serialReader.txRxMap->list[i].rxPort;
if (detected[tx] && detected[rx])
{
LISTAPPEND(u8list, ant);
}
}
break;
}
case TMR_PARAM_ANTENNA_TXRXMAP:
{
TMR_AntennaMapList *map, *mymap;
uint16_t i;
map = value;
mymap = sr->txRxMap;
for (i = 0 ; i < mymap->len && i < map->max ; i++)
map->list[i] = mymap->list[i];
map->len = mymap->len;
break;
}
case TMR_PARAM_REGION_HOPTABLE:
{
TMR_uint32List *u32List;
uint8_t count;
u32List = value;
count = (uint8_t)u32List->max;
ret = TMR_SR_cmdGetFrequencyHopTable(reader,&count, u32List->list);
if (TMR_SUCCESS != ret)
{
break;
}
u32List->len = count;
break;
}
case TMR_PARAM_REGION_HOPTIME:
ret = TMR_SR_cmdGetFrequencyHopTime(reader, value);
break;
case TMR_PARAM_REGION_LBT_ENABLE:
ret = TMR_SR_cmdGetRegionConfiguration(reader,
TMR_SR_REGION_CONFIGURATION_LBT_ENABLED, value);
if (TMR_SUCCESS != ret && TMR_ERROR_IS_CODE(ret))
{
*(bool *)value = false;
ret = TMR_SUCCESS;
}
break;
case TMR_PARAM_TAGOP_ANTENNA:
*(uint8_t *)value = reader->tagOpParams.antenna;
break;
case TMR_PARAM_TAGOP_PROTOCOL:
*(TMR_TagProtocol *)value = reader->tagOpParams.protocol;
break;
case TMR_PARAM_POWERMODE:
if (reader->connected)
{
TMR_SR_PowerMode pm;
ret = TMR_SR_cmdGetPowerMode(reader, &pm);
if (TMR_SUCCESS == ret)
{
sr->powerMode = pm;
}
}
*(TMR_SR_PowerMode*)value = sr->powerMode;
break;
case TMR_PARAM_USERMODE:
ret = TMR_SR_cmdGetUserMode(reader, value);
break;
case TMR_PARAM_GEN2_Q:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_Q;
break;
case TMR_PARAM_GEN2_TAGENCODING:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TAGENCODING;
break;
case TMR_PARAM_GEN2_SESSION:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_SESSION;
break;
case TMR_PARAM_GEN2_TARGET:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TARGET;
break;
case TMR_PARAM_GEN2_BLF:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_LINKFREQUENCY;
break;
case TMR_PARAM_GEN2_TARI:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_TARI;
break;
case TMR_PARAM_GEN2_BAP:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_BAP;
break;
case TMR_PARAM_GEN2_WRITEMODE:
*(TMR_GEN2_WriteMode *)value = sr->writeMode;
break;
case TMR_PARAM_GEN2_PROTOCOLEXTENSION:
protokey.u.gen2 = TMR_SR_GEN2_CONFIGURATION_PROTCOLEXTENSION;
break;
#ifdef TMR_ENABLE_ISO180006B
case TMR_PARAM_ISO180006B_BLF:
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_LINKFREQUENCY;
break;
case TMR_PARAM_ISO180006B_MODULATION_DEPTH:
{
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_MODULATION_DEPTH;
break;
}
case TMR_PARAM_ISO180006B_DELIMITER:
{
protokey.protocol = TMR_TAG_PROTOCOL_ISO180006B;
protokey.u.iso180006b = TMR_SR_ISO180006B_CONFIGURATION_DELIMITER;
break;
}
#endif /* TMR_ENABLE_ISO180006B */
case TMR_PARAM_GEN2_ACCESSPASSWORD:
*(TMR_GEN2_Password *)value = sr->gen2AccessPassword;
break;
case TMR_PARAM_REGION_SUPPORTEDREGIONS:
ret = TMR_SR_cmdGetAvailableRegions(reader, value);
break;
case TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS:
ret = TMR_SR_cmdGetAvailableProtocols(reader, value);
break;
case TMR_PARAM_RADIO_TEMPERATURE:
ret = TMR_SR_cmdGetTemperature(reader, value);
break;
case TMR_PARAM_VERSION_HARDWARE:
ret = getHardwareInfo(reader, value);
break;
case TMR_PARAM_VERSION_SERIAL:
ret = getSerialNumber(reader, value);
break;
case TMR_PARAM_VERSION_MODEL:
{
const char *model = NULL;
switch (sr->versionInfo.hardware[0])
{
case TMR_SR_MODEL_M5E:
model = "M5e";
break;
case TMR_SR_MODEL_M5E_COMPACT:
model = "M5e Compact";
break;
case TMR_SR_MODEL_M5E_I:
{
/**
* I - International . It has following Variants.
**/
switch (sr->versionInfo.hardware[3])
{
case TMR_SR_MODEL_M5E_I_REV_EU:
model = "M5e EU";
break;
case TMR_SR_MODEL_M5E_I_REV_NA:
model = "M5e NA";
break;
case TMR_SR_MODEL_M5E_I_REV_JP:
model = "M5E JP";
break;
case TMR_SR_MODEL_M5E_I_REV_PRC:
model = "M5e PRC";
break;
default:
model = "Unknown";
break;
}
break;
}
case TMR_SR_MODEL_M4E:
model = "M4e";
break;
case TMR_SR_MODEL_M6E:
model = "M6e";
break;
case TMR_SR_MODEL_M6E_I:
{
/**
* M6e I has following variants
**/
switch (sr->versionInfo.hardware[3])
{
case TMR_SR_MODEL_M6E_I_PRC:
model = "M6e PRC";
break;
case TMR_SR_MODEL_M6E_I_JIC:
model = "M6e JIC";
break;
default:
model = "Unknown";
}
}
break;
case TMR_SR_MODEL_MICRO:
{
/**
* Micro has following variants.
**/
switch (sr->versionInfo.hardware[3])
{
case TMR_SR_MODEL_M6E_MICRO:
model = "M6e Micro";
break;
case TMR_SR_MODEL_M6E_MICRO_USB:
model = "M6e Micro USB";
break;
case TMR_SR_MODEL_M6E_MICRO_USB_PRO:
model = "M6e Micro USBPro";
break;
}
}
break;
case TMR_SR_MODEL_M6E_NANO:
model = "M6e Nano";
break;
default:
model = "Unknown";
}
TMR_stringCopy(value, model, (int)strlen(model));
break;
}
case TMR_PARAM_VERSION_SOFTWARE:
{
char tmp[38];
TMR_SR_VersionInfo *info;
info = &sr->versionInfo;
TMR_hexDottedQuad(info->fwVersion, tmp);
tmp[11] = '-';
TMR_hexDottedQuad(info->fwDate, tmp + 12);
tmp[23] = '-';
tmp[24] = 'B';
tmp[25] = 'L';
TMR_hexDottedQuad(info->bootloader, tmp+26);
TMR_stringCopy(value, tmp, 37);
break;
}
case TMR_PARAM_LICENSE_KEY:
ret = TMR_ERROR_UNSUPPORTED;
break;
case TMR_PARAM_USER_CONFIG:
ret = TMR_ERROR_UNSUPPORTED;
break;
case TMR_PARAM_READER_STATS:
{
if ((NULL != reader->pSupportsResetStats) && (false == *(reader->pSupportsResetStats)))
{
/* Command not supported, pop up the error */
return TMR_ERROR_UNSUPPORTED;
}
/**
* We should ask for the fields which are requested by the user,
* if no fields are requested by the user, then fetch all fields.
*/
if (TMR_READER_STATS_FLAG_NONE == reader->statsFlag)
{
reader->statsFlag = TMR_READER_STATS_FLAG_ALL;
}
ret = TMR_SR_cmdGetReaderStats(reader, reader->statsFlag, value);
break;
}
case TMR_PARAM_READER_STATS_ENABLE:
{
if ((NULL != reader->pSupportsResetStats) && (false == *(reader->pSupportsResetStats)))
{
/* Command not supported, pop up the error */
return TMR_ERROR_UNSUPPORTED;
}
*(TMR_Reader_StatsFlag *)value = reader->statsFlag;
break;
}
case TMR_PARAM_READER_STATISTICS:
ret = TMR_SR_cmdGetReaderStatistics(reader, TMR_SR_READER_STATS_ALL, value);
break;
case TMR_PARAM_PRODUCT_GROUP:
{
const char *group;
TMR_SR_ProductGroupID id = (TMR_SR_ProductGroupID)sr->productId;
switch (id)
{
case TMR_SR_PRODUCT_MODULE:
case TMR_SR_PRODUCT_INVALID:
group = "Embedded Reader";
break;
case TMR_SR_PRODUCT_RUGGEDIZED_READER:
group = "Ruggedized Reader";
break;
case TMR_SR_PRODUCT_USB_READER:
group = "USB Reader";
break;
default:
group = "Unknown";
break;
}
if (NULL != value)
{
TMR_stringCopy(value, group, (int)strlen(group));
}
else
{
ret = TMR_ERROR_ILLEGAL_VALUE;
}
break;
}
case TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT:
{
*(uint16_t *)value = sr->tagopSuccessCount;
break;
}
case TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT:
{
*(uint16_t *)value = sr->tagopFailureCount;
break;
}
case TMR_PARAM_READER_WRITE_REPLY_TIMEOUT:
case TMR_PARAM_READER_WRITE_EARLY_EXIT:
{
TMR_SR_Gen2ReaderWriteTimeOut timeout;
ret = TMR_SR_cmdGetReaderWriteTimeOut(reader, protokey.protocol, &timeout);
if (TMR_SUCCESS != ret)
{
break;
}
switch (key)
{
case TMR_PARAM_READER_WRITE_REPLY_TIMEOUT:
{
*(uint16_t *)value = (uint16_t)timeout.writetimeout;
break;
}
case TMR_PARAM_READER_WRITE_EARLY_EXIT:
{
*(bool *)value = !((bool)timeout.earlyexit);
break;
}
default:
ret = TMR_ERROR_NOT_FOUND;
}
}
break;
case TMR_PARAM_METADATAFLAG:
{
*(TMR_TRD_MetadataFlag *)value = reader->userMetadataFlag;
break;
}
default:
ret = TMR_ERROR_NOT_FOUND;
}
switch (key)
{
case TMR_PARAM_ANTENNA_CHECKPORT:
case TMR_PARAM_RADIO_ENABLEPOWERSAVE:
case TMR_PARAM_RADIO_ENABLESJC:
case TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI:
case TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM:
case TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA:
case TMR_PARAM_TAGREADDATA_UNIQUEBYDATA:
case TMR_PARAM_PRODUCT_GROUP_ID:
case TMR_PARAM_PRODUCT_ID:
ret = TMR_SR_cmdGetReaderConfiguration(reader, readerkey, value);
break;
case TMR_PARAM_EXTENDEDEPC:
{
if ((TMR_SR_MODEL_M6E == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_I == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_M6E_NANO == sr->versionInfo.hardware[0]) ||
(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0]))
{
ret = TMR_ERROR_UNSUPPORTED;
}
else
{
ret = TMR_SR_cmdGetReaderConfiguration(reader, readerkey, value);
}
}
break;
case TMR_PARAM_GEN2_Q:
case TMR_PARAM_GEN2_TAGENCODING:
case TMR_PARAM_GEN2_SESSION:
case TMR_PARAM_GEN2_TARGET:
case TMR_PARAM_GEN2_BLF:
case TMR_PARAM_GEN2_TARI:
case TMR_PARAM_GEN2_BAP:
case TMR_PARAM_GEN2_PROTOCOLEXTENSION:
#ifdef TMR_ENABLE_ISO180006B
case TMR_PARAM_ISO180006B_BLF:
case TMR_PARAM_ISO180006B_MODULATION_DEPTH:
case TMR_PARAM_ISO180006B_DELIMITER:
#endif /* TMR_ENABLE_ISO180006B */
ret = TMR_SR_cmdGetProtocolConfiguration(reader, protokey.protocol,
protokey, value);
break;
default:
;
}
if (0 == BITGET(sr->paramConfirmed, key))
{
if ((TMR_SUCCESS == ret) || ret == TMR_ERROR_AUTOREAD_ENABLED )
{
BITSET(sr->paramPresent, key);
}
BITSET(sr->paramConfirmed, key);
}
return ret;
}
TMR_Status
TMR_SR_SerialReader_init(TMR_Reader *reader)
{
reader->readerType = TMR_READER_TYPE_SERIAL;
#ifndef TMR_ENABLE_SERIAL_READER_ONLY
reader->connect = TMR_SR_connect;
reader->destroy = TMR_SR_destroy;
reader->read = TMR_SR_read;
reader->hasMoreTags = TMR_SR_hasMoreTags;
reader->getNextTag = TMR_SR_getNextTag;
reader->executeTagOp = TMR_SR_executeTagOp;
reader->readTagMemWords = TMR_SR_readTagMemWords;
reader->readTagMemBytes = TMR_SR_readTagMemBytes;
reader->writeTagMemBytes = TMR_SR_writeTagMemBytes;
reader->writeTagMemWords = TMR_SR_writeTagMemWords;
reader->writeTag = TMR_SR_writeTag;
reader->killTag = TMR_SR_killTag;
reader->lockTag = TMR_SR_lockTag;
reader->gpiGet = TMR_SR_gpiGet;
reader->gpoSet = TMR_SR_gpoSet;
#ifdef TMR_ENABLE_STDIO
reader->firmwareLoad = TMR_SR_firmwareLoad;
#endif
reader->modifyFlash = TMR_SR_modifyFlash;
reader->reboot = TMR_SR_reboot;
#endif
reader->cmdStopReading = TMR_SR_cmdStopReading;
#ifdef TMR_ENABLE_BACKGROUND_READS
reader->cmdAutonomousReading = TMR_SR_receiveAutonomousReading;
#endif
reader->paramSet = TMR_SR_paramSet;
reader->paramGet = TMR_SR_paramGet;
memset(reader->u.serialReader.paramConfirmed,0,
sizeof(reader->u.serialReader.paramConfirmed));
memset(reader->u.serialReader.paramPresent,0,
sizeof(reader->u.serialReader.paramPresent));
reader->u.serialReader.baudRate = 115200;
reader->u.serialReader.currentProtocol = TMR_TAG_PROTOCOL_NONE;
reader->u.serialReader.versionInfo.hardware[0] = TMR_SR_MODEL_UNKNOWN;
reader->u.serialReader.supportsPreamble = false;
reader->u.serialReader.extendedEPC = false;
reader->u.serialReader.powerMode = TMR_SR_POWER_MODE_INVALID;
reader->u.serialReader.transportTimeout = 5000;
reader->u.serialReader.commandTimeout = 1000;
reader->u.serialReader.regionId = TMR_REGION_NONE;
reader->u.serialReader.tagsRemaining = 0;
reader->u.serialReader.tagsRemainingInBuffer = 0;
reader->u.serialReader.gen2AccessPassword = 0;
reader->u.serialReader.oldQ.type = TMR_SR_GEN2_Q_INVALID;
reader->u.serialReader.writeMode = TMR_GEN2_WORD_ONLY;
reader->u.serialReader.tagopSuccessCount = 0;
reader->u.serialReader.tagopFailureCount = 0;
reader->u.serialReader.enableReadFiltering = true;
reader->u.serialReader.readFilterTimeout = 0;
reader->u.serialReader.usrTimeoutEnable = false;
reader->u.serialReader.crcEnabled = true;
reader->u.serialReader.transportType = TMR_SR_MSG_SOURCE_UNKNOWN;
reader->u.serialReader.gen2AllMemoryBankEnabled = false;
reader->u.serialReader.isBapEnabled = false;
reader->u.serialReader.probeBaudRates.list = reader->u.serialReader.baudRates;
reader->u.serialReader.probeBaudRates.max = TMR_MAX_PROBE_BAUDRATE_LENGTH;
reader->u.serialReader.probeBaudRates.len = 0;
reader->u.serialReader.enableAutonomousRead = false;
reader->u.serialReader.isBasetimeUpdated = false;
{
//initialize the probe baud rate list with the supported baud rate values
TMR_uint32List value;
uint32_t rates[TMR_MAX_PROBE_BAUDRATE_LENGTH] ={9600, 115200, 921600, 19200, 38400, 57600,230400, 460800};
value.list = rates;
value.len = value.max = 8;
TMR_paramSet(reader, TMR_PARAM_PROBEBAUDRATES, &value);
}
return TMR_reader_init_internal(reader);
}
uint16_t TMR_SR_getConfigWord(TMR_Reader *reader, TMR_TagOp_GEN2_NXP_Untraceable op)
{
uint16_t configWord = 0x0000;
uint16_t Mask;
int Pos;
if(op.epc == 1)
{
configWord |= 0x0001 << 14;
}
Mask = 0x1F;
Pos = 9;
configWord |= (uint16_t)((op.epcLength & Mask) << Pos);
Mask = 0x03;
Pos = 7;
configWord |= (uint16_t)((op.tid & Mask) << Pos);
if (op.userMemory == 1)
{
configWord |= 0x0001 << 6;
}
Mask = 0x03;
Pos = 4;
configWord |= (uint16_t)((op.range & Mask) << Pos);
return configWord;
}
TMR_Status
TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *filter, TMR_uint8List *data)
{
TMR_Status ret;
TMR_SR_SerialReader *sr;
sr = &reader->u.serialReader;
switch (tagop->type)
{
case (TMR_TAGOP_GEN2_WRITETAG):
{
TMR_TagOp_GEN2_WriteTag op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.writeTag;
return TMR_SR_cmdWriteGen2TagEpc(reader, filter, sr->gen2AccessPassword,
(uint16_t)(sr->commandTimeout),
op.epcptr->epcByteCount,
op.epcptr->epc,
false);
}
case (TMR_TAGOP_GEN2_KILL):
{
TMR_TagOp_GEN2_Kill op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.kill;
return TMR_SR_cmdKillTag(reader,
(uint16_t)(sr->commandTimeout),
op.password,
filter);
}
case (TMR_TAGOP_GEN2_LOCK):
{
TMR_TagOp_GEN2_Lock op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.lock;
return TMR_SR_cmdGEN2LockTag(reader, (uint16_t)sr->commandTimeout,
op.mask, op.action, op.accessPassword, filter);
}
case (TMR_TAGOP_GEN2_WRITEDATA):
{
TMR_TagOp_GEN2_WriteData op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.writeData;
return TMR_SR_writeTagMemWords(reader, filter, op.bank, op.wordAddress, op.data.len, op.data.list);
}
case (TMR_TAGOP_GEN2_READDATA):
{
TMR_TagOp_GEN2_ReadData op;
TMR_TagReadData read;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (NULL != data)
{
read.data.len = 0;
read.data.list = data->list;
read.data.max = data->max;
}
else
{
read.data.list = NULL;
}
read.metadataFlags = 0;
op = tagop->u.gen2.u.readData;
ret = TMR_SR_cmdGEN2ReadTagData(reader, (uint16_t)(sr->commandTimeout), op.bank,
op.wordAddress, op.len, sr->gen2AccessPassword, filter, &read);
if (NULL != data)
{
data->len = read.data.len;
}
return ret;
}
case (TMR_TAGOP_GEN2_BLOCKWRITE):
{
TMR_TagOp_GEN2_BlockWrite op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.blockWrite;
return TMR_SR_cmdBlockWrite(reader,(uint16_t)sr->commandTimeout, op.bank,
op.wordPtr, op.data.len, op.data.list, sr->gen2AccessPassword, filter);
}
case (TMR_TAGOP_GEN2_BLOCKPERMALOCK):
{
TMR_TagOp_GEN2_BlockPermaLock op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.blockPermaLock;
return TMR_SR_cmdBlockPermaLock(reader, (uint16_t)sr->commandTimeout, op.readLock, op.bank,
op.blockPtr, op.mask.len, op.mask.list, sr->gen2AccessPassword, filter, data);
}
case (TMR_TAGOP_GEN2_BLOCKERASE):
{
TMR_TagOp_GEN2_BlockErase op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.blockErase;
return TMR_SR_cmdBlockErase(reader, (uint16_t)sr->commandTimeout, op.bank, op.wordPtr,
op.wordCount, sr->gen2AccessPassword, filter);
}
#ifdef TMR_ENABLE_GEN2_CUSTOM_TAGOPS
case (TMR_TAGOP_GEN2_ALIEN_HIGGS2_PARTIALLOADIMAGE):
{
TMR_TagOp_GEN2_Alien_Higgs2_PartialLoadImage op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.alien.u.higgs2.u.partialLoadImage;
if (op.epcptr->epcByteCount > 12 || op.epcptr->epcByteCount <=0 )
{ /* Only 96 bit epc */
return TMR_ERROR_PROTOCOL_INVALID_EPC;
}
return TMR_SR_cmdHiggs2PartialLoadImage(reader, (uint16_t)sr->commandTimeout,
op.accessPassword, op.killPassword, op.epcptr->epcByteCount, op.epcptr->epc, filter);
}
case (TMR_TAGOP_GEN2_ALIEN_HIGGS2_FULLLOADIMAGE):
{
TMR_TagOp_GEN2_Alien_Higgs2_FullLoadImage op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage;
if (op.epcptr->epcByteCount > 12 || op.epcptr->epcByteCount <= 0 )
{ /* Only 96 bit epc */
return TMR_ERROR_PROTOCOL_INVALID_EPC;
}
return TMR_SR_cmdHiggs2FullLoadImage(reader, (uint16_t)sr->commandTimeout, op.accessPassword,
op.killPassword, op.lockBits, op.pcWord, op.epcptr->epcByteCount, op.epcptr->epc, filter);
}
case (TMR_TAGOP_GEN2_ALIEN_HIGGS3_FASTLOADIMAGE):
{
/* The FastLoadImage command automatically erases the content of all
* User Memory. If this is undesirable then use the LoadImage or multiple Write
* Tag Data commands.
*/
TMR_TagOp_GEN2_Alien_Higgs3_FastLoadImage op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage;
if (op.epcptr->epcByteCount > 12 || op.epcptr->epcByteCount <= 0 )
{ /* Only 96 bit epc */
return TMR_ERROR_PROTOCOL_INVALID_EPC;
}
return TMR_SR_cmdHiggs3FastLoadImage(reader, (uint16_t)sr->commandTimeout, op.currentAccessPassword, op.accessPassword,
op.killPassword, op.pcWord, op.epcptr->epcByteCount, op.epcptr->epc, filter);
}
case (TMR_TAGOP_GEN2_ALIEN_HIGGS3_LOADIMAGE):
{
TMR_TagOp_GEN2_Alien_Higgs3_LoadImage op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage;
if (op.epcAndUserData->len > 76 || op.epcAndUserData->len <= 0 )
{ /* Only 76 byte epcAndUserData */
return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;
}
return TMR_SR_cmdHiggs3LoadImage(reader, (uint16_t)sr->commandTimeout, op.currentAccessPassword,
op.accessPassword, op.killPassword, op.pcWord, (uint8_t)op.epcAndUserData->len, op.epcAndUserData->list, filter);
}
case (TMR_TAGOP_GEN2_ALIEN_HIGGS3_BLOCKREADLOCK):
{
TMR_TagOp_GEN2_Alien_Higgs3_BlockReadLock op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.alien.u.higgs3.u.blockReadLock;
return TMR_SR_cmdHiggs3BlockReadLock(reader, (uint16_t)sr->commandTimeout, op.accessPassword, op.lockBits, filter);
}
case (TMR_TAGOP_GEN2_NXP_SETREADPROTECT):
{
TMR_TagOp_GEN2_NXP_SetReadProtect op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.setReadProtect;
return TMR_SR_cmdNxpSetReadProtect(reader, (uint16_t)sr->commandTimeout,
tagop->u.gen2.u.custom.chipType, op.accessPassword, filter);
}
case (TMR_TAGOP_GEN2_NXP_RESETREADPROTECT):
{
TMR_TagOp_GEN2_NXP_ResetReadProtect op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.resetReadProtect;
return TMR_SR_cmdNxpResetReadProtect(reader, (uint16_t)sr->commandTimeout,
tagop->u.gen2.u.custom.chipType, op.accessPassword, filter);
}
case (TMR_TAGOP_GEN2_NXP_CHANGEEAS):
{
TMR_TagOp_GEN2_NXP_ChangeEAS op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.changeEAS;
return TMR_SR_cmdNxpChangeEas(reader, (uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
op.accessPassword, op.reset, filter);
}
case (TMR_TAGOP_GEN2_NXP_EASALARM):
{
TMR_TagOp_GEN2_NXP_EASAlarm op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.EASAlarm;
return TMR_SR_cmdNxpEasAlarm(reader, (uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
op.dr, op.m, op.trExt, data, filter);
}
case (TMR_TAGOP_GEN2_NXP_CALIBRATE):
{
TMR_TagOp_GEN2_NXP_Calibrate op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.calibrate;
return TMR_SR_cmdNxpCalibrate(reader, (uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
op.accessPassword, data, filter);
}
case (TMR_TAGOP_GEN2_NXP_CHANGECONFIG):
{
TMR_TagOp_GEN2_NXP_ChangeConfig op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.nxp.u.changeConfig;
return TMR_SR_cmdNxpChangeConfig(reader, (uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
op.accessPassword, op.configWord, data, filter);
}
case (TMR_TAGOP_GEN2_NXP_UNTRACEABLE):
{
TMR_TagOp_GEN2_NXP_Untraceable op;
uint16_t configWord;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.untraceable;
configWord = TMR_SR_getConfigWord(reader,op);
return TMR_SR_cmdGen2v2NXPUntraceable(reader,(uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
sr->gen2AccessPassword, configWord , op, data, filter);
}
case (TMR_TAGOP_GEN2_NXP_AUTHENTICATE):
{
TMR_TagOp_GEN2_NXP_Authenticate op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.authenticate;
return TMR_SR_cmdGen2v2NXPAuthenticate(reader,(uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
sr->gen2AccessPassword, op, data, filter);
}
case (TMR_TAGOP_GEN2_NXP_READBUFFER):
{
TMR_TagOp_GEN2_NXP_Readbuffer op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.gen2.u.custom.u.nxp.u.readBuffer;
return TMR_SR_cmdGen2v2NXPReadBuffer(reader,(uint16_t)sr->commandTimeout, tagop->u.gen2.u.custom.chipType,
sr->gen2AccessPassword, op, data, filter);
}
case (TMR_TAGOP_GEN2_IMPINJ_MONZA4_QTREADWRITE):
{
TMR_TagOp_GEN2_Impinj_Monza4_QTReadWrite op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.impinj.u.monza4.u.qtReadWrite;
return TMR_SR_cmdMonza4QTReadWrite(reader, (uint16_t)sr->commandTimeout, op.accessPassword,
op.controlByte, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_GETSENSOR):
{
TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.sensor;
return TMR_SR_cmdSL900aGetSensorValue(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password,op.sl900A.level, op.sl900A.sensortype, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_GETMEASUREMENTSETUP):
{
TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.measurementSetup;
return TMR_SR_cmdSL900aGetMeasurementSetup(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password,op.sl900A.level, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_GETCALIBRATIONDATA):
{
TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.calibrationData;
return TMR_SR_cmdSL900aGetCalibrationData(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETCALIBRATIONDATA):
{
TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setCalibration;
return TMR_SR_cmdSL900aSetCalibrationData(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.cal.raw, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETSFEPARAMETERS):
{
TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setSfeParameters;
return TMR_SR_cmdSL900aSetSfeParameters(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.sfe->raw, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_GETLOGSTATE):
{
TMR_TagOp_GEN2_IDS_SL900A_GetLogState op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.getLog;
return TMR_SR_cmdSL900aGetLogState(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETLOGMODE):
{
TMR_TagOp_GEN2_IDS_SL900A_SetLogMode op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setLogMode;
return TMR_SR_cmdSL900aSetLogMode(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.sl900A.dataLog, op.sl900A.rule, op.Ext1Enable, op.Ext2Enable, op.TempEnable,
op.BattEnable, op.LogInterval, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_INITIALIZE):
{
TMR_TagOp_GEN2_IDS_SL900A_Initialize op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.initialize;
return TMR_SR_cmdSL900aInitialize(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.delayTime.raw, op.applicationData.raw, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_ENDLOG):
{
TMR_TagOp_GEN2_IDS_SL900A_EndLog op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.endLog;
return TMR_SR_cmdSL900aEndLog(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password,op.sl900A.level, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETPASSWORD):
{
TMR_TagOp_GEN2_IDS_SL900A_SetPassword op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setPassword;
return TMR_SR_cmdSL900aSetPassword(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password,op.sl900A.level, op.NewPassword, op.NewPasswordLevel, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOSTATUS):
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus;
return TMR_SR_cmdSL900aAccessFifoStatus(reader, (uint16_t)sr->commandTimeout, op.status.AccessPassword, op.status.CommandCode,
op.status.Password, op.status.sl900A.level, op.status.operation, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOREAD):
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.accessFifoRead;
return TMR_SR_cmdSL900aAccessFifoRead(reader, (uint16_t)sr->commandTimeout, op.read.AccessPassword, op.read.CommandCode,
op.read.Password, op.read.sl900A.level, op.read.operation,op.length, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOWRITE):
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite;
return TMR_SR_cmdSL900aAccessFifoWrite(reader, (uint16_t)sr->commandTimeout, op.write.AccessPassword, op.write.CommandCode,
op.write.Password, op.write.sl900A.level, op.write.operation, op.payLoad, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_STARTLOG):
{
TMR_TagOp_GEN2_IDS_SL900A_StartLog op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.startLog;
return TMR_SR_cmdSL900aStartLog(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.startTime, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_GETBATTERYLEVEL):
{
TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.batteryLevel;
return TMR_SR_cmdSL900aGetBatteryLevel(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.batteryType, data, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETLOGLIMITS):
{
TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setLogLimit;
return TMR_SR_cmdSL900aSetLogLimit(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.limit.extremeLower, op.limit.lower, op.limit.upper, op.limit.extremeUpper, filter);
}
case (TMR_TAGOP_GEN2_IDS_SL900A_SETSHELFLIFE):
{
TMR_TagOp_GEN2_IDS_SL900A_SetShelfLife op;
/* Set the protocol for tag operation */
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
/* Do some error checking */
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.ids.u.setShelfLife;
return TMR_SR_cmdSL900aSetShelfLife(reader, (uint16_t)sr->commandTimeout, op.AccessPassword, op.CommandCode,
op.Password, op.sl900A.level, op.shelfLifeBlock0->raw, op.shelfLifeBlock1->raw, filter);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_ACTIVATESECUREMODE):
{
TMR_TagOp_GEN2_Denatran_IAV_Activate_Secure_Mode op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.secureMode;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATEOBU):
{
TMR_TagOp_GEN2_Denatran_IAV_Authenticate_OBU op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.authenticateOBU;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_ACTIVATE_SINIAV_MODE):
{
TMR_TagOp_GEN2_Denatran_IAV_Activate_Siniav_Mode op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode;
return TMR_SR_cmdIAVDenatranCustomActivateSiniavMode(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter, op.isTokenDesc, op.token);
}
case (TMR_TAGOP_GEN2_OBU_AUTH_ID):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_ID op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthId;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS1):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1 op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass1;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS2):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2 op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass2;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_OBU_READ_FROM_MEM_MAP):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_ReadFromMemMap op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuReadFromMemMap;
return TMR_SR_cmdIAVDenatranCustomReadFromMemMap(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter, op.readPtr);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_READ_SEC):
{
TMR_TagOp_GEN2_Denatran_IAV_Read_Sec op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.readSec;
return TMR_SR_cmdIAVDenatranCustomReadSec(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter, op.readPtr);
}
case (TMR_TAGOP_GEN2_OBU_WRITE_TO_MEM_MAP):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_WriteToMemMap op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap;
return TMR_SR_cmdIAVDenatranCustomWriteToMemMap(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter, op.writePtr, op.wordData,op.tagIdentification, op.dataBuf);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_WRITE_SEC):
{
TMR_TagOp_GEN2_Denatran_IAV_Write_Sec op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec;
return TMR_SR_cmdIAVDenatranCustomWriteSec(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, op.payload, data, filter, op.dataWords, op.dataBuf);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_GET_TOKEN_ID):
{
TMR_TagOp_GEN2_Denatran_IAV_Get_Token_Id op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if ( TMR_SUCCESS != ret)
{
return ret;
}
if (NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.getTokenId;
return TMR_SR_cmdIAVDenatranCustomGetTokenId(reader, (uint16_t)sr->commandTimeout, sr->gen2AccessPassword,
op.mode, data, filter);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATE_OBU_FULL_PASS):
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout,
sr->gen2AccessPassword, op.mode, op.payload, data, filter);
}
case (TMR_TAGOP_GEN2_DENATRAN_IAV_G0_PA_OBU_AUTHENTICATE_ID):
{
TMR_TagOp_GEN2_Denatran_IAV_G0_PA_OBU_Auth_ID op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);
if (TMR_SUCCESS != ret)
{
return ret;
}
if(NULL != data)
{
data->len = 0;
}
op = tagop->u.gen2.u.custom.u.IavDenatran.u.g0paobuauthid;
return TMR_SR_cmdIAVDenatranCustomOp(reader, (uint16_t)sr->commandTimeout,
sr->gen2AccessPassword, op.mode, op.payload, data, filter);
}
#endif /* TMR_ENABLE_GEN2_CUSTOM_TAGOPS */
#ifdef TMR_ENABLE_ISO180006B
case (TMR_TAGOP_ISO180006B_READDATA):
{
TMR_TagOp_ISO180006B_ReadData op;
TMR_TagReadData read;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_ISO180006B);
if (TMR_SUCCESS != ret)
{
return ret;
}
if (NULL != data)
{
read.data.max = data->max;
read.data.len = 0;
read.data.list = data->list;
}
else
{
read.data.list = NULL;
}
read.metadataFlags = 0;
op = tagop->u.iso180006b.u.readData;
ret = TMR_SR_cmdISO180006BReadTagData(reader, (uint16_t)sr->commandTimeout,
op.byteAddress, op.len, filter, &read);
if (NULL != data)
{
data->len = read.data.len;
}
return ret;
}
case (TMR_TAGOP_ISO180006B_WRITEDATA):
{
TMR_TagOp_ISO180006B_WriteData op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_ISO180006B);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.iso180006b.u.writeData;
return TMR_SR_cmdISO180006BWriteTagData(reader, (uint16_t)(sr->commandTimeout), op.byteAddress,
(uint8_t)op.data.len, op.data.list, filter);
}
case (TMR_TAGOP_ISO180006B_LOCK):
{
TMR_TagOp_ISO180006B_Lock op;
ret = setProtocol(reader, TMR_TAG_PROTOCOL_ISO180006B);
if (TMR_SUCCESS != ret)
{
return ret;
}
op = tagop->u.iso180006b.u.lock;
return TMR_SR_cmdISO180006BLockTag(reader, (uint16_t)(sr->commandTimeout), op.address, filter);
}
#endif /* TMR_ENABLE_ISO180006B */
default:
{
return TMR_ERROR_UNIMPLEMENTED_FEATURE;
}
}
}
/**
* Internal method used for adding the tagop
**/
TMR_Status
TMR_SR_addTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop,TMR_ReadPlan *rp, uint8_t *msg, uint8_t *j, uint32_t readTimeMs, uint8_t *byte )
{
TMR_Status ret = TMR_SUCCESS;
TMR_SR_SerialReader *sr;
uint8_t i, lenbyte;
i = *j; lenbyte = *byte;
sr = &reader->u.serialReader;
switch (tagop->type)
{
case (TMR_TAGOP_GEN2_WRITETAG):
{
TMR_TagOp_GEN2_WriteTag *args;
args = &rp->u.simple.tagop->u.gen2.u.writeTag;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2WriteTagEPC(msg,&i, 0, args->epcptr->epc, args->epcptr->epcByteCount);
break;
}
case TMR_TAGOP_GEN2_READDATA:
{
TMR_TagOp_GEN2_ReadData *args;
args = &rp->u.simple.tagop->u.gen2.u.readData;
/**
* If user wants to read all the memory bank data,
* In that case args.bank value should be greater than 3
**/
if ((uint8_t)args->bank > 3)
{
/* enable the gen2AllMemoryBankEnabled option */
sr->gen2AllMemoryBankEnabled = true;
}
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2DataRead(msg, &i, 2000, args->bank, args->wordAddress,
args->len, 0x00, false);
break;
}
case TMR_TAGOP_GEN2_SECURE_READDATA:
{
TMR_TagOp_GEN2_SecureReadData *args;
uint8_t accessPassword[4];
int index = 0;
/* Enable the Secure ReadData option */
isSecureAccessEnabled = true;
args = &rp->u.simple.tagop->u.gen2.u.secureReadData;
if (args->passwordType == TMR_SECURE_GEN2_LOOKUP_TABLE_PASSWORD)
{
/* Do this in case of look up table */
accessPassword[index++] = args->password.secureAddressLength;
accessPassword[index++] = args->password.secureAddressOffset;
accessPassword[index++] = (args->password.secureFlashOffset >> 8);
accessPassword[index++] = (args->password.secureFlashOffset & 0xFF);
sr->gen2AccessPassword = (uint32_t)accessPassword[0] << 24 |
(uint32_t)accessPassword[1] << 16 |
(uint32_t)accessPassword[2] << 8 |
(uint32_t)accessPassword[3];
}
else
{
/* Do this in case of Gen2 password */
sr->gen2AccessPassword = args->password.gen2PassWord.u.gen2Password;
}
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND | TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2DataRead(msg, &i, 2000, args->readData.bank, args->readData.wordAddress,
args->readData.len,args->type, false);
isSecureAccessEnabled = false;
break;
}
case TMR_TAGOP_GEN2_WRITEDATA:
{
TMR_TagOp_GEN2_WriteData *args;
int idx ;
args = &rp->u.simple.tagop->u.gen2.u.writeData;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2DataWrite(msg, &i, 0, args->bank, args->wordAddress);
for(idx = 0 ; idx< args->data.len; idx++)
{
msg[i++]= (args->data.list[idx]>>8) & 0xFF;
msg[i++]= (args->data.list[idx]>>0) & 0xFF;
}
break;
}
case TMR_TAGOP_GEN2_LOCK:
{
TMR_TagOp_GEN2_Lock *args;
args = &rp->u.simple.tagop->u.gen2.u.lock;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddGEN2LockTag(msg, &i, 0, args->mask, args->action, 0);
break;
}
case TMR_TAGOP_GEN2_KILL:
{
TMR_TagOp_GEN2_Kill *args;
args = &rp->u.simple.tagop->u.gen2.u.kill;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2KillTag(msg, &i, 0, args->password);
break;
}
case TMR_TAGOP_GEN2_BLOCKWRITE:
{
TMR_TagOp_GEN2_BlockWrite *args;
args = &rp->u.simple.tagop->u.gen2.u.blockWrite;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2BlockWrite(msg, &i, 0, args->bank, args->wordPtr, args->data.len, args->data.list, 0, NULL);
break;
}
case TMR_TAGOP_GEN2_BLOCKPERMALOCK:
{
TMR_TagOp_GEN2_BlockPermaLock *args;
args = &rp->u.simple.tagop->u.gen2.u.blockPermaLock;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2BlockPermaLock(msg, &i, 0,args->readLock, args->bank, args->blockPtr, args->mask.len,
args->mask.list, 0, NULL);
break;
}
case TMR_TAGOP_GEN2_BLOCKERASE:
{
TMR_TagOp_GEN2_BlockErase *args;
args = &rp->u.simple.tagop->u.gen2.u.blockErase;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddGEN2BlockErase(msg, &i, 0, args->wordPtr, args->bank, args->wordCount, 0, NULL);
break;
}
#ifdef TMR_ENABLE_GEN2_CUSTOM_TAGOPS
case TMR_TAGOP_GEN2_ALIEN_HIGGS2_PARTIALLOADIMAGE:
{
TMR_TagOp_GEN2_Alien_Higgs2_PartialLoadImage *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.alien.u.higgs2.u.partialLoadImage;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddHiggs2PartialLoadImage(msg, &i, 0, args->accessPassword, args->killPassword,
args->epcptr->epcByteCount, args->epcptr->epc, NULL);
break;
}
case TMR_TAGOP_GEN2_ALIEN_HIGGS2_FULLLOADIMAGE:
{
TMR_TagOp_GEN2_Alien_Higgs2_FullLoadImage *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddHiggs2FullLoadImage(msg, &i, 0, args->accessPassword, args->killPassword, args->lockBits,
args->pcWord, args->epcptr->epcByteCount, args->epcptr->epc, NULL);
break;
}
case TMR_TAGOP_GEN2_ALIEN_HIGGS3_FASTLOADIMAGE:
{
TMR_TagOp_GEN2_Alien_Higgs3_FastLoadImage *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->currentAccessPassword, &lenbyte);
TMR_SR_msgAddHiggs3FastLoadImage(msg, &i, 0, args->currentAccessPassword, args->accessPassword,
args->killPassword, args->pcWord, args->epcptr->epcByteCount, args->epcptr->epc, NULL);
break;
}
case TMR_TAGOP_GEN2_ALIEN_HIGGS3_LOADIMAGE:
{
TMR_TagOp_GEN2_Alien_Higgs3_LoadImage *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->currentAccessPassword, &lenbyte);
TMR_SR_msgAddHiggs3LoadImage(msg, &i, 0, args->currentAccessPassword, args->accessPassword,
args->killPassword, args->pcWord, (uint8_t)args->epcAndUserData->len, args->epcAndUserData->list, NULL);
break;
}
case TMR_TAGOP_GEN2_ALIEN_HIGGS3_BLOCKREADLOCK:
{
TMR_TagOp_GEN2_Alien_Higgs3_BlockReadLock *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.alien.u.higgs3.u.blockReadLock;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddHiggs3BlockReadLock(msg, &i, 0, args->accessPassword, args->lockBits, NULL);
break;
}
case TMR_TAGOP_GEN2_NXP_SETREADPROTECT:
{
TMR_TagOp_GEN2_NXP_SetReadProtect *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.nxp.u.setReadProtect;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddNXPSetReadProtect(msg, &i, 0, rp->u.simple.tagop->u.gen2.u.custom.chipType, args->accessPassword, NULL);
break;
}
case TMR_TAGOP_GEN2_NXP_RESETREADPROTECT:
{
TMR_TagOp_GEN2_NXP_ResetReadProtect *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.nxp.u.resetReadProtect;
if (rp->u.simple.tagop->u.gen2.u.custom.chipType == TMR_SR_GEN2_NXP_G2X_SILICON)
{
/* NXP_G2XL_ResetReadProtect can not be embedded.
* Throw un supported exception to the user
*/
return TMR_ERROR_UNSUPPORTED;
}
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddNXPResetReadProtect(msg, &i, 0, rp->u.simple.tagop->u.gen2.u.custom.chipType, args->accessPassword, NULL);
break;
}
case TMR_TAGOP_GEN2_NXP_CHANGEEAS:
{
TMR_TagOp_GEN2_NXP_ChangeEAS *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.nxp.u.changeEAS;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddNXPChangeEAS(msg, &i, 0, rp->u.simple.tagop->u.gen2.u.custom.chipType, args->accessPassword, args->reset, NULL);
break;
}
case TMR_TAGOP_GEN2_NXP_EASALARM:
{
return TMR_ERROR_UNSUPPORTED;
}
case TMR_TAGOP_GEN2_NXP_CALIBRATE:
{
TMR_TagOp_GEN2_NXP_Calibrate *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.nxp.u.calibrate;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddNXPCalibrate(msg, &i, 0, rp->u.simple.tagop->u.gen2.u.custom.chipType, args->accessPassword, NULL);
break;
}
case TMR_TAGOP_GEN2_NXP_CHANGECONFIG:
{
TMR_TagOp_GEN2_NXP_ChangeConfig *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.nxp.u.changeConfig;
if (rp->u.simple.tagop->u.gen2.u.custom.chipType == TMR_SR_GEN2_NXP_G2X_SILICON)
{
/* Change Config is not supported for G2xL silicon*/
return TMR_ERROR_UNSUPPORTED;
}
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddNXPChangeConfig(msg, &i, 0, rp->u.simple.tagop->u.gen2.u.custom.chipType, 0, args->configWord, NULL);
break;
}
case TMR_TAGOP_GEN2_IMPINJ_MONZA4_QTREADWRITE:
{
TMR_TagOp_GEN2_Impinj_Monza4_QTReadWrite *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.impinj.u.monza4.u.qtReadWrite;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->accessPassword, &lenbyte);
TMR_SR_msgAddMonza4QTReadWrite(msg, &i, 0, 0, args->controlByte, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_GETSENSOR:
{
TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.sensor;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aGetSensorValue(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level,
args->sl900A.sensortype, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_GETMEASUREMENTSETUP:
{
TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.measurementSetup;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aGetMeasurementSetup(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, NULL);
}
case TMR_TAGOP_GEN2_IDS_SL900A_GETLOGSTATE:
{
TMR_TagOp_GEN2_IDS_SL900A_GetLogState *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.getLog;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aGetLogState(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level,NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_SETLOGMODE:
{
TMR_TagOp_GEN2_IDS_SL900A_SetLogMode *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.setLogMode;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aSetLogMode(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level,
args->sl900A.dataLog, args->sl900A.rule, args->Ext1Enable, args->Ext2Enable, args->TempEnable,
args->BattEnable, args->LogInterval, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_INITIALIZE:
{
TMR_TagOp_GEN2_IDS_SL900A_Initialize *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.initialize;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aInitialize(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level,
args->delayTime.raw, args->applicationData.raw, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_ENDLOG:
{
TMR_TagOp_GEN2_IDS_SL900A_EndLog *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.endLog;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aEndLog(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_SETPASSWORD:
{
TMR_TagOp_GEN2_IDS_SL900A_SetPassword *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.setPassword;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aSetPassword(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level,
args->NewPassword, args->NewPasswordLevel, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_STARTLOG:
{
TMR_TagOp_GEN2_IDS_SL900A_StartLog *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.startLog;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aStartLog(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, args->startTime, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOSTATUS:
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->status.AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aAccessFifoStatus(msg, &i, 0, 0, args->status.CommandCode, args->status.Password, args->status.sl900A.level, args->status.operation, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOREAD:
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.accessFifoRead;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->read.AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aAccessFifoRead(msg, &i, 0, 0, args->read.CommandCode, args->read.Password, args->read.sl900A.level, args->read.operation, args->length, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOWRITE:
{
TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->write.AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aAccessFifoWrite(msg, &i, 0, 0, args->write.CommandCode, args->write.Password, args->write.sl900A.level, args->write.operation, args->payLoad, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_GETCALIBRATIONDATA:
{
TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.calibrationData;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aGetCalibrationData(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_SETCALIBRATIONDATA:
{
TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.setCalibration;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aSetCalibrationData(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, args->cal.raw, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_SETSFEPARAMETERS:
{
TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.setSfeParameters;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aSetSfeParameters(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, args->sfe->raw, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_GETBATTERYLEVEL:
{
TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.batteryLevel;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aGetBatteryLevel(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, args->batteryType, NULL);
break;
}
case TMR_TAGOP_GEN2_IDS_SL900A_SETLOGLIMITS:
{
TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.ids.u.setLogLimit;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, args->AccessPassword, &lenbyte);
TMR_SR_msgAddIdsSL900aSetLogLimit(msg, &i, 0, 0, args->CommandCode, args->Password, args->sl900A.level, args->limit.extremeLower,
args->limit.lower, args->limit.upper, args->limit.extremeUpper, NULL);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_ACTIVATESECUREMODE:
{
TMR_TagOp_GEN2_Denatran_IAV_Activate_Secure_Mode *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.secureMode;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATEOBU:
{
TMR_TagOp_GEN2_Denatran_IAV_Authenticate_OBU *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.authenticateOBU;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_ACTIVATE_SINIAV_MODE:
{
TMR_TagOp_GEN2_Denatran_IAV_Activate_Siniav_Mode *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomActivateSiniavMode(msg, &i, 0, 0, args->mode, args->payload, NULL, args->isTokenDesc, args->token);
break;
}
case TMR_TAGOP_GEN2_OBU_AUTH_ID:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_ID *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthId;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS1:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1 *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass1;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS2:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2 *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass2;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_OBU_READ_FROM_MEM_MAP:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_ReadFromMemMap *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuReadFromMemMap;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomReadFromMemMap(msg, &i, 0, 0, args->mode, args->payload, NULL, args->readPtr);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_READ_SEC:
{
TMR_TagOp_GEN2_Denatran_IAV_Read_Sec *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.readSec;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomReadSec(msg, &i, 0, 0, args->mode, args->payload, NULL, args->readPtr);
break;
}
case TMR_TAGOP_GEN2_OBU_WRITE_TO_MEM_MAP:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_WriteToMemMap *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomWriteToMemMap(msg, &i, 0, 0, args->mode, args->payload, NULL, args->writePtr, args->wordData, args->tagIdentification, args->dataBuf);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_WRITE_SEC:
{
TMR_TagOp_GEN2_Denatran_IAV_Write_Sec *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomWriteSec(msg, &i, 0, 0, args->mode, args->payload, NULL, args->dataWords, args->dataBuf);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_GET_TOKEN_ID:
{
TMR_TagOp_GEN2_Denatran_IAV_Get_Token_Id *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.getTokenId;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomGetTokenId(msg, &i, 0, 0, args->mode, NULL);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATE_OBU_FULL_PASS:
{
TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
case TMR_TAGOP_GEN2_DENATRAN_IAV_G0_PA_OBU_AUTHENTICATE_ID:
{
TMR_TagOp_GEN2_Denatran_IAV_G0_PA_OBU_Auth_ID *args;
args = &rp->u.simple.tagop->u.gen2.u.custom.u.IavDenatran.u.g0paobuauthid;
prepEmbReadTagMultiple(reader, msg, &i, (uint16_t)readTimeMs, (TMR_SR_SearchFlag)(TMR_SR_SEARCH_FLAG_CONFIGURED_LIST
| TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND|TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT),
rp->u.simple.filter, rp->u.simple.protocol, sr->gen2AccessPassword, &lenbyte);
TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, 0, 0, args->mode, args->payload, NULL);
break;
}
#endif /* TMR_ENABLE_GEN2_CUSTOM_TAGOPS */
case TMR_TAGOP_LIST:
return TMR_ERROR_UNIMPLEMENTED; /* Module doesn't implement these */
default:
return TMR_ERROR_INVALID; /* Unknown tagop - internal error */
}
*j = i;
*byte = lenbyte;
return ret;
}
/* Internal method used to update the base times stamp */
void TMR_SR_updateBaseTimeStamp(TMR_Reader *reader)
{
/* update the base time stamp to current host time */
uint32_t starttimeLow, starttimeHigh;
starttimeHigh = 0;
starttimeLow = 0;
tm_gettime_consistent(&starttimeHigh, &starttimeLow);
reader->u.serialReader.readTimeHigh = starttimeHigh;
reader->u.serialReader.readTimeLow = starttimeLow;
reader->u.serialReader.lastSentTagTimestampHigh = starttimeHigh;
reader->u.serialReader.lastSentTagTimestampLow = starttimeLow;
}
#endif /* TMR_ENABLE_SERIAL_READER */